@rhseung/ps-cli 1.6.0 → 1.7.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.
@@ -3,13 +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
11
  getSolvedAcHandle,
11
12
  getSolvingDir
12
- } from "../chunk-RVD22OUQ.js";
13
+ } from "../chunk-TNGUME4H.js";
13
14
  import {
14
15
  __decorateClass,
15
16
  getSupportedLanguages
@@ -37,6 +38,7 @@ function useInit({ onComplete }) {
37
38
  const [initialized, setInitialized] = useState(false);
38
39
  const [problemDir, setProblemDirValue] = useState(getProblemDir());
39
40
  const [solvingDir, setSolvingDirValue] = useState(getSolvingDir());
41
+ const [archiveStrategy, setArchiveStrategy] = useState(getArchiveStrategy());
40
42
  const [language, setLanguage] = useState(getDefaultLanguage());
41
43
  const [editor, setEditorValue] = useState(getEditor());
42
44
  const [autoOpen, setAutoOpen] = useState(getAutoOpenEditor());
@@ -73,6 +75,8 @@ function useInit({ onComplete }) {
73
75
  setProblemDirValue(projectConfig.problemDir);
74
76
  if (projectConfig.solvingDir)
75
77
  setSolvingDirValue(projectConfig.solvingDir);
78
+ if (projectConfig.archiveStrategy)
79
+ setArchiveStrategy(projectConfig.archiveStrategy);
76
80
  if (projectConfig.defaultLanguage)
77
81
  setLanguage(projectConfig.defaultLanguage);
78
82
  if (projectConfig.editor) setEditorValue(projectConfig.editor);
@@ -93,6 +97,8 @@ function useInit({ onComplete }) {
93
97
  return "\uBB38\uC81C \uB514\uB809\uD1A0\uB9AC \uC124\uC815 (\uC544\uCE74\uC774\uBE0C\uB41C \uBB38\uC81C)";
94
98
  case "solving-dir":
95
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";
96
102
  case "language":
97
103
  return "\uAE30\uBCF8 \uC5B8\uC5B4 \uC124\uC815";
98
104
  case "editor":
@@ -112,6 +118,15 @@ function useInit({ onComplete }) {
112
118
  return problemDir === "." ? "\uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8" : problemDir;
113
119
  case "solving-dir":
114
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
+ }
115
130
  case "language":
116
131
  return language;
117
132
  case "editor":
@@ -124,145 +139,170 @@ function useInit({ onComplete }) {
124
139
  return "";
125
140
  }
126
141
  },
127
- [problemDir, solvingDir, language, editor, autoOpen, handle]
142
+ [
143
+ problemDir,
144
+ solvingDir,
145
+ archiveStrategy,
146
+ language,
147
+ editor,
148
+ autoOpen,
149
+ handle
150
+ ]
128
151
  );
129
- const executeInit = useCallback(async () => {
130
- try {
131
- const cwd = process.cwd();
132
- const projectConfigPath = join(cwd, ".ps-cli.json");
133
- const projectConfig = {
134
- problemDir,
135
- solvingDir,
136
- defaultLanguage: language,
137
- editor,
138
- autoOpenEditor: autoOpen,
139
- solvedAcHandle: handle || void 0
140
- };
141
- await writeFile(
142
- projectConfigPath,
143
- JSON.stringify(projectConfig, null, 2),
144
- "utf-8"
145
- );
146
- setCreated((prev) => [...prev, ".ps-cli.json"]);
147
- if (problemDir !== "." && problemDir !== "") {
148
- const problemDirPath = join(cwd, problemDir);
149
- try {
150
- await mkdir(problemDirPath, { recursive: true });
151
- setCreated((prev) => [...prev, `${problemDir}/`]);
152
- } catch (err) {
153
- const error = err;
154
- if (error.code !== "EEXIST") {
155
- throw err;
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();
168
+ }
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
+ }
156
185
  }
157
186
  }
158
- }
159
- if (solvingDir !== "." && solvingDir !== "") {
160
- const solvingDirPath = join(cwd, solvingDir);
161
- try {
162
- await mkdir(solvingDirPath, { recursive: true });
163
- setCreated((prev) => [...prev, `${solvingDir}/`]);
164
- } catch (err) {
165
- const error = err;
166
- if (error.code !== "EEXIST") {
167
- throw err;
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
+ }
168
197
  }
169
198
  }
170
- }
171
- const gitignorePath = join(cwd, ".gitignore");
172
- const gitignorePatterns = [];
173
- if (problemDir !== "." && problemDir !== "") {
174
- gitignorePatterns.push(`${problemDir}/`);
175
- }
176
- if (solvingDir !== "." && solvingDir !== "") {
177
- gitignorePatterns.push(`${solvingDir}/`);
178
- }
179
- if (gitignorePatterns.length > 0) {
180
- try {
181
- const gitignoreContent = await readFile(gitignorePath, "utf-8");
182
- let updatedContent = gitignoreContent.trim();
183
- let hasChanges = false;
184
- for (const pattern of gitignorePatterns) {
185
- if (!gitignoreContent.includes(pattern)) {
186
- updatedContent += (updatedContent ? "\n" : "") + `# ps-cli \uBB38\uC81C \uB514\uB809\uD1A0\uB9AC
199
+ const gitignorePath = join(cwd, ".gitignore");
200
+ const gitignorePatterns = [];
201
+ if (solvingDir !== "." && solvingDir !== "") {
202
+ gitignorePatterns.push(`${solvingDir}/`);
203
+ }
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
187
212
  ${pattern}`;
188
- hasChanges = true;
213
+ hasChanges = true;
214
+ }
189
215
  }
190
- }
191
- if (hasChanges) {
192
- await writeFile(gitignorePath, updatedContent + "\n", "utf-8");
193
- setCreated((prev) => [...prev, ".gitignore \uC5C5\uB370\uC774\uD2B8"]);
194
- }
195
- } catch (err) {
196
- const error = err;
197
- if (error.code === "ENOENT") {
198
- const content = `# ps-cli \uBB38\uC81C \uB514\uB809\uD1A0\uB9AC
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
199
224
  ${gitignorePatterns.join("\n")}
200
225
  `;
201
- await writeFile(gitignorePath, content, "utf-8");
202
- setCreated((prev) => [...prev, ".gitignore \uC0DD\uC131"]);
203
- } else {
204
- console.warn(".gitignore \uC5C5\uB370\uC774\uD2B8 \uC2E4\uD328:", error.message);
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
+ }
205
231
  }
206
232
  }
207
- }
208
- try {
209
- const gitDir = join(cwd, ".git");
210
- let isGitRepo = false;
211
233
  try {
212
- await access(gitDir);
213
- isGitRepo = true;
214
- } catch {
215
- }
216
- if (!isGitRepo) {
217
- await execaCommand("git init", { cwd });
218
- setCreated((prev) => [...prev, "Git \uC800\uC7A5\uC18C \uCD08\uAE30\uD654"]);
219
- }
220
- const filesToAdd = [".ps-cli.json"];
221
- const gitignorePath2 = join(cwd, ".gitignore");
222
- try {
223
- await access(gitignorePath2);
224
- filesToAdd.push(".gitignore");
225
- } catch {
226
- }
227
- if (filesToAdd.length > 0) {
228
- await execa("git", ["add", ...filesToAdd], { cwd });
234
+ const gitDir = join(cwd, ".git");
235
+ let isGitRepo = false;
229
236
  try {
230
- await execa("git", ["rev-parse", "--verify", "HEAD"], { cwd });
237
+ await access(gitDir);
238
+ isGitRepo = true;
231
239
  } catch {
232
- await execa(
233
- "git",
234
- ["commit", "-m", "chore: ps-cli \uD504\uB85C\uC81D\uD2B8 \uCD08\uAE30\uD654"],
235
- { cwd }
236
- );
237
- setCreated((prev) => [...prev, "\uCD08\uAE30 \uCEE4\uBC0B \uC0DD\uC131"]);
238
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);
239
268
  }
269
+ setTimeout(() => {
270
+ onComplete();
271
+ }, 3e3);
240
272
  } catch (err) {
241
273
  const error = err;
242
- 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);
243
280
  }
