@rhseung/ps-cli 1.7.5 → 1.9.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.
@@ -0,0 +1,370 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ runSolution
4
+ } from "./chunk-TTTS4CDS.js";
5
+ import {
6
+ Command,
7
+ CommandBuilder,
8
+ CommandDef,
9
+ __decorateClass,
10
+ defineFlags,
11
+ getProblemTimeLimitMs,
12
+ getSupportedLanguagesString,
13
+ icons,
14
+ resolveLanguage,
15
+ resolveProblemContext
16
+ } from "./chunk-JZK2464U.js";
17
+
18
+ // src/commands/test.tsx
19
+ import { Alert, Spinner } from "@inkjs/ui";
20
+ import { Box as Box2, Text as Text2 } from "ink";
21
+
22
+ // src/components/test-result.tsx
23
+ import { Badge, StatusMessage } from "@inkjs/ui";
24
+ import { Box, Text } from "ink";
25
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
26
+ function truncate(text = "", max = 200) {
27
+ return text.length > max ? `${text.slice(0, max)}...` : text;
28
+ }
29
+ function formatDuration(ms) {
30
+ if (ms < 1e3) return `${ms}ms`;
31
+ return `${(ms / 1e3).toFixed(2)}s`;
32
+ }
33
+ function ResultRow({ result }) {
34
+ const badgeColor = result.status === "pass" ? "green" : result.status === "fail" ? "red" : "yellow";
35
+ const statusText = result.status === "pass" ? "PASS" : result.status === "fail" ? "FAIL" : "ERROR";
36
+ const statusIcon = result.status === "pass" ? icons.success : result.status === "fail" ? icons.error : icons.warning;
37
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
38
+ /* @__PURE__ */ jsxs(Box, { children: [
39
+ /* @__PURE__ */ jsxs(Badge, { color: badgeColor, children: [
40
+ statusIcon,
41
+ " ",
42
+ statusText
43
+ ] }),
44
+ /* @__PURE__ */ jsx(Text, { children: " " }),
45
+ /* @__PURE__ */ jsxs(Text, { children: [
46
+ "\uCF00\uC774\uC2A4 ",
47
+ result.caseId
48
+ ] }),
49
+ result.durationMs !== void 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
50
+ /* @__PURE__ */ jsx(Text, { children: " " }),
51
+ /* @__PURE__ */ jsxs(Text, { color: "cyan", children: [
52
+ "(",
53
+ formatDuration(result.durationMs),
54
+ ")"
55
+ ] })
56
+ ] })
57
+ ] }),
58
+ result.status === "fail" && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginLeft: 3, marginTop: 1, children: [
59
+ /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
60
+ /* @__PURE__ */ jsx(Text, { color: "gray", children: "\uAE30\uB300\uAC12:" }),
61
+ /* @__PURE__ */ jsx(Text, { children: truncate(result.expected ?? "") })
62
+ ] }),
63
+ /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
64
+ /* @__PURE__ */ jsx(Text, { color: "gray", children: "\uC2E4\uC81C\uAC12:" }),
65
+ /* @__PURE__ */ jsx(Text, { children: truncate(result.actual ?? "") })
66
+ ] })
67
+ ] }),
68
+ result.status === "error" && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginLeft: 3, marginTop: 1, children: [
69
+ /* @__PURE__ */ jsx(Text, { color: "yellow", children: result.error ?? "\uC54C \uC218 \uC5C6\uB294 \uC624\uB958" }),
70
+ result.stderr && /* @__PURE__ */ jsx(Text, { color: "gray", dimColor: true, children: truncate(result.stderr) })
71
+ ] })
72
+ ] });
73
+ }
74
+ function TestResultView({ summary, results }) {
75
+ const allPassed = summary.failed === 0 && summary.errored === 0;
76
+ const summaryVariant = allPassed ? "success" : "error";
77
+ const summaryText = `\uCD1D ${summary.total}\uAC1C | Pass ${summary.passed}${summary.failed > 0 ? ` | Fail ${summary.failed}` : ""}${summary.errored > 0 ? ` | Error ${summary.errored}` : ""}`;
78
+ return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
79
+ /* @__PURE__ */ jsxs(StatusMessage, { variant: summaryVariant, children: [
80
+ "\uD14C\uC2A4\uD2B8 \uACB0\uACFC: ",
81
+ summaryText
82
+ ] }),
83
+ /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginTop: 1, children: results.map((r) => /* @__PURE__ */ jsx(ResultRow, { result: r }, r.caseId)) })
84
+ ] });
85
+ }
86
+
87
+ // src/hooks/use-test-runner.ts
88
+ import { join as join2 } from "path";
89
+ import chokidar from "chokidar";
90
+ import { useEffect, useState, useCallback } from "react";
91
+
92
+ // src/services/test-runner.ts
93
+ import { readdir, readFile } from "fs/promises";
94
+ import { join } from "path";
95
+
96
+ // src/services/diff-checker.ts
97
+ function normalizeOutput(output) {
98
+ return output.replace(/\r\n/g, "\n").split("\n").map((line) => line.trimEnd()).join("\n").trimEnd();
99
+ }
100
+ function compareOutput(expected, actual) {
101
+ const expectedNorm = normalizeOutput(expected);
102
+ const actualNorm = normalizeOutput(actual);
103
+ return {
104
+ pass: expectedNorm === actualNorm,
105
+ expected: expectedNorm,
106
+ actual: actualNorm
107
+ };
108
+ }
109
+
110
+ // src/services/test-runner.ts
111
+ function buildSummary(results) {
112
+ const summary = {
113
+ total: results.length,
114
+ passed: 0,
115
+ failed: 0,
116
+ errored: 0
117
+ };
118
+ for (const r of results) {
119
+ if (r.status === "pass") summary.passed += 1;
120
+ else if (r.status === "fail") summary.failed += 1;
121
+ else summary.errored += 1;
122
+ }
123
+ return summary;
124
+ }
125
+ async function runAllTests({
126
+ problemDir,
127
+ language,
128
+ timeoutMs
129
+ }) {
130
+ const testcasesDir = join(problemDir, "testcases");
131
+ let caseDirs = [];
132
+ try {
133
+ const entries = await readdir(testcasesDir);
134
+ caseDirs = entries.filter((entry) => /^\d+$/.test(entry)).sort((a, b) => Number(a) - Number(b)).map((entry) => join(testcasesDir, entry));
135
+ } catch {
136
+ return { results: [], summary: buildSummary([]) };
137
+ }
138
+ const results = [];
139
+ let effectiveTimeout = timeoutMs;
140
+ if (effectiveTimeout == null) {
141
+ effectiveTimeout = await getProblemTimeLimitMs(problemDir);
142
+ }
143
+ if (effectiveTimeout == null) {
144
+ effectiveTimeout = 5e3;
145
+ }
146
+ for (const caseDir of caseDirs) {
147
+ const caseId = Number(join(caseDir).split("/").pop() || "0");
148
+ const inputPath = join(caseDir, "input.txt");
149
+ const outputPath = join(caseDir, "output.txt");
150
+ let expected;
151
+ try {
152
+ expected = await readFile(outputPath, "utf-8");
153
+ } catch {
154
+ results.push({
155
+ caseId,
156
+ inputPath,
157
+ status: "error",
158
+ error: "\uAE30\uB300 \uCD9C\uB825(output.txt)\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."
159
+ });
160
+ continue;
161
+ }
162
+ const runResult = await runSolution({
163
+ problemDir,
164
+ language,
165
+ inputPath,
166
+ timeoutMs: effectiveTimeout
167
+ });
168
+ if (runResult.exitCode !== 0 || runResult.timedOut) {
169
+ results.push({
170
+ caseId,
171
+ inputPath,
172
+ expected,
173
+ actual: runResult.stdout,
174
+ error: runResult.timedOut ? `\uC2DC\uAC04 \uCD08\uACFC (timeout ${effectiveTimeout}ms)` : runResult.stderr || "\uC2E4\uD589 \uC5D0\uB7EC",
175
+ status: "error",
176
+ durationMs: runResult.durationMs
177
+ });
178
+ continue;
179
+ }
180
+ const diff = compareOutput(expected ?? "", runResult.stdout);
181
+ results.push({
182
+ caseId,
183
+ inputPath,
184
+ expected: diff.expected,
185
+ actual: diff.actual,
186
+ status: diff.pass ? "pass" : "fail",
187
+ durationMs: runResult.durationMs
188
+ });
189
+ }
190
+ return { results, summary: buildSummary(results) };
191
+ }
192
+
193
+ // src/hooks/use-test-runner.ts
194
+ function useTestRunner({
195
+ problemDir,
196
+ language,
197
+ watch,
198
+ timeoutMs,
199
+ onComplete
200
+ }) {
201
+ const [status, setStatus] = useState("loading");
202
+ const [results, setResults] = useState([]);
203
+ const [summary, setSummary] = useState({
204
+ total: 0,
205
+ passed: 0,
206
+ failed: 0,
207
+ errored: 0
208
+ });
209
+ const [error, setError] = useState(null);
210
+ const runTests = useCallback(
211
+ (isWatchTrigger = false) => {
212
+ if (isWatchTrigger && watch) {
213
+ console.clear();
214
+ }
215
+ setStatus("loading");
216
+ void runAllTests({
217
+ problemDir,
218
+ language,
219
+ timeoutMs
220
+ }).then(({ results: results2, summary: summary2 }) => {
221
+ setResults(results2);
222
+ setSummary(summary2);
223
+ setStatus("ready");
224
+ }).catch((err) => {
225
+ setError(err instanceof Error ? err.message : String(err));
226
+ setStatus("error");
227
+ });
228
+ },
229
+ [problemDir, language, timeoutMs, watch]
230
+ );
231
+ useEffect(() => {
232
+ const timer = setTimeout(() => {
233
+ void runTests();
234
+ }, 0);
235
+ return () => clearTimeout(timer);
236
+ }, [runTests]);
237
+ useEffect(() => {
238
+ if (!watch) {
239
+ return void 0;
240
+ }
241
+ const watcher = chokidar.watch(
242
+ [
243
+ join2(problemDir, "solution.*"),
244
+ join2(problemDir, "testcases", "**", "*.txt")
245
+ ],
246
+ {
247
+ ignoreInitial: true
248
+ }
249
+ );
250
+ watcher.on("change", () => {
251
+ runTests(true);
252
+ });
253
+ return () => {
254
+ void watcher.close();
255
+ };
256
+ }, [problemDir, watch, runTests]);
257
+ useEffect(() => {
258
+ if (!watch && status === "ready") {
259
+ const timer = setTimeout(() => onComplete(), 200);
260
+ return () => clearTimeout(timer);
261
+ }
262
+ return void 0;
263
+ }, [status, watch, onComplete]);
264
+ return {
265
+ status,
266
+ results,
267
+ summary,
268
+ error
269
+ };
270
+ }
271
+
272
+ // src/commands/test.tsx
273
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
274
+ var testFlagsSchema = {
275
+ language: {
276
+ type: "string",
277
+ shortFlag: "l",
278
+ description: `\uC5B8\uC5B4 \uC120\uD0DD (\uC9C0\uC815 \uC2DC \uC790\uB3D9 \uAC10\uC9C0 \uBB34\uC2DC)
279
+ \uC9C0\uC6D0 \uC5B8\uC5B4: ${getSupportedLanguagesString()}`
280
+ },
281
+ watch: {
282
+ type: "boolean",
283
+ shortFlag: "w",
284
+ description: `watch \uBAA8\uB4DC (\uD30C\uC77C \uBCC0\uACBD \uC2DC \uC790\uB3D9 \uC7AC\uD14C\uC2A4\uD2B8)
285
+ solution.*, testcases/**/*.txt \uD30C\uC77C \uBCC0\uACBD \uAC10\uC9C0`
286
+ }
287
+ };
288
+ function TestView({
289
+ problemDir,
290
+ language,
291
+ watch,
292
+ timeoutMs,
293
+ onComplete
294
+ }) {
295
+ const { status, results, summary, error } = useTestRunner({
296
+ problemDir,
297
+ language,
298
+ watch,
299
+ timeoutMs,
300
+ onComplete
301
+ });
302
+ if (status === "loading") {
303
+ return /* @__PURE__ */ jsx2(Box2, { flexDirection: "column", children: /* @__PURE__ */ jsx2(Spinner, { label: "\uD14C\uC2A4\uD2B8 \uC2E4\uD589 \uC911..." }) });
304
+ }
305
+ if (status === "error") {
306
+ return /* @__PURE__ */ jsx2(Box2, { flexDirection: "column", children: /* @__PURE__ */ jsxs2(Alert, { variant: "error", children: [
307
+ "\uD14C\uC2A4\uD2B8 \uC2E4\uD589 \uC2E4\uD328",
308
+ error ? `: ${error}` : ""
309
+ ] }) });
310
+ }
311
+ return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", children: [
312
+ /* @__PURE__ */ jsxs2(Box2, { marginBottom: 1, children: [
313
+ /* @__PURE__ */ jsx2(Text2, { color: "cyan", bold: true, children: "\uD14C\uC2A4\uD2B8 \uC2E4\uD589 \uC911" }),
314
+ /* @__PURE__ */ jsx2(Text2, { children: " " }),
315
+ /* @__PURE__ */ jsxs2(Text2, { color: "gray", children: [
316
+ problemDir,
317
+ " ",
318
+ icons.solving,
319
+ " ",
320
+ language,
321
+ watch && ` ${icons.solving} watch`
322
+ ] })
323
+ ] }),
324
+ /* @__PURE__ */ jsx2(TestResultView, { results, summary })
325
+ ] });
326
+ }
327
+ var TestCommand = class extends Command {
328
+ async execute(args, flags) {
329
+ const context = await resolveProblemContext(args);
330
+ const language = await resolveLanguage(
331
+ context.archiveDir,
332
+ flags.language
333
+ );
334
+ await this.renderView(TestView, {
335
+ problemDir: context.archiveDir,
336
+ language,
337
+ watch: Boolean(flags.watch),
338
+ timeoutMs: flags.timeoutMs
339
+ });
340
+ }
341
+ };
342
+ TestCommand = __decorateClass([
343
+ CommandDef({
344
+ name: "test",
345
+ description: `\uC608\uC81C \uC785\uCD9C\uB825 \uAE30\uBC18\uC73C\uB85C \uB85C\uCEEC \uD14C\uC2A4\uD2B8\uB97C \uC2E4\uD589\uD569\uB2C8\uB2E4.
346
+ - \uD604\uC7AC \uB514\uB809\uD1A0\uB9AC \uB610\uB294 \uC9C0\uC815\uD55C \uBB38\uC81C \uBC88\uD638\uC758 \uD14C\uC2A4\uD2B8 \uC2E4\uD589
347
+ - solution.* \uD30C\uC77C\uC744 \uC790\uB3D9\uC73C\uB85C \uCC3E\uC544 \uC5B8\uC5B4 \uAC10\uC9C0
348
+ - testcases/{\uBC88\uD638}/input.txt\uC640 testcases/{\uBC88\uD638}/output.txt \uD30C\uC77C\uC744 \uAE30\uBC18\uC73C\uB85C \uD14C\uC2A4\uD2B8
349
+ - \uBB38\uC81C\uC758 \uC2DC\uAC04 \uC81C\uD55C\uC744 \uC790\uB3D9\uC73C\uB85C \uC801\uC6A9
350
+ - --watch \uC635\uC158\uC73C\uB85C \uD30C\uC77C \uBCC0\uACBD \uC2DC \uC790\uB3D9 \uC7AC\uD14C\uC2A4\uD2B8
351
+ - \uAE30\uBCF8 \uC5B8\uC5B4 \uB4F1\uC740 ps config\uC5D0\uC11C \uC124\uC815 \uAC00\uB2A5\uD569\uB2C8\uB2E4.`,
352
+ flags: defineFlags(testFlagsSchema),
353
+ autoDetectProblemId: true,
354
+ autoDetectLanguage: true,
355
+ examples: [
356
+ "test # \uD604\uC7AC \uB514\uB809\uD1A0\uB9AC\uC5D0\uC11C \uD14C\uC2A4\uD2B8",
357
+ "test 1000 # 1000\uBC88 \uBB38\uC81C \uD14C\uC2A4\uD2B8",
358
+ "test --watch # watch \uBAA8\uB4DC\uB85C \uD14C\uC2A4\uD2B8",
359
+ "test 1000 --watch # 1000\uBC88 \uBB38\uC81C\uB97C watch \uBAA8\uB4DC\uB85C \uD14C\uC2A4\uD2B8",
360
+ "test --language python # Python\uC73C\uB85C \uD14C\uC2A4\uD2B8"
361
+ ]
362
+ })
363
+ ], TestCommand);
364
+ var test_default = CommandBuilder.fromClass(TestCommand);
365
+
366
+ export {
367
+ TestView,
368
+ TestCommand,
369
+ test_default
370
+ };
@@ -1,201 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
- Command,
4
- CommandBuilder,
5
- CommandDef,
6
- findProjectRoot,
7
- getArchiveDirPath,
8
- getSolvingDir,
9
- getSolvingDirPath,
10
- resolveProblemContext
11
- } from "../chunk-F4LZ6ENP.js";
12
- import {
13
- __decorateClass
14
- } from "../chunk-7MQMPJ3X.js";
15
-
16
- // src/commands/archive.tsx
17
- import { StatusMessage, Alert } from "@inkjs/ui";
18
- import { Spinner } from "@inkjs/ui";
19
- import { Box } from "ink";
20
-
21
- // src/hooks/use-archive.ts
22
- import { access, readFile, rename, mkdir, readdir, rmdir } from "fs/promises";
23
- import { join, dirname } from "path";
24
- import { execa } from "execa";
25
- import { useEffect, useState } from "react";
26
- function useArchive({
27
- problemId,
28
- onComplete
29
- }) {
30
- const [status, setStatus] = useState(
31
- "loading"
32
- );
33
- const [message, setMessage] = useState("\uBB38\uC81C\uB97C \uC544\uCE74\uC774\uBE0C\uD558\uB294 \uC911...");
34
- const [error, setError] = useState(null);
35
- useEffect(() => {
36
- async function archive() {
37
- try {
38
- const projectRoot = findProjectRoot();
39
- if (!projectRoot) {
40
- throw new Error("\uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.");
41
- }
42
- const solvingDir = getSolvingDirPath(problemId, projectRoot);
43
- setMessage("solving \uB514\uB809\uD1A0\uB9AC\uC5D0\uC11C \uBB38\uC81C\uB97C \uD655\uC778\uD558\uB294 \uC911...");
44
- try {
45
- await access(solvingDir);
46
- } catch {
47
- throw new Error(
48
- `solving \uB514\uB809\uD1A0\uB9AC\uC5D0 \uBB38\uC81C ${problemId}\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.`
49
- );
50
- }
51
- setMessage("\uBB38\uC81C \uC815\uBCF4\uB97C \uC77D\uB294 \uC911...");
52
- const metaPath = join(solvingDir, "meta.json");
53
- let problemTitle = `\uBB38\uC81C ${problemId}`;
54
- let problem;
55
- try {
56
- const metaContent = await readFile(metaPath, "utf-8");
57
- const meta = JSON.parse(metaContent);
58
- if (meta.title) {
59
- problemTitle = meta.title;
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
- }
72
- } catch {
73
- }
74
- const archiveDir = getArchiveDirPath(problemId, projectRoot, problem);
75
- try {
76
- await access(archiveDir);
77
- throw new Error(
78
- `archive \uB514\uB809\uD1A0\uB9AC\uC5D0 \uC774\uBBF8 \uBB38\uC81C ${problemId}\uAC00 \uC874\uC7AC\uD569\uB2C8\uB2E4.`
79
- );
80
- } catch (err) {
81
- if (err instanceof Error && err.message.includes("\uC774\uBBF8")) {
82
- throw err;
83
- }
84
- }
85
- const archiveDirParent = dirname(archiveDir);
86
- setMessage("\uC544\uCE74\uC774\uBE0C \uB514\uB809\uD1A0\uB9AC\uB97C \uC900\uBE44\uD558\uB294 \uC911...");
87
- await mkdir(archiveDirParent, { recursive: true });
88
- setMessage("\uBB38\uC81C\uB97C archive \uB514\uB809\uD1A0\uB9AC\uB85C \uC774\uB3D9\uD558\uB294 \uC911...");
89
- await rename(solvingDir, archiveDir);
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
- }
112
- setMessage("Git \uCEE4\uBC0B\uC744 \uC2E4\uD589\uD558\uB294 \uC911...");
113
- try {
114
- await execa("git", ["add", archiveDir], { cwd: projectRoot });
115
- const commitMessage = `solve: ${problemId} - ${problemTitle}`;
116
- await execa("git", ["commit", "-m", commitMessage], {
117
- cwd: projectRoot
118
- });
119
- } catch (gitError) {
120
- console.warn(
121
- "Git \uCEE4\uBC0B \uC2E4\uD328:",
122
- gitError instanceof Error ? gitError.message : String(gitError)
123
- );
124
- }
125
- setStatus("success");
126
- setMessage(`\uBB38\uC81C ${problemId}\uB97C \uC544\uCE74\uC774\uBE0C\uD588\uC2B5\uB2C8\uB2E4: ${archiveDir}`);
127
- setTimeout(() => {
128
- onComplete?.();
129
- }, 2e3);
130
- } catch (err) {
131
- setStatus("error");
132
- setError(err instanceof Error ? err.message : String(err));
133
- setTimeout(() => {
134
- onComplete?.();
135
- }, 2e3);
136
- }
137
- }
138
- void archive();
139
- }, [problemId, onComplete]);
140
- return {
141
- status,
142
- message,
143
- error
144
- };
145
- }
146
-
147
- // src/commands/archive.tsx
148
- import { jsx, jsxs } from "react/jsx-runtime";
149
- function ArchiveView({ problemId, onComplete }) {
150
- const { status, message, error } = useArchive({
151
- problemId,
152
- onComplete
153
- });
154
- if (status === "loading") {
155
- return /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: /* @__PURE__ */ jsx(Spinner, { label: message }) });
156
- }
157
- if (status === "error") {
158
- return /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: /* @__PURE__ */ jsxs(Alert, { variant: "error", children: [
159
- "\uC624\uB958 \uBC1C\uC0DD: ",
160
- error
161
- ] }) });
162
- }
163
- return /* @__PURE__ */ jsx(Box, { flexDirection: "column", width: "100%", children: /* @__PURE__ */ jsx(StatusMessage, { variant: "success", children: message }) });
164
- }
165
- var ArchiveCommand = class extends Command {
166
- async execute(args, _) {
167
- const context = await resolveProblemContext(args, { requireId: false });
168
- if (context.problemId === null) {
169
- console.error("\uC624\uB958: \uBB38\uC81C \uBC88\uD638\uB97C \uC785\uB825\uD574\uC8FC\uC138\uC694.");
170
- console.error(`\uC0AC\uC6A9\uBC95: ps archive <\uBB38\uC81C\uBC88\uD638>`);
171
- console.error(`\uB3C4\uC6C0\uB9D0: ps archive --help`);
172
- console.error(
173
- `\uD78C\uD2B8: solving/{\uBB38\uC81C\uBC88\uD638} \uB514\uB809\uD1A0\uB9AC\uC5D0\uC11C \uC2E4\uD589\uD558\uBA74 \uC790\uB3D9\uC73C\uB85C \uBB38\uC81C \uBC88\uD638\uB97C \uCD94\uB860\uD569\uB2C8\uB2E4.`
174
- );
175
- process.exit(1);
176
- return;
177
- }
178
- await this.renderView(ArchiveView, {
179
- problemId: context.problemId
180
- });
181
- }
182
- };
183
- ArchiveCommand = __decorateClass([
184
- CommandDef({
185
- name: "archive",
186
- description: `\uBB38\uC81C\uB97C \uC544\uCE74\uC774\uBE0C\uD558\uACE0 Git \uCEE4\uBC0B\uC744 \uC0DD\uC131\uD569\uB2C8\uB2E4.
187
- - solving \uB514\uB809\uD1A0\uB9AC\uC5D0\uC11C \uBB38\uC81C\uB97C \uCC3E\uC544 archive \uB514\uB809\uD1A0\uB9AC\uB85C \uC774\uB3D9
188
- - Git add \uBC0F commit \uC2E4\uD589 (\uCEE4\uBC0B \uBA54\uC2DC\uC9C0: "solve: {\uBB38\uC81C\uBC88\uD638} - {\uBB38\uC81C\uC774\uB984}")`,
189
- autoDetectProblemId: true,
190
- requireProblemId: false,
191
- examples: [
192
- "archive 1000",
193
- "archive # \uD604\uC7AC \uB514\uB809\uD1A0\uB9AC\uC5D0\uC11C \uBB38\uC81C \uBC88\uD638 \uC790\uB3D9 \uAC10\uC9C0"
194
- ]
195
- })
196
- ], ArchiveCommand);
197
- var archive_default = CommandBuilder.fromClass(ArchiveCommand);
3
+ ArchiveCommand,
4
+ ArchiveView,
5
+ archive_default
6
+ } from "../chunk-D5PTJ4WQ.js";
7
+ import "../chunk-JZK2464U.js";
198
8
  export {
199
9
  ArchiveCommand,
10
+ ArchiveView,
200
11
  archive_default as default
201
12
  };