@rhseung/ps-cli 1.5.0 → 1.7.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.
@@ -3,12 +3,13 @@ import {
3
3
  Command,
4
4
  CommandBuilder,
5
5
  CommandDef,
6
+ getArchiveStrategy,
6
7
  getAutoOpenEditor,
7
8
  getDefaultLanguage,
8
9
  getEditor,
9
10
  getProblemDir,
10
11
  getSolvedAcHandle
11
- } from "../chunk-7SVCS23X.js";
12
+ } from "../chunk-TNGUME4H.js";
12
13
  import {
13
14
  __decorateClass,
14
15
  getSupportedLanguages,
@@ -104,6 +105,18 @@ function useConfig({
104
105
  case "problem-dir":
105
106
  updatedConfig.problemDir = value;
106
107
  break;
108
+ case "archive-strategy": {
109
+ const validStrategies = ["flat", "by-range", "by-tier", "by-tag"];
110
+ if (!validStrategies.includes(value)) {
111
+ console.error(
112
+ `\uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 \uC544\uCE74\uC774\uBE59 \uC804\uB7B5\uC785\uB2C8\uB2E4: ${value}
113
+ \uC9C0\uC6D0 \uC804\uB7B5: ${validStrategies.join(", ")}`
114
+ );
115
+ process.exit(1);
116
+ }
117
+ updatedConfig.archiveStrategy = value;
118
+ break;
119
+ }
107
120
  default:
108
121
  console.error(`\uC54C \uC218 \uC5C6\uB294 \uC124\uC815 \uD0A4: ${configKey}`);
109
122
  process.exit(1);
@@ -147,6 +160,7 @@ function getConfigHelp() {
147
160
  auto-open-editor fetch \uD6C4 \uC790\uB3D9\uC73C\uB85C \uC5D0\uB514\uD130 \uC5F4\uAE30 (true/false)
148
161
  solved-ac-handle Solved.ac \uD578\uB4E4 (stats \uBA85\uB839\uC5B4\uC6A9)
149
162
  problem-dir \uBB38\uC81C \uB514\uB809\uD1A0\uB9AC \uACBD\uB85C (\uAE30\uBCF8\uAC12: problems, "." \uB610\uB294 ""\uB294 \uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8)
163
+ archive-strategy \uC544\uCE74\uC774\uBE59 \uC804\uB7B5 (flat, by-range, by-tier, by-tag)
150
164
 
151
165
  \uC635\uC158:
152
166
  --help, -h \uB3C4\uC6C0\uB9D0 \uD45C\uC2DC
@@ -166,7 +180,8 @@ var CONFIG_KEYS = [
166
180
  { label: "editor", value: "editor" },
167
181
  { label: "auto-open-editor", value: "auto-open-editor" },
168
182
  { label: "solved-ac-handle", value: "solved-ac-handle" },
169
- { label: "problem-dir", value: "problem-dir" }
183
+ { label: "problem-dir", value: "problem-dir" },
184
+ { label: "archive-strategy", value: "archive-strategy" }
170
185
  ];
171
186
  function ConfigView({
172
187
  configKey,
@@ -199,6 +214,7 @@ function ConfigView({
199
214
  const autoOpen = config?.autoOpenEditor ?? getAutoOpenEditor();
200
215
  const handle = config?.solvedAcHandle ?? getSolvedAcHandle();
201
216
  const problemDir = config?.problemDir ?? getProblemDir();
217
+ const archiveStrategy = config?.archiveStrategy ?? getArchiveStrategy();
202
218
  return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
203
219
  /* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { color: "cyan", bold: true, children: "\u2699\uFE0F \uD604\uC7AC \uC124\uC815 (.ps-cli.json)" }) }),
204
220
  /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
@@ -226,6 +242,11 @@ function ConfigView({
226
242
  /* @__PURE__ */ jsx(Text, { color: "gray", children: "problem-dir:" }),
227
243
  /* @__PURE__ */ jsx(Text, { children: " " }),
228
244
  /* @__PURE__ */ jsx(Text, { bold: true, children: problemDir })
245
+ ] }),
246
+ /* @__PURE__ */ jsxs(Box, { marginBottom: 1, children: [
247
+ /* @__PURE__ */ jsx(Text, { color: "gray", children: "archive-strategy:" }),
248
+ /* @__PURE__ */ jsx(Text, { children: " " }),
249
+ /* @__PURE__ */ jsx(Text, { bold: true, children: archiveStrategy })
229
250
  ] })
230
251
  ] })
231
252
  ] });