244
- setTimeout(() => {
245
- onComplete();
246
- }, 3e3);
247
- } catch (err) {
248
- const error = err;
249
- console.error("\uCD08\uAE30\uD654 \uC911 \uC624\uB958 \uBC1C\uC0DD:", error.message);
250
- setCancelled(true);
251
- setCurrentStep("cancelled");
252
- setTimeout(() => {
253
- onComplete();
254
- }, 2e3);
255
- }
256
- }, [problemDir, solvingDir, 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
+ );
257
293
  const moveToNextStep = useCallback(
258
- (selectedValue, stepLabel) => {
294
+ (selectedValue, stepLabel, handleValue) => {
259
295
  setCompletedSteps((prev) => [
260
296
  ...prev,
261
297
  { label: stepLabel, value: selectedValue }
262
298
  ]);
299
+ if (currentStep === "handle" && handleValue !== void 0) {
300
+ setHandle(handleValue);
301
+ }
263
302
  const stepOrder = [
264
303
  "problem-dir",
265
304
  "solving-dir",
305
+ "archive-strategy",
266
306
  "language",
267
307
  "editor",
268
308
  "auto-open",
@@ -274,11 +314,25 @@ ${gitignorePatterns.join("\n")}
274
314
  const nextStep = stepOrder[currentIndex + 1];
275
315
  setCurrentStep(nextStep);
276
316
  if (nextStep === "done") {
277
- void executeInit();
317
+ if (currentStep === "handle" && handleValue !== void 0) {
318
+ void executeInit(handleValue.trim());
319
+ } else {
320
+ void executeInit();
321
+ }
278
322
  }
279
323
  }
280
324
  },
281
- [currentStep, executeInit]
325
+ [
326
+ currentStep,
327
+ executeInit,
328
+ problemDir,
329
+ solvingDir,
330
+ archiveStrategy,
331
+ language,
332
+ editor,
333
+ autoOpen,
334
+ onComplete
335
+ ]
282
336
  );
283
337
  return {
284
338
  currentStep,
@@ -287,6 +341,7 @@ ${gitignorePatterns.join("\n")}
287
341
  initialized,
288
342
  problemDir,
289
343
  solvingDir,
344
+ archiveStrategy,
290
345
  language,
291
346
  editor,
292
347
  autoOpen,
@@ -296,6 +351,7 @@ ${gitignorePatterns.join("\n")}
296
351
  cancelled,
297
352
  setProblemDirValue,
298
353
  setSolvingDirValue,
354
+ setArchiveStrategy,
299
355
  setLanguage,
300
356
  setEditorValue,
301
357
  setAutoOpen,
@@ -323,6 +379,7 @@ function InitView({ onComplete }) {
323
379
  cancelled,
324
380
  setProblemDirValue,
325
381
  setSolvingDirValue,
382
+ setArchiveStrategy,
326
383
  setLanguage,
327
384
  setEditorValue,
328
385
  setAutoOpen,
@@ -407,6 +464,36 @@ function InitView({ onComplete }) {
407
464
  )
408
465
  );
409
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
+ }
410
497
  case "language": {
411
498
  const supportedLanguages = getSupportedLanguages();
412
499
  const options = supportedLanguages.map((lang) => ({
@@ -479,9 +566,14 @@ function InitView({ onComplete }) {
479
566
  {
480
567
  placeholder: "\uD578\uB4E4 \uC785\uB825",
481
568
  onSubmit: (value) => {
482
- setHandle(value);
569
+ const handleValue = value.trim();
570
+ setHandle(handleValue);
483
571
  setHandleInputMode(false);
484
- moveToNextStep(value || "(\uC2A4\uD0B5)", getStepLabel(currentStep));
572
+ moveToNextStep(
573
+ handleValue || "(\uC2A4\uD0B5)",
574
+ getStepLabel(currentStep),
575
+ handleValue
576
+ );
485
577
  }
486
578
  }
487
579
  ) })
@@ -9,7 +9,7 @@ import {
9
9
  CommandDef,
10
10
  getProblemId,
11
11
  resolveProblemContext
12
- } from "../chunk-RVD22OUQ.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-RVD22OUQ.js";
12
+ } from "../chunk-TNGUME4H.js";
13
13
  import {
14
14
  __decorateClass,
15
15
  getSupportedLanguagesString
@@ -4,12 +4,10 @@ import {
4
4
  } from "../chunk-ASMT3CRD.js";
5
5
  import {
6
6
  searchProblems
7
- } from "../chunk-AG6KWWHS.js";
7
+ } from "../chunk-4ISG24GW.js";
8
8
  import {
9
- getProblem,
10
- getTierColor,
11
- getTierName
12
- } from "../chunk-NH36IFWR.js";
9
+ getProblem
10
+ } from "../chunk-A6STXEAE.js";
13
11
  import {
14
12
  useOpenBrowser
15
13
  } from "../chunk-GCOFFYJ3.js";
@@ -18,8 +16,10 @@ import {
18
16
  Command,
19
17
  CommandBuilder,
20
18
  CommandDef,
21
- getProblemDirPath
22
- } from "../chunk-RVD22OUQ.js";
19
+ getProblemDirPath,
20
+ getTierColor,
21
+ getTierName
22
+ } from "../chunk-TNGUME4H.js";
23
23
  import {
24
24
  __decorateClass
25
25
  } from "../chunk-7MQMPJ3X.js";