@@ -248,6 +269,9 @@ function ConfigView({
248
269
  case "problem-dir":
249
270
  configValue = config?.problemDir ?? getProblemDir();
250
271
  break;
272
+ case "archive-strategy":
273
+ configValue = config?.archiveStrategy ?? getArchiveStrategy();
274
+ break;
251
275
  default:
252
276
  console.error(`\uC54C \uC218 \uC5C6\uB294 \uC124\uC815 \uD0A4: ${configKey}`);
253
277
  process.exit(1);
@@ -418,6 +442,8 @@ var ConfigCommand = class extends Command {
418
442
  return "Solved.ac \uD578\uB4E4 \uC785\uB825";
419
443
  case "problem-dir":
420
444
  return "\uBB38\uC81C \uB514\uB809\uD1A0\uB9AC \uACBD\uB85C \uC785\uB825";
445
+ case "archive-strategy":
446
+ return "\uC544\uCE74\uC774\uBE59 \uC804\uB7B5 \uC785\uB825 (flat, by-range, by-tier, by-tag)";
421
447
  default:
422
448
  return "\uAC12 \uC785\uB825";
423
449
  }
@@ -434,6 +460,8 @@ var ConfigCommand = class extends Command {
434
460
  return "Solved.ac \uC0AC\uC6A9\uC790 \uD578\uB4E4";
435
461
  case "problem-dir":
436
462
  return '\uBB38\uC81C \uB514\uB809\uD1A0\uB9AC \uACBD\uB85C (\uAE30\uBCF8\uAC12: "problems", \uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8: ".")';
463
+ case "archive-strategy":
464
+ return "\uC544\uCE74\uC774\uBE59 \uC804\uB7B5: flat (\uD3C9\uBA74), by-range (1000\uBC88\uB300 \uBB36\uAE30), by-tier (\uD2F0\uC5B4\uBCC4), by-tag (\uD0DC\uADF8\uBCC4)";
437
465
  default:
438
466
  return "";
439
467
  }
@@ -448,6 +476,8 @@ var ConfigCommand = class extends Command {
448
476
  return ["true", "false"];
449
477
  case "problem-dir":
450
478
  return ["problems", ".", ""];
479
+ case "archive-strategy":
480
+ return ["flat", "by-range", "by-tier", "by-tag"];
451
481
  default:
452
482
  return [];
453
483
  }
@@ -5,21 +5,18 @@ import {
5
5
  import {
6
6
  getProblem
7
7
  } from "../chunk-A6STXEAE.js";
8
- import {
9
- getTierColor,
10
- getTierImageUrl,
11
- getTierName,
12
- source_default
13
- } from "../chunk-HDNNR5OY.js";
14
8
  import {
15
9
  Command,
16
10
  CommandBuilder,
17
11
  CommandDef,
18
12
  getAutoOpenEditor,
19
13
  getEditor,
20
- getProblemDirPath,
21
- getProblemId
22
- } from "../chunk-7SVCS23X.js";
14
+ getProblemId,
15
+ getSolvingDirPath,
16
+ getTierColor,
17
+ getTierImageUrl,
18
+ getTierName
19
+ } from "../chunk-TNGUME4H.js";
23
20
  import {
24
21
  __decorateClass,
25
22
  getLanguageConfig,
@@ -33,14 +30,14 @@ import { Spinner } from "@inkjs/ui";
33
30
  import { Box as Box2 } from "ink";
34
31
 
35
32
  // src/components/problem-dashboard.tsx
36
- import { Box, Text, Transform } from "ink";
33
+ import { Box, Text } from "ink";
37
34
  import { jsx, jsxs } from "react/jsx-runtime";
38
35
  function ProblemDashboard({ problem }) {
39
36
  const tierName = getTierName(problem.level);
40
37
  const tierColor = getTierColor(problem.level);
41
- const tierColorFn = typeof tierColor === "string" ? source_default.hex(tierColor) : tierColor.multiline;
42
38
  const borderColorString = typeof tierColor === "string" ? tierColor : "#ff7ca8";
43
- return /* @__PURE__ */ jsx(Transform, { transform: (output) => tierColorFn(output), children: /* @__PURE__ */ jsx(
39
+ const textColorString = borderColorString;
40
+ return /* @__PURE__ */ jsx(
44
41
  Box,
45
42
  {
46
43
  flexDirection: "column",
@@ -48,7 +45,7 @@ function ProblemDashboard({ problem }) {
48
45
  borderColor: borderColorString,
49
46
  paddingX: 1,
50
47
  alignSelf: "flex-start",
51
- children: /* @__PURE__ */ jsxs(Text, { bold: true, children: [
48
+ children: /* @__PURE__ */ jsxs(Text, { bold: true, color: textColorString, children: [
52
49
  tierName,
53
50
  " ",
54
51
  /* @__PURE__ */ jsxs(Text, { color: "white", children: [
@@ -59,7 +56,7 @@ function ProblemDashboard({ problem }) {
59
56
  ] })
60
57
  ] })
61
58
  }
62
- ) });
59
+ );
63
60
  }
64
61
 
65
62
  // src/hooks/use-fetch-problem.ts
@@ -87,7 +84,7 @@ function getProjectRoot() {
87
84
  return join(__dirname, "../..");
88
85
  }
89
86
  async function generateProblemFiles(problem, language = "python") {
90
- const problemDir = getProblemDirPath(problem.id);
87
+ const problemDir = getSolvingDirPath(problem.id, process.cwd(), problem);
91
88
  await mkdir(problemDir, { recursive: true });
92
89
  const langConfig = getLanguageConfig(language);
93
90
  const projectRoot = getProjectRoot();
@@ -189,6 +186,7 @@ ${tags}
189
186
  id: problem.id,
190
187
  title: problem.title,
191
188
  level: problem.level,
189
+ tags: problem.tags,
192
190
  timeLimit: problem.timeLimit,
193
191
  timeLimitMs: parseTimeLimitToMs(problem.timeLimit),
194
192
  memoryLimit: problem.memoryLimit
@@ -3,12 +3,14 @@ import {
3
3
  Command,
4
4
  CommandBuilder,
5
5
  CommandDef,
6
+ getArchiveStrategy,
6
7
  getAutoOpenEditor,
7
8
  getDefaultLanguage,
8
9
  getEditor,
9
10
  getProblemDir,
10
- getSolvedAcHandle
11
- } from "../chunk-7SVCS23X.js";
11
+ getSolvedAcHandle,
12
+ getSolvingDir
13
+ } from "../chunk-TNGUME4H.js";
12
14
  import {
13
15
  __decorateClass,
14
16
  getSupportedLanguages
@@ -35,6 +37,8 @@ function useInit({ onComplete }) {
35
37
  const [confirmExit, setConfirmExit] = useState(false);
36
38
  const [initialized, setInitialized] = useState(false);
37
39
  const [problemDir, setProblemDirValue] = useState(getProblemDir());
40
+ const [solvingDir, setSolvingDirValue] = useState(getSolvingDir());
41
+ const [archiveStrategy, setArchiveStrategy] = useState(getArchiveStrategy());
38
42
  const [language, setLanguage] = useState(getDefaultLanguage());
39
43
  const [editor, setEditorValue] = useState(getEditor());
40
44
  const [autoOpen, setAutoOpen] = useState(getAutoOpenEditor());
@@ -69,6 +73,10 @@ function useInit({ onComplete }) {
69
73
  const projectConfig = JSON.parse(configContent);
70
74
  if (projectConfig.problemDir)
71
75
  setProblemDirValue(projectConfig.problemDir);
76
+ if (projectConfig.solvingDir)
77
+ setSolvingDirValue(projectConfig.solvingDir);
78
+ if (projectConfig.archiveStrategy)
79
+ setArchiveStrategy(projectConfig.archiveStrategy);
72
80
  if (projectConfig.defaultLanguage)
73
81
  setLanguage(projectConfig.defaultLanguage);
74
82
  if (projectConfig.editor) setEditorValue(projectConfig.editor);
@@ -86,7 +94,11 @@ function useInit({ onComplete }) {
86
94
  const getStepLabel = useCallback((step) => {
87
95
  switch (step) {
88
96
  case "problem-dir":
89
- return "\uBB38\uC81C \uB514\uB809\uD1A0\uB9AC \uC124\uC815";
97
+ return "\uBB38\uC81C \uB514\uB809\uD1A0\uB9AC \uC124\uC815 (\uC544\uCE74\uC774\uBE0C\uB41C \uBB38\uC81C)";
98
+ case "solving-dir":
99
+ return "Solving \uB514\uB809\uD1A0\uB9AC \uC124\uC815 (\uD478\uB294 \uC911\uC778 \uBB38\uC81C)";
100
+ case "archive-strategy":
101
+ return "\uC544\uCE74\uC774\uBE59 \uC804\uB7B5 \uC124\uC815";
90
102
  case "language":
91
103
  return "\uAE30\uBCF8 \uC5B8\uC5B4 \uC124\uC815";
92
104
  case "editor":
@@ -104,6 +116,17 @@ function useInit({ onComplete }) {
104
116
  switch (step) {
105
117
  case "problem-dir":
106
118
  return problemDir === "." ? "\uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8" : problemDir;
119
+ case "solving-dir":
120
+ return solvingDir === "." ? "\uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8" : solvingDir;
121
+ case "archive-strategy": {
122
+ const strategyLabels = {
123
+ flat: "\uD3C9\uBA74 (\uC804\uBD80 \uB098\uC5F4)",
124
+ "by-range": "1000\uBC88\uB300 \uBB36\uAE30",
125
+ "by-tier": "\uD2F0\uC5B4\uBCC4",
126
+ "by-tag": "\uD0DC\uADF8\uBCC4"
127
+ };
128
+ return strategyLabels[archiveStrategy] || archiveStrategy;
129
+ }
107
130
  case "language":
108
131
  return language;
109
132
  case "editor":
@@ -116,121 +139,170 @@ function useInit({ onComplete }) {
116
139
  return "";
117
140
  }
118
141
  },
119
- [problemDir, language, editor, autoOpen, handle]
142
+ [
143
+ problemDir,
144
+ solvingDir,
145
+ archiveStrategy,
146
+ language,
147
+ editor,
148
+ autoOpen,
149
+ handle
150
+ ]
120
151
  );
121
- const executeInit = useCallback(async () => {
122
- try {
123
- const cwd = process.cwd();
124
- const projectConfigPath = join(cwd, ".ps-cli.json");
125
- const projectConfig = {
126
- problemDir,
127
- defaultLanguage: language,
128
- editor,
129
- autoOpenEditor: autoOpen,
130
- solvedAcHandle: handle || void 0
131
- };
132
- await writeFile(
133
- projectConfigPath,
134
- JSON.stringify(projectConfig, null, 2),
135
- "utf-8"
136
- );
137
- setCreated((prev) => [...prev, ".ps-cli.json"]);
138
- if (problemDir !== "." && problemDir !== "") {
139
- const problemDirPath = join(cwd, problemDir);
140
- try {
141
- await mkdir(problemDirPath, { recursive: true });
142
- setCreated((prev) => [...prev, `${problemDir}/`]);
143
- } catch (err) {
144
- const error = err;
145
- if (error.code !== "EEXIST") {
146
- throw err;
147
- }
152
+ const executeInit = useCallback(
153
+ async (overrideHandle) => {
154
+ try {
155
+ const cwd = process.cwd();
156
+ const projectConfigPath = join(cwd, ".ps-cli.json");
157
+ const projectConfig = {
158
+ problemDir,
159
+ solvingDir,
160
+ archiveStrategy,
161
+ defaultLanguage: language,
162
+ editor,
163
+ autoOpenEditor: autoOpen
164
+ };
165
+ const handleToUse = overrideHandle ?? handle;
166
+ if (handleToUse && typeof handleToUse === "string" && handleToUse.trim().length > 0) {
167
+ projectConfig.solvedAcHandle = handleToUse.trim();
148
168
  }
149
- const gitignorePath = join(cwd, ".gitignore");
150
- const gitignorePattern = `${problemDir}/`;
151
- try {
152
- const gitignoreContent = await readFile(gitignorePath, "utf-8");
153
- if (!gitignoreContent.includes(gitignorePattern)) {
154
- const updatedContent = gitignoreContent.trim() + (gitignoreContent.trim() ? "\n" : "") + `
155
- # ps-cli \uBB38\uC81C \uB514\uB809\uD1A0\uB9AC
156
- ${gitignorePattern}
157
- `;
158
- await writeFile(gitignorePath, updatedContent, "utf-8");
159
- setCreated((prev) => [...prev, ".gitignore \uC5C5\uB370\uC774\uD2B8"]);
169
+ await writeFile(
170
+ projectConfigPath,
171
+ JSON.stringify(projectConfig, null, 2),
172
+ "utf-8"
173
+ );
174
+ setCreated((prev) => [...prev, ".ps-cli.json"]);
175
+ if (problemDir !== "." && problemDir !== "") {
176
+ const problemDirPath = join(cwd, problemDir);
177
+ try {
178
+ await mkdir(problemDirPath, { recursive: true });
179
+ setCreated((prev) => [...prev, `${problemDir}/`]);
180
+ } catch (err) {
181
+ const error = err;
182
+ if (error.code !== "EEXIST") {
183
+ throw err;
184
+ }
160
185
  }
161
- } catch (err) {
162
- const error = err;
163
- if (error.code === "ENOENT") {
164
- await writeFile(
165
- gitignorePath,
166
- `# ps-cli \uBB38\uC81C \uB514\uB809\uD1A0\uB9AC
167
- ${gitignorePattern}
168
- `,
169
- "utf-8"
170
- );
171
- setCreated((prev) => [...prev, ".gitignore \uC0DD\uC131"]);
172
- } else {
173
- console.warn(".gitignore \uC5C5\uB370\uC774\uD2B8 \uC2E4\uD328:", error.message);
186
+ }
187
+ if (solvingDir !== "." && solvingDir !== "") {
188
+ const solvingDirPath = join(cwd, solvingDir);
189
+ try {
190
+ await mkdir(solvingDirPath, { recursive: true });
191
+ setCreated((prev) => [...prev, `${solvingDir}/`]);
192
+ } catch (err) {
193
+ const error = err;
194
+ if (error.code !== "EEXIST") {
195
+ throw err;
196
+ }
174
197
  }
175
198
  }
176
- }
177
- try {
178
- const gitDir = join(cwd, ".git");
179
- let isGitRepo = false;
180
- try {
181
- await access(gitDir);
182
- isGitRepo = true;
183
- } catch {
199
+ const gitignorePath = join(cwd, ".gitignore");
200
+ const gitignorePatterns = [];
201
+ if (solvingDir !== "." && solvingDir !== "") {
202
+ gitignorePatterns.push(`${solvingDir}/`);
184
203
  }
185
- if (!isGitRepo) {
186
- await execaCommand("git init", { cwd });
187
- setCreated((prev) => [...prev, "Git \uC800\uC7A5\uC18C \uCD08\uAE30\uD654"]);
204
+ if (gitignorePatterns.length > 0) {
205
+ try {
206
+ const gitignoreContent = await readFile(gitignorePath, "utf-8");
207
+ let updatedContent = gitignoreContent.trim();
208
+ let hasChanges = false;
209
+ for (const pattern of gitignorePatterns) {
210
+ if (!gitignoreContent.includes(pattern)) {
211
+ updatedContent += (updatedContent ? "\n" : "") + `# ps-cli \uBB38\uC81C \uB514\uB809\uD1A0\uB9AC
212
+ ${pattern}`;
213
+ hasChanges = true;
214
+ }
215
+ }
216
+ if (hasChanges) {
217
+ await writeFile(gitignorePath, updatedContent + "\n", "utf-8");
218
+ setCreated((prev) => [...prev, ".gitignore \uC5C5\uB370\uC774\uD2B8"]);
219
+ }
220
+ } catch (err) {
221
+ const error = err;
222
+ if (error.code === "ENOENT") {
223
+ const content = `# ps-cli \uBB38\uC81C \uB514\uB809\uD1A0\uB9AC
224
+ ${gitignorePatterns.join("\n")}
225
+ `;
226
+ await writeFile(gitignorePath, content, "utf-8");
227
+ setCreated((prev) => [...prev, ".gitignore \uC0DD\uC131"]);
228
+ } else {
229
+ console.warn(".gitignore \uC5C5\uB370\uC774\uD2B8 \uC2E4\uD328:", error.message);
230
+ }
231
+ }
188
232
  }
189
- const filesToAdd = [".ps-cli.json"];
190
- const gitignorePath = join(cwd, ".gitignore");
191
233
  try {
192
- await access(gitignorePath);
193
- filesToAdd.push(".gitignore");
194
- } catch {
195
- }
196
- if (filesToAdd.length > 0) {
197
- await execa("git", ["add", ...filesToAdd], { cwd });
234
+ const gitDir = join(cwd, ".git");
235
+ let isGitRepo = false;
198
236
  try {
199
- await execa("git", ["rev-parse", "--verify", "HEAD"], { cwd });
237
+ await access(gitDir);
238
+ isGitRepo = true;
200
239
  } catch {
201
- await execa(
202
- "git",
203
- ["commit", "-m", "chore: ps-cli \uD504\uB85C\uC81D\uD2B8 \uCD08\uAE30\uD654"],
204
- { cwd }
205
- );
206
- setCreated((prev) => [...prev, "\uCD08\uAE30 \uCEE4\uBC0B \uC0DD\uC131"]);
207
240
  }
241
+ if (!isGitRepo) {
242
+ await execaCommand("git init", { cwd });
243
+ setCreated((prev) => [...prev, "Git \uC800\uC7A5\uC18C \uCD08\uAE30\uD654"]);
244
+ }
245
+ const filesToAdd = [".ps-cli.json"];
246
+ const gitignorePath2 = join(cwd, ".gitignore");
247
+ try {
248
+ await access(gitignorePath2);
249
+ filesToAdd.push(".gitignore");
250
+ } catch {
251
+ }
252
+ if (filesToAdd.length > 0) {
253
+ await execa("git", ["add", ...filesToAdd], { cwd });
254
+ try {
255
+ await execa("git", ["rev-parse", "--verify", "HEAD"], { cwd });
256
+ } catch {
257
+ await execa(
258
+ "git",
259
+ ["commit", "-m", "chore: ps-cli \uD504\uB85C\uC81D\uD2B8 \uCD08\uAE30\uD654"],
260
+ { cwd }
261
+ );
262
+ setCreated((prev) => [...prev, "\uCD08\uAE30 \uCEE4\uBC0B \uC0DD\uC131"]);
263
+ }
264
+ }
265
+ } catch (err) {
266
+ const error = err;
267
+ console.warn("Git \uC5F0\uB3D9 \uC2E4\uD328:", error.message);
208
268
  }
269
+ setTimeout(() => {
270
+ onComplete();
271
+ }, 3e3);
209
272
  } catch (err) {
210
273
  const error = err;
211
- console.warn("Git \uC5F0\uB3D9 \uC2E4\uD328:", error.message);
274
+ console.error("\uCD08\uAE30\uD654 \uC911 \uC624\uB958 \uBC1C\uC0DD:", error.message);
275
+ setCancelled(true);
276
+ setCurrentStep("cancelled");
277
+ setTimeout(() => {
278
+ onComplete();
279
+ }, 2e3);
212
280
  }
213
- setTimeout(() => {
214
- onComplete();
215
- }, 3e3);
216
- } catch (err) {
217
- const error = err;
218
- console.error("\uCD08\uAE30\uD654 \uC911 \uC624\uB958 \uBC1C\uC0DD:", error.message);
219
- setCancelled(true);
220
- setCurrentStep("cancelled");
221
- setTimeout(() => {
222
- onComplete();
223
- }, 2e3);
224
- }
225
- }, [problemDir, language, editor, autoOpen, handle, onComplete]);
281
+ },
282
+ [
283
+ problemDir,
284
+ solvingDir,
285
+ archiveStrategy,
286
+ language,
287
+ editor,
288
+ autoOpen,
289
+ handle,
290
+ onComplete
291
+ ]
292
+ );
226
293
  const moveToNextStep = useCallback(
227
- (selectedValue, stepLabel) => {
294
+ (selectedValue, stepLabel, handleValue) => {
228
295
  setCompletedSteps((prev) => [
229
296
  ...prev,
230
297
  { label: stepLabel, value: selectedValue }
231
298
  ]);
299
+ if (currentStep === "handle" && handleValue !== void 0) {
300
+ setHandle(handleValue);
301
+ }
232
302
  const stepOrder = [
233
303
  "problem-dir",
304
+ "solving-dir",
305
+ "archive-strategy",
234
306
  "language",
235
307
  "editor",
236
308
  "auto-open",
@@ -242,11 +314,25 @@ ${gitignorePattern}
242
314
  const nextStep = stepOrder[currentIndex + 1];
243
315
  setCurrentStep(nextStep);
244
316
  if (nextStep === "done") {
245
- void executeInit();
317
+ if (currentStep === "handle" && handleValue !== void 0) {
318
+ void executeInit(handleValue.trim());
319
+ } else {
320
+ void executeInit();
321
+ }
246
322
  }
247
323
  }
248
324
  },
249
- [currentStep, executeInit]
325
+ [
326
+ currentStep,
327
+ executeInit,
328
+ problemDir,
329
+ solvingDir,
330
+ archiveStrategy,
331
+ language,
332
+ editor,
333
+ autoOpen,
334
+ onComplete
335
+ ]
250
336
  );
251
337
  return {
252
338
  currentStep,
@@ -254,6 +340,8 @@ ${gitignorePattern}
254
340
  confirmExit,
255
341
  initialized,
256
342
  problemDir,
343
+ solvingDir,
344
+ archiveStrategy,
257
345
  language,
258
346
  editor,
259
347
  autoOpen,
@@ -262,6 +350,8 @@ ${gitignorePattern}
262
350
  created,
263
351
  cancelled,
264
352
  setProblemDirValue,
353
+ setSolvingDirValue,
354
+ setArchiveStrategy,
265
355
  setLanguage,
266
356
  setEditorValue,
267
357
  setAutoOpen,
@@ -288,6 +378,8 @@ function InitView({ onComplete }) {
288
378
  created,
289
379
  cancelled,
290
380
  setProblemDirValue,
381
+ setSolvingDirValue,
382
+ setArchiveStrategy,
291
383
  setLanguage,
292
384
  setEditorValue,
293
385
  setAutoOpen,
@@ -352,6 +444,56 @@ function InitView({ onComplete }) {
352
444
  )
353
445
  );
354
446
  }
447
+ case "solving-dir": {
448
+ const options = [
449
+ { label: "solving", value: "solving" },
450
+ { label: ". (\uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8)", value: "." }
451
+ ];
452
+ return renderQuestionCard(
453
+ getStepLabel(currentStep),
454
+ /* @__PURE__ */ jsx(
455
+ Select,
456
+ {
457
+ options,
458
+ onChange: (value) => {
459
+ setSolvingDirValue(value);
460
+ const displayValue = value === "." ? "\uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8" : value;
461
+ moveToNextStep(displayValue, getStepLabel(currentStep));
462
+ }
463
+ }
464
+ )
465
+ );
466
+ }
467
+ case "archive-strategy": {
468
+ const options = [
469
+ { label: "\uD3C9\uBA74 (\uC804\uBD80 \uB098\uC5F4)", value: "flat" },
470
+ { label: "1000\uBC88\uB300 \uBB36\uAE30", value: "by-range" },
471
+ { label: "\uD2F0\uC5B4\uBCC4", value: "by-tier" },
472
+ { label: "\uD0DC\uADF8\uBCC4", value: "by-tag" }
473
+ ];
474
+ return renderQuestionCard(
475
+ getStepLabel(currentStep),
476
+ /* @__PURE__ */ jsx(
477
+ Select,
478
+ {
479
+ options,
480
+ onChange: (value) => {
481
+ setArchiveStrategy(value);
482
+ const strategyLabels = {
483
+ flat: "\uD3C9\uBA74 (\uC804\uBD80 \uB098\uC5F4)",
484
+ "by-range": "1000\uBC88\uB300 \uBB36\uAE30",
485
+ "by-tier": "\uD2F0\uC5B4\uBCC4",
486
+ "by-tag": "\uD0DC\uADF8\uBCC4"
487
+ };
488
+ moveToNextStep(
489
+ strategyLabels[value] || value,
490
+ getStepLabel(currentStep)
491
+ );
492
+ }
493
+ }
494
+ )
495
+ );
496
+ }
355
497
  case "language": {
356
498
  const supportedLanguages = getSupportedLanguages();
357
499
  const options = supportedLanguages.map((lang) => ({
@@ -424,9 +566,14 @@ function InitView({ onComplete }) {
424
566
  {
425
567
  placeholder: "\uD578\uB4E4 \uC785\uB825",
426
568
  onSubmit: (value) => {
427
- setHandle(value);
569
+ const handleValue = value.trim();
570
+ setHandle(handleValue);
428
571
  setHandleInputMode(false);
429
- moveToNextStep(value || "(\uC2A4\uD0B5)", getStepLabel(currentStep));
572
+ moveToNextStep(
573
+ handleValue || "(\uC2A4\uD0B5)",
574
+ getStepLabel(currentStep),
575
+ handleValue
576
+ );
430
577
  }
431
578
  }
432
579
  ) })
@@ -9,7 +9,7 @@ import {
9
9
  CommandDef,
10
10
  getProblemId,
11
11
  resolveProblemContext
12
- } from "../chunk-7SVCS23X.js";
12
+ } from "../chunk-TNGUME4H.js";
13
13
  import {
14
14
  __decorateClass
15
15
  } from "../chunk-7MQMPJ3X.js";
@@ -9,7 +9,7 @@ import {
9
9
  getProblemId,
10
10
  resolveLanguage,
11
11
  resolveProblemContext
12
- } from "../chunk-7SVCS23X.js";
12
+ } from "../chunk-TNGUME4H.js";
13
13
  import {
14
14
  __decorateClass,
15
15
  getSupportedLanguagesString