@@ -435,7 +435,7 @@ function SearchView({ query, onComplete }) {
435
435
  },
436
436
  header: /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", children: [
437
437
  /* @__PURE__ */ jsx2(Box2, { marginBottom: 1, children: /* @__PURE__ */ jsx2(Text2, { color: "cyan", bold: true, children: "\u{1F50D} \uAC80\uC0C9 \uACB0\uACFC" }) }),
438
- /* @__PURE__ */ jsx2(Box2, { marginBottom: 1, children: /* @__PURE__ */ jsxs2(Text2, { color: "gray", children: [
438
+ /* @__PURE__ */ jsx2(Box2, { children: /* @__PURE__ */ jsxs2(Text2, { color: "gray", children: [
439
439
  "\uCFFC\uB9AC: ",
440
440
  query
441
441
  ] }) })
@@ -6,8 +6,9 @@ import {
6
6
  findProjectRoot,
7
7
  getProblemDirPath,
8
8
  getProblemId,
9
+ getSolvingDir,
9
10
  getSolvingDirPath
10
- } from "../chunk-RVD22OUQ.js";
11
+ } from "../chunk-TNGUME4H.js";
11
12
  import {
12
13
  __decorateClass
13
14
  } from "../chunk-7MQMPJ3X.js";
@@ -18,8 +19,8 @@ import { Spinner } from "@inkjs/ui";
18
19
  import { Box } from "ink";
19
20
 
20
21
  // src/hooks/use-solve.ts
21
- import { access, readFile, rename } from "fs/promises";
22
- import { join } from "path";
22
+ import { access, readFile, rename, mkdir, readdir, rmdir } from "fs/promises";
23
+ import { join, dirname } from "path";
23
24
  import { execa } from "execa";
24
25
  import { useEffect, useState } from "react";
25
26
  function useSolve({
@@ -50,15 +51,27 @@ function useSolve({
50
51
  setMessage("\uBB38\uC81C \uC815\uBCF4\uB97C \uC77D\uB294 \uC911...");
51
52
  const metaPath = join(solvingDir, "meta.json");
52
53
  let problemTitle = `\uBB38\uC81C ${problemId}`;
54
+ let problem;
53
55
  try {
54
56
  const metaContent = await readFile(metaPath, "utf-8");
55
57
  const meta = JSON.parse(metaContent);
56
58
  if (meta.title) {
57
59
  problemTitle = meta.title;
58
60
  }
61
+ if (meta.id && meta.level !== void 0) {
62
+ problem = {
63
+ id: meta.id,
64
+ title: meta.title || `\uBB38\uC81C ${meta.id}`,
65
+ level: meta.level,
66
+ tier: "",
67
+ // tier는 level에서 계산되므로 빈 문자열로 충분
68
+ tags: meta.tags || [],
69
+ testCases: []
70
+ };
71
+ }
59
72
  } catch {
60
73
  }
61
- const problemDir = getProblemDirPath(problemId, projectRoot);
74
+ const problemDir = getProblemDirPath(problemId, projectRoot, problem);
62
75
  try {
63
76
  await access(problemDir);
64
77
  throw new Error(
@@ -69,8 +82,33 @@ function useSolve({
69
82
  throw err;
70
83
  }
71
84
  }
85
+ const problemDirParent = dirname(problemDir);
86
+ setMessage("\uC544\uCE74\uC774\uBE0C \uB514\uB809\uD1A0\uB9AC\uB97C \uC900\uBE44\uD558\uB294 \uC911...");
87
+ await mkdir(problemDirParent, { recursive: true });
72
88
  setMessage("\uBB38\uC81C\uB97C problem \uB514\uB809\uD1A0\uB9AC\uB85C \uC774\uB3D9\uD558\uB294 \uC911...");
73
89
  await rename(solvingDir, problemDir);
90
+ setMessage("\uBE48 \uB514\uB809\uD1A0\uB9AC \uC815\uB9AC \uC911...");
91
+ try {
92
+ const solvingDirConfig = getSolvingDir();
93
+ if (solvingDirConfig && solvingDirConfig !== "." && solvingDirConfig !== "") {
94
+ let currentParentDir = dirname(solvingDir);
95
+ const solvingBaseDir = join(projectRoot, solvingDirConfig);
96
+ while (currentParentDir !== solvingBaseDir && currentParentDir !== projectRoot) {
97
+ try {
98
+ const entries = await readdir(currentParentDir);
99
+ if (entries.length === 0) {
100
+ await rmdir(currentParentDir);
101
+ currentParentDir = dirname(currentParentDir);
102
+ } else {
103
+ break;
104
+ }
105
+ } catch {
106
+ break;
107
+ }
108
+ }
109
+ }
110
+ } catch {
111
+ }
74
112
  setMessage("Git \uCEE4\uBC0B\uC744 \uC2E4\uD589\uD558\uB294 \uC911...");
75
113
  try {
76
114
  await execa("git", ["add", problemDir], { cwd: projectRoot });
@@ -3,18 +3,18 @@ import {
3
3
  source_default
4
4
  } from "../chunk-ASMT3CRD.js";
5
5
  import {
6
- calculateTierProgress,
7
- getNextTierMinRating,
8
- getTierColor,
9
- getTierName,
10
6
  getUserStats
11
- } from "../chunk-NH36IFWR.js";
7
+ } from "../chunk-A6STXEAE.js";
12
8
  import {
13
9
  Command,
14
10
  CommandBuilder,
15
11
  CommandDef,
16
- getSolvedAcHandle
17
- } from "../chunk-RVD22OUQ.js";
12
+ calculateTierProgress,
13
+ getNextTierMinRating,
14
+ getSolvedAcHandle,
15
+ getTierColor,
16
+ getTierName
17
+ } from "../chunk-TNGUME4H.js";
18
18
  import {
19
19
  __decorateClass
20
20
  } from "../chunk-7MQMPJ3X.js";
@@ -11,7 +11,7 @@ import {
11
11
  getProblemId,
12
12
  resolveLanguage,
13
13
  resolveProblemContext
14
- } from "../chunk-RVD22OUQ.js";
14
+ } from "../chunk-TNGUME4H.js";
15
15
  import {
16
16
  __decorateClass,
17
17
  getSupportedLanguagesString
@@ -9,7 +9,7 @@ import {
9
9
  getProblemId,
10
10
  resolveLanguage,
11
11
  resolveProblemContext
12
- } from "../chunk-RVD22OUQ.js";
12
+ } from "../chunk-TNGUME4H.js";
13
13
  import {
14
14
  __decorateClass,
15
15
  getSupportedLanguagesString
package/dist/index.js CHANGED
@@ -9422,25 +9422,21 @@ function generateHelpText(commands2) {
9422
9422
 
9423
9423
  \uBA85\uB839\uC5B4:
9424
9424
  ${commandList}
9425
- help \uC774 \uB3C4\uC6C0\uB9D0 \uD45C\uC2DC
9425
+ help \uB3C4\uC6C0\uB9D0 \uD45C\uC2DC
9426
9426
 
9427
- \uC635\uC158:
9428
- --language, -l \uC5B8\uC5B4 \uC120\uD0DD
9429
- \uC9C0\uC6D0 \uC5B8\uC5B4: ${getSupportedLanguagesString()}
9430
- - fetch: \uAE30\uBCF8\uAC12 python
9431
- - test: solution.* \uD30C\uC77C\uB85C \uC790\uB3D9 \uAC10\uC9C0 (\uC9C0\uC815 \uC2DC \uB36E\uC5B4\uC4F0\uAE30)
9427
+ \uC8FC\uC694 \uC635\uC158:
9428
+ --language, -l \uC5B8\uC5B4 \uC120\uD0DD (${getSupportedLanguagesString()})
9429
+ --watch, -w \uD14C\uC2A4\uD2B8 watch \uBAA8\uB4DC (test \uC804\uC6A9)
9430
+ --help, -h \uBA85\uB839\uC5B4\uBCC4 \uB3C4\uC6C0\uB9D0
9432
9431
 
9433
- --watch, -w \uD14C\uC2A4\uD2B8 watch \uBAA8\uB4DC (test \uBA85\uB839\uC5B4 \uC804\uC6A9)
9434
- - solution.*, input*.txt, output*.txt \uD30C\uC77C \uBCC0\uACBD \uAC10\uC9C0
9435
- - \uBCC0\uACBD \uC2DC \uC790\uB3D9\uC73C\uB85C \uD14C\uC2A4\uD2B8 \uC7AC\uC2E4\uD589
9432
+ \uBE60\uB978 \uC2DC\uC791:
9433
+ $ ps init # \uD504\uB85C\uC81D\uD2B8 \uCD08\uAE30\uD654
9434
+ $ ps fetch 1000 # \uBB38\uC81C \uAC00\uC838\uC624\uAE30
9435
+ $ ps test # \uD14C\uC2A4\uD2B8 \uC2E4\uD589
9436
+ $ ps submit # \uC81C\uCD9C
9436
9437
 
9437
- --help, -h \uBA85\uB839\uC5B4\uBCC4 \uB3C4\uC6C0\uB9D0 \uD45C\uC2DC
9438
-
9439
- \uC608\uC81C:
9440
- $ ps fetch 1000
9441
- $ ps test 1000 --watch
9442
- $ ps help
9443
- $ ps fetch --help
9438
+ \uC790\uC138\uD55C \uB3C4\uC6C0\uB9D0:
9439
+ $ ps <\uBA85\uB839\uC5B4> --help
9444
9440
  `;
9445
9441
  }
9446
9442
  var cli = meow(