@rhseung/ps-cli 1.9.8 → 1.10.2

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.
@@ -161,10 +161,10 @@ var require_code = __commonJS({
161
161
  function interpolate(x) {
162
162
  return typeof x == "number" || typeof x == "boolean" || x === null ? x : safeStringify(Array.isArray(x) ? x.join(",") : x);
163
163
  }
164
- function stringify(x) {
164
+ function stringify2(x) {
165
165
  return new _Code(safeStringify(x));
166
166
  }
167
- exports.stringify = stringify;
167
+ exports.stringify = stringify2;
168
168
  function safeStringify(x) {
169
169
  return JSON.stringify(x).replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
170
170
  }
@@ -3579,24 +3579,24 @@ var require_fast_uri = __commonJS({
3579
3579
  function normalize(uri, options) {
3580
3580
  if (typeof uri === "string") {
3581
3581
  uri = /** @type {T} */
3582
- serialize(parse(uri, options), options);
3582
+ serialize(parse2(uri, options), options);
3583
3583
  } else if (typeof uri === "object") {
3584
3584
  uri = /** @type {T} */
3585
- parse(serialize(uri, options), options);
3585
+ parse2(serialize(uri, options), options);
3586
3586
  }
3587
3587
  return uri;
3588
3588
  }
3589
3589
  function resolve(baseURI, relativeURI, options) {
3590
3590
  const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
3591
- const resolved = resolveComponent(parse(baseURI, schemelessOptions), parse(relativeURI, schemelessOptions), schemelessOptions, true);
3591
+ const resolved = resolveComponent(parse2(baseURI, schemelessOptions), parse2(relativeURI, schemelessOptions), schemelessOptions, true);
3592
3592
  schemelessOptions.skipEscape = true;
3593
3593
  return serialize(resolved, schemelessOptions);
3594
3594
  }
3595
3595
  function resolveComponent(base, relative, options, skipNormalization) {
3596
3596
  const target = {};
3597
3597
  if (!skipNormalization) {
3598
- base = parse(serialize(base, options), options);
3599
- relative = parse(serialize(relative, options), options);
3598
+ base = parse2(serialize(base, options), options);
3599
+ relative = parse2(serialize(relative, options), options);
3600
3600
  }
3601
3601
  options = options || {};
3602
3602
  if (!options.tolerant && relative.scheme) {
@@ -3648,13 +3648,13 @@ var require_fast_uri = __commonJS({
3648
3648
  function equal(uriA, uriB, options) {
3649
3649
  if (typeof uriA === "string") {
3650
3650
  uriA = unescape(uriA);
3651
- uriA = serialize(normalizeComponentEncoding(parse(uriA, options), true), { ...options, skipEscape: true });
3651
+ uriA = serialize(normalizeComponentEncoding(parse2(uriA, options), true), { ...options, skipEscape: true });
3652
3652
  } else if (typeof uriA === "object") {
3653
3653
  uriA = serialize(normalizeComponentEncoding(uriA, true), { ...options, skipEscape: true });
3654
3654
  }
3655
3655
  if (typeof uriB === "string") {
3656
3656
  uriB = unescape(uriB);
3657
- uriB = serialize(normalizeComponentEncoding(parse(uriB, options), true), { ...options, skipEscape: true });
3657
+ uriB = serialize(normalizeComponentEncoding(parse2(uriB, options), true), { ...options, skipEscape: true });
3658
3658
  } else if (typeof uriB === "object") {
3659
3659
  uriB = serialize(normalizeComponentEncoding(uriB, true), { ...options, skipEscape: true });
3660
3660
  }
@@ -3723,7 +3723,7 @@ var require_fast_uri = __commonJS({
3723
3723
  return uriTokens.join("");
3724
3724
  }
3725
3725
  var URI_PARSE = /^(?:([^#/:?]+):)?(?:\/\/((?:([^#/?@]*)@)?(\[[^#/?\]]+\]|[^#/:?]*)(?::(\d*))?))?([^#?]*)(?:\?([^#]*))?(?:#((?:.|[\n\r])*))?/u;
3726
- function parse(uri, opts) {
3726
+ function parse2(uri, opts) {
3727
3727
  const options = Object.assign({}, opts);
3728
3728
  const parsed = {
3729
3729
  scheme: void 0,
@@ -3817,7 +3817,7 @@ var require_fast_uri = __commonJS({
3817
3817
  resolveComponent,
3818
3818
  equal,
3819
3819
  serialize,
3820
- parse
3820
+ parse: parse2
3821
3821
  };
3822
3822
  module.exports = fastUri;
3823
3823
  module.exports.default = fastUri;
@@ -7215,7 +7215,7 @@ var require_parse = __commonJS({
7215
7215
  "node_modules/conf/node_modules/semver/functions/parse.js"(exports, module) {
7216
7216
  "use strict";
7217
7217
  var SemVer = require_semver();
7218
- var parse = (version, options, throwErrors = false) => {
7218
+ var parse2 = (version, options, throwErrors = false) => {
7219
7219
  if (version instanceof SemVer) {
7220
7220
  return version;
7221
7221
  }
@@ -7228,7 +7228,7 @@ var require_parse = __commonJS({
7228
7228
  throw er;
7229
7229
  }
7230
7230
  };
7231
- module.exports = parse;
7231
+ module.exports = parse2;
7232
7232
  }
7233
7233
  });
7234
7234
 
@@ -7236,9 +7236,9 @@ var require_parse = __commonJS({
7236
7236
  var require_valid = __commonJS({
7237
7237
  "node_modules/conf/node_modules/semver/functions/valid.js"(exports, module) {
7238
7238
  "use strict";
7239
- var parse = require_parse();
7239
+ var parse2 = require_parse();
7240
7240
  var valid = (version, options) => {
7241
- const v = parse(version, options);
7241
+ const v = parse2(version, options);
7242
7242
  return v ? v.version : null;
7243
7243
  };
7244
7244
  module.exports = valid;
@@ -7249,9 +7249,9 @@ var require_valid = __commonJS({
7249
7249
  var require_clean = __commonJS({
7250
7250
  "node_modules/conf/node_modules/semver/functions/clean.js"(exports, module) {
7251
7251
  "use strict";
7252
- var parse = require_parse();
7252
+ var parse2 = require_parse();
7253
7253
  var clean = (version, options) => {
7254
- const s = parse(version.trim().replace(/^[=v]+/, ""), options);
7254
+ const s = parse2(version.trim().replace(/^[=v]+/, ""), options);
7255
7255
  return s ? s.version : null;
7256
7256
  };
7257
7257
  module.exports = clean;
@@ -7286,10 +7286,10 @@ var require_inc = __commonJS({
7286
7286
  var require_diff = __commonJS({
7287
7287
  "node_modules/conf/node_modules/semver/functions/diff.js"(exports, module) {
7288
7288
  "use strict";
7289
- var parse = require_parse();
7289
+ var parse2 = require_parse();
7290
7290
  var diff = (version1, version2) => {
7291
- const v1 = parse(version1, null, true);
7292
- const v2 = parse(version2, null, true);
7291
+ const v1 = parse2(version1, null, true);
7292
+ const v2 = parse2(version2, null, true);
7293
7293
  const comparison = v1.compare(v2);
7294
7294
  if (comparison === 0) {
7295
7295
  return null;
@@ -7360,9 +7360,9 @@ var require_patch = __commonJS({
7360
7360
  var require_prerelease = __commonJS({
7361
7361
  "node_modules/conf/node_modules/semver/functions/prerelease.js"(exports, module) {
7362
7362
  "use strict";
7363
- var parse = require_parse();
7363
+ var parse2 = require_parse();
7364
7364
  var prerelease = (version, options) => {
7365
- const parsed = parse(version, options);
7365
+ const parsed = parse2(version, options);
7366
7366
  return parsed && parsed.prerelease.length ? parsed.prerelease : null;
7367
7367
  };
7368
7368
  module.exports = prerelease;
@@ -7548,7 +7548,7 @@ var require_coerce = __commonJS({
7548
7548
  "node_modules/conf/node_modules/semver/functions/coerce.js"(exports, module) {
7549
7549
  "use strict";
7550
7550
  var SemVer = require_semver();
7551
- var parse = require_parse();
7551
+ var parse2 = require_parse();
7552
7552
  var { safeRe: re, t } = require_re();
7553
7553
  var coerce = (version, options) => {
7554
7554
  if (version instanceof SemVer) {
@@ -7583,7 +7583,7 @@ var require_coerce = __commonJS({
7583
7583
  const patch = match[4] || "0";
7584
7584
  const prerelease = options.includePrerelease && match[5] ? `-${match[5]}` : "";
7585
7585
  const build = options.includePrerelease && match[6] ? `+${match[6]}` : "";
7586
- return parse(`${major}.${minor}.${patch}${prerelease}${build}`, options);
7586
+ return parse2(`${major}.${minor}.${patch}${prerelease}${build}`, options);
7587
7587
  };
7588
7588
  module.exports = coerce;
7589
7589
  }
@@ -8600,7 +8600,7 @@ var require_semver2 = __commonJS({
8600
8600
  var constants = require_constants();
8601
8601
  var SemVer = require_semver();
8602
8602
  var identifiers = require_identifiers();
8603
- var parse = require_parse();
8603
+ var parse2 = require_parse();
8604
8604
  var valid = require_valid();
8605
8605
  var clean = require_clean();
8606
8606
  var inc = require_inc();
@@ -8638,7 +8638,7 @@ var require_semver2 = __commonJS({
8638
8638
  var simplifyRange = require_simplify();
8639
8639
  var subset = require_subset();
8640
8640
  module.exports = {
8641
- parse,
8641
+ parse: parse2,
8642
8642
  valid,
8643
8643
  clean,
8644
8644
  inc,
@@ -8688,7 +8688,13 @@ var require_semver2 = __commonJS({
8688
8688
  });
8689
8689
 
8690
8690
  // src/core/config.ts
8691
- import { readFileSync, existsSync } from "fs";
8691
+ import {
8692
+ readFileSync,
8693
+ existsSync,
8694
+ mkdirSync,
8695
+ writeFileSync as writeFileSync2,
8696
+ unlinkSync
8697
+ } from "fs";
8692
8698
  import { join, dirname } from "path";
8693
8699
 
8694
8700
  // node_modules/conf/dist/source/index.js
@@ -9911,28 +9917,37 @@ var Conf = class {
9911
9917
  };
9912
9918
 
9913
9919
  // src/core/config.ts
9920
+ import { parse, stringify } from "yaml";
9914
9921
  var getConfigMetadata = () => [
9915
9922
  {
9916
- key: "default-language",
9917
- property: "defaultLanguage",
9923
+ key: "general.default-language",
9924
+ path: "general.default_language",
9918
9925
  label: "\uAE30\uBCF8 \uC5B8\uC5B4",
9919
9926
  description: `\uAE30\uBCF8\uC73C\uB85C \uC0AC\uC6A9\uD560 \uD504\uB85C\uADF8\uB798\uBC0D \uC5B8\uC5B4\uC785\uB2C8\uB2E4.`,
9920
- placeholder: "\uC5B8\uC5B4 \uC785\uB825 (python, javascript, typescript, cpp)",
9927
+ placeholder: "\uC5B8\uC5B4 \uC785\uB825 (python, cpp \uB4F1)",
9921
9928
  type: "select",
9922
- suggestions: ["python", "javascript", "typescript", "cpp"]
9929
+ suggestions: ["python", "cpp"]
9923
9930
  },
9924
9931
  {
9925
- key: "editor",
9926
- property: "editor",
9927
- label: "\uC5D0\uB514\uD130",
9932
+ key: "general.solved-ac-handle",
9933
+ path: "general.solved_ac_handle",
9934
+ label: "Solved.ac \uD578\uB4E4",
9935
+ description: "\uC0AC\uC6A9\uC790\uC758 Solved.ac \uD578\uB4E4\uC785\uB2C8\uB2E4 (\uD1B5\uACC4 \uC870\uD68C\uC6A9).",
9936
+ placeholder: "\uD578\uB4E4 \uC785\uB825",
9937
+ type: "string"
9938
+ },
9939
+ {
9940
+ key: "editor.command",
9941
+ path: "editor.command",
9942
+ label: "\uC5D0\uB514\uD130 \uBA85\uB839\uC5B4",
9928
9943
  description: "\uBB38\uC81C\uB97C \uAC00\uC838\uC628 \uD6C4 \uC790\uB3D9\uC73C\uB85C \uC5F4 \uC5D0\uB514\uD130 \uBA85\uB839\uC5B4\uC785\uB2C8\uB2E4.",
9929
- placeholder: "\uC5D0\uB514\uD130 \uBA85\uB839\uC5B4 \uC785\uB825 (\uC608: code, cursor, vim, nano)",
9944
+ placeholder: "\uC5D0\uB514\uD130 \uBA85\uB839\uC5B4 \uC785\uB825 (\uC608: code, cursor, vim)",
9930
9945
  type: "string",
9931
9946
  suggestions: ["code", "cursor", "vim", "nano"]
9932
9947
  },
9933
9948
  {
9934
- key: "auto-open-editor",
9935
- property: "autoOpenEditor",
9949
+ key: "editor.auto-open",
9950
+ path: "editor.auto_open",
9936
9951
  label: "\uC790\uB3D9 \uC5D0\uB514\uD130 \uC5F4\uAE30",
9937
9952
  description: "fetch \uBA85\uB839 \uC2E4\uD589 \uD6C4 \uC790\uB3D9\uC73C\uB85C \uC5D0\uB514\uD130\uB97C \uC5F4\uC9C0 \uC5EC\uBD80\uC785\uB2C8\uB2E4.",
9938
9953
  placeholder: "true \uB610\uB294 false \uC785\uB825",
@@ -9940,16 +9955,17 @@ var getConfigMetadata = () => [
9940
9955
  suggestions: ["true", "false"]
9941
9956
  },
9942
9957
  {
9943
- key: "solved-ac-handle",
9944
- property: "solvedAcHandle",
9945
- label: "Solved.ac \uD578\uB4E4",
9946
- description: "\uC0AC\uC6A9\uC790\uC758 Solved.ac \uD578\uB4E4\uC785\uB2C8\uB2E4 (\uD1B5\uACC4 \uC870\uD68C\uC6A9).",
9947
- placeholder: "\uD578\uB4E4 \uC785\uB825",
9948
- type: "string"
9958
+ key: "paths.solving",
9959
+ path: "paths.solving",
9960
+ label: "Solving \uB514\uB809\uD1A0\uB9AC",
9961
+ description: "\uD604\uC7AC \uD480\uACE0 \uC788\uB294 \uBB38\uC81C\uB97C \uB2F4\uC744 \uB514\uB809\uD1A0\uB9AC \uACBD\uB85C\uC785\uB2C8\uB2E4.",
9962
+ placeholder: "\uB514\uB809\uD1A0\uB9AC \uACBD\uB85C \uC785\uB825 (\uAE30\uBCF8\uAC12: solving)",
9963
+ type: "string",
9964
+ suggestions: ["solving", ".", ""]
9949
9965
  },
9950
9966
  {
9951
- key: "archive-dir",
9952
- property: "archiveDir",
9967
+ key: "paths.archive",
9968
+ path: "paths.archive",
9953
9969
  label: "\uC544\uCE74\uC774\uBE0C \uB514\uB809\uD1A0\uB9AC",
9954
9970
  description: "\uD574\uACB0\uD55C \uBB38\uC81C\uB97C \uBCF4\uAD00\uD560 \uB514\uB809\uD1A0\uB9AC \uACBD\uB85C\uC785\uB2C8\uB2E4.",
9955
9971
  placeholder: "\uB514\uB809\uD1A0\uB9AC \uACBD\uB85C \uC785\uB825 (\uAE30\uBCF8\uAC12: problems)",
@@ -9957,17 +9973,8 @@ var getConfigMetadata = () => [
9957
9973
  suggestions: ["problems", ".", ""]
9958
9974
  },
9959
9975
  {
9960
- key: "solving-dir",
9961
- property: "solvingDir",
9962
- label: "Solving \uB514\uB809\uD1A0\uB9AC",
9963
- description: "\uD604\uC7AC \uD480\uACE0 \uC788\uB294 \uBB38\uC81C\uB97C \uB2F4\uC744 \uB514\uB809\uD1A0\uB9AC \uACBD\uB85C\uC785\uB2C8\uB2E4.",
9964
- placeholder: "\uB514\uB809\uD1A0\uB9AC \uACBD\uB85C \uC785\uB825 (\uAE30\uBCF8\uAC12: solving)",
9965
- type: "string",
9966
- suggestions: ["solving", ".", ""]
9967
- },
9968
- {
9969
- key: "archive-strategy",
9970
- property: "archiveStrategy",
9976
+ key: "paths.archive-strategy",
9977
+ path: "paths.archive_strategy",
9971
9978
  label: "\uC544\uCE74\uC774\uBE59 \uC804\uB7B5",
9972
9979
  description: "\uBB38\uC81C\uB97C \uC544\uCE74\uC774\uBE0C\uD560 \uB54C\uC758 \uB514\uB809\uD1A0\uB9AC \uAD6C\uC870 \uC804\uB7B5\uC785\uB2C8\uB2E4.",
9973
9980
  placeholder: "\uC804\uB7B5 \uC785\uB825 (flat, by-range, by-tier, by-tag)",
@@ -9975,8 +9982,8 @@ var getConfigMetadata = () => [
9975
9982
  suggestions: ["flat", "by-range", "by-tier", "by-tag"]
9976
9983
  },
9977
9984
  {
9978
- key: "archive-auto-commit",
9979
- property: "archiveAutoCommit",
9985
+ key: "archive.auto-commit",
9986
+ path: "archive.auto_commit",
9980
9987
  label: "\uC790\uB3D9 Git \uCEE4\uBC0B",
9981
9988
  description: "\uC544\uCE74\uC774\uBE0C \uC2DC \uC790\uB3D9\uC73C\uB85C Git \uCEE4\uBC0B\uC744 \uC218\uD589\uD560\uC9C0 \uC5EC\uBD80\uC785\uB2C8\uB2E4.",
9982
9989
  placeholder: "true \uB610\uB294 false \uC785\uB825",
@@ -9984,16 +9991,16 @@ var getConfigMetadata = () => [
9984
9991
  suggestions: ["true", "false"]
9985
9992
  },
9986
9993
  {
9987
- key: "archive-commit-message",
9988
- property: "archiveCommitMessage",
9994
+ key: "archive.commit-message",
9995
+ path: "archive.commit_message",
9989
9996
  label: "\uCEE4\uBC0B \uBA54\uC2DC\uC9C0 \uD15C\uD50C\uB9BF",
9990
9997
  description: "\uC544\uCE74\uC774\uBE0C \uC2DC \uC0AC\uC6A9\uD560 Git \uCEE4\uBC0B \uBA54\uC2DC\uC9C0 \uD15C\uD50C\uB9BF\uC785\uB2C8\uB2E4.",
9991
9998
  placeholder: "\uBA54\uC2DC\uC9C0 \uD15C\uD50C\uB9BF \uC785\uB825 ({id}, {title} \uC0AC\uC6A9 \uAC00\uB2A5)",
9992
9999
  type: "string"
9993
10000
  },
9994
10001
  {
9995
- key: "include-tag",
9996
- property: "includeTag",
10002
+ key: "markdown.include-tag",
10003
+ path: "markdown.include_tag",
9997
10004
  label: "\uD0DC\uADF8 \uD3EC\uD568 \uC5EC\uBD80",
9998
10005
  description: "README \uC0DD\uC131 \uC2DC \uC54C\uACE0\uB9AC\uC998 \uBD84\uB958(\uD0DC\uADF8)\uB97C \uD3EC\uD568\uD560\uC9C0 \uC5EC\uBD80\uC785\uB2C8\uB2E4.",
9999
10006
  placeholder: "true \uB610\uB294 false \uC785\uB825",
@@ -10008,14 +10015,10 @@ var config = new Conf({
10008
10015
  defaultLanguage: "python",
10009
10016
  codeOpen: false,
10010
10017
  editor: "code",
10011
- // 기본값: VS Code
10012
10018
  autoOpenEditor: false,
10013
- // 기본값: 자동 열기 비활성화
10014
10019
  solvedAcHandle: void 0,
10015
10020
  archiveDir: "problems",
10016
- // 기본값: problems 디렉토리
10017
10021
  solvingDir: "solving",
10018
- // 기본값: solving 디렉토리
10019
10022
  archiveAutoCommit: true,
10020
10023
  includeTag: true
10021
10024
  }
@@ -10026,8 +10029,11 @@ function findProjectRoot(startDir = process.cwd()) {
10026
10029
  let currentDir = startDir;
10027
10030
  const rootPath = process.platform === "win32" ? currentDir.split("\\")[0] + "\\" : "/";
10028
10031
  while (currentDir !== rootPath) {
10029
- const projectConfigPath = join(currentDir, ".ps-cli.json");
10030
- if (existsSync(projectConfigPath)) {
10032
+ const psCliDir = join(currentDir, ".ps-cli");
10033
+ if (existsSync(psCliDir)) {
10034
+ return currentDir;
10035
+ }
10036
+ if (existsSync(join(currentDir, ".ps-cli.json"))) {
10031
10037
  return currentDir;
10032
10038
  }
10033
10039
  const parentDir = dirname(currentDir);
@@ -10038,33 +10044,73 @@ function findProjectRoot(startDir = process.cwd()) {
10038
10044
  }
10039
10045
  return null;
10040
10046
  }
10047
+ function migrateOldConfig(projectRoot) {
10048
+ const oldPath = join(projectRoot, ".ps-cli.json");
10049
+ if (!existsSync(oldPath)) return null;
10050
+ try {
10051
+ const content = readFileSync(oldPath, "utf-8");
10052
+ const oldConfig = JSON.parse(content);
10053
+ const newConfig = {
10054
+ general: {
10055
+ default_language: oldConfig.defaultLanguage,
10056
+ solved_ac_handle: oldConfig.solvedAcHandle
10057
+ },
10058
+ editor: {
10059
+ command: oldConfig.editor,
10060
+ auto_open: oldConfig.autoOpenEditor
10061
+ },
10062
+ paths: {
10063
+ solving: oldConfig.solvingDir,
10064
+ archive: oldConfig.archiveDir,
10065
+ archive_strategy: oldConfig.archiveStrategy
10066
+ },
10067
+ archive: {
10068
+ auto_commit: oldConfig.archiveAutoCommit,
10069
+ commit_message: oldConfig.archiveCommitMessage
10070
+ },
10071
+ markdown: {
10072
+ include_tag: oldConfig.includeTag
10073
+ }
10074
+ };
10075
+ const psCliDir = join(projectRoot, ".ps-cli");
10076
+ if (!existsSync(psCliDir)) {
10077
+ mkdirSync(psCliDir, { recursive: true });
10078
+ }
10079
+ const newPath = join(psCliDir, "config.yaml");
10080
+ writeFileSync2(newPath, stringify(newConfig), "utf-8");
10081
+ unlinkSync(oldPath);
10082
+ return newConfig;
10083
+ } catch (err) {
10084
+ console.error("\uC124\uC815 \uD30C\uC77C \uB9C8\uC774\uADF8\uB808\uC774\uC158 \uC2E4\uD328:", err);
10085
+ return null;
10086
+ }
10087
+ }
10041
10088
  function getProjectConfigSync() {
10042
10089
  try {
10043
10090
  const cwd = process.cwd();
10044
10091
  const projectRoot = findProjectRoot(cwd);
10045
- if (!projectRoot) {
10046
- projectConfigCache = null;
10047
- projectConfigCachePath = null;
10048
- return null;
10049
- }
10050
- const projectConfigPath = join(projectRoot, ".ps-cli.json");
10051
- if (projectConfigCache && projectConfigCachePath === projectConfigPath) {
10092
+ if (!projectRoot) return null;
10093
+ const psCliDir = join(projectRoot, ".ps-cli");
10094
+ const configPath = join(psCliDir, "config.yaml");
10095
+ if (!existsSync(psCliDir) || !existsSync(configPath)) {
10096
+ const migrated = migrateOldConfig(projectRoot);
10097
+ if (migrated) {
10098
+ projectConfigCache = migrated;
10099
+ projectConfigCachePath = configPath;
10100
+ return migrated;
10101
+ }
10102
+ if (!existsSync(configPath)) return null;
10103
+ }
10104
+ if (projectConfigCache && projectConfigCachePath === configPath) {
10052
10105
  return projectConfigCache;
10053
10106
  }
10054
- if (!existsSync(projectConfigPath)) {
10055
- projectConfigCache = null;
10056
- projectConfigCachePath = null;
10057
- return null;
10058
- }
10059
10107
  try {
10060
- const content = readFileSync(projectConfigPath, "utf-8");
10061
- const projectConfig = JSON.parse(content);
10108
+ const content = readFileSync(configPath, "utf-8");
10109
+ const projectConfig = parse(content);
10062
10110
  projectConfigCache = projectConfig;
10063
- projectConfigCachePath = projectConfigPath;
10111
+ projectConfigCachePath = configPath;
10064
10112
  return projectConfig;
10065
10113
  } catch {
10066
- projectConfigCache = null;
10067
- projectConfigCachePath = null;
10068
10114
  return null;
10069
10115
  }
10070
10116
  } catch {
@@ -10073,111 +10119,96 @@ function getProjectConfigSync() {
10073
10119
  }
10074
10120
  function getDefaultLanguage() {
10075
10121
  const projectConfig = getProjectConfigSync();
10076
- if (projectConfig?.defaultLanguage) {
10077
- return projectConfig.defaultLanguage;
10078
- }
10079
- return config.get("defaultLanguage") ?? "python";
10122
+ return projectConfig?.general?.default_language || config.get("defaultLanguage") || "python";
10080
10123
  }
10081
10124
  function getEditor() {
10082
10125
  const projectConfig = getProjectConfigSync();
10083
- if (projectConfig?.editor) {
10084
- return projectConfig.editor;
10085
- }
10086
- return config.get("editor") ?? "code";
10126
+ return projectConfig?.editor?.command || config.get("editor") || "code";
10087
10127
  }
10088
10128
  function getAutoOpenEditor() {
10089
10129
  const projectConfig = getProjectConfigSync();
10090
- if (projectConfig?.autoOpenEditor !== void 0) {
10091
- return projectConfig.autoOpenEditor;
10092
- }
10093
- return config.get("autoOpenEditor") ?? false;
10130
+ return projectConfig?.editor?.auto_open ?? config.get("autoOpenEditor") ?? false;
10094
10131
  }
10095
10132
  function getSolvedAcHandle() {
10096
10133
  const projectConfig = getProjectConfigSync();
10097
- if (projectConfig?.solvedAcHandle) {
10098
- return projectConfig.solvedAcHandle;
10099
- }
10100
- return config.get("solvedAcHandle");
10134
+ return projectConfig?.general?.solved_ac_handle || config.get("solvedAcHandle");
10101
10135
  }
10102
10136
  function getArchiveDir() {
10103
10137
  const projectConfig = getProjectConfigSync();
10104
- if (projectConfig?.archiveDir !== void 0) {
10105
- return projectConfig.archiveDir;
10106
- }
10107
- return config.get("archiveDir") ?? "problems";
10138
+ return projectConfig?.paths?.archive || config.get("archiveDir") || "problems";
10108
10139
  }
10109
10140
  function getSolvingDir() {
10110
10141
  const projectConfig = getProjectConfigSync();
10111
- if (projectConfig?.solvingDir !== void 0) {
10112
- return projectConfig.solvingDir;
10113
- }
10114
- return config.get("solvingDir") ?? "solving";
10142
+ return projectConfig?.paths?.solving || config.get("solvingDir") || "solving";
10115
10143
  }
10116
10144
  function getArchiveStrategy() {
10117
10145
  const projectConfig = getProjectConfigSync();
10118
- if (projectConfig?.archiveStrategy !== void 0) {
10119
- return projectConfig.archiveStrategy;
10120
- }
10121
- return config.get("archiveStrategy") ?? "flat";
10146
+ return projectConfig?.paths?.archive_strategy || config.get("archiveStrategy") || "flat";
10122
10147
  }
10123
10148
  function getArchiveAutoCommit() {
10124
10149
  const projectConfig = getProjectConfigSync();
10125
- if (projectConfig?.archiveAutoCommit !== void 0) {
10126
- return projectConfig.archiveAutoCommit;
10127
- }
10128
- const globalValue = config.get("archiveAutoCommit");
10129
- if (globalValue !== void 0) {
10130
- return globalValue;
10131
- }
10132
- return true;
10150
+ return projectConfig?.archive?.auto_commit ?? config.get("archiveAutoCommit") ?? true;
10133
10151
  }
10134
10152
  function getArchiveCommitMessage() {
10135
10153
  const projectConfig = getProjectConfigSync();
10136
- if (projectConfig?.archiveCommitMessage !== void 0) {
10137
- return projectConfig.archiveCommitMessage;
10138
- }
10139
- return config.get("archiveCommitMessage");
10154
+ return projectConfig?.archive?.commit_message || config.get("archiveCommitMessage");
10140
10155
  }
10141
10156
  function getIncludeTag() {
10142
10157
  const projectConfig = getProjectConfigSync();
10143
- if (projectConfig?.includeTag !== void 0) {
10144
- return projectConfig.includeTag;
10145
- }
10146
- return config.get("includeTag") ?? true;
10158
+ return projectConfig?.markdown?.include_tag ?? config.get("includeTag") ?? true;
10147
10159
  }
10148
10160
 
10149
10161
  // src/core/language.ts
10150
- var SUPPORTED_LANGUAGES = ["python", "cpp"];
10151
- function getSupportedLanguages() {
10152
- return [...SUPPORTED_LANGUAGES];
10153
- }
10154
- function getSupportedLanguagesString() {
10155
- return SUPPORTED_LANGUAGES.join(", ");
10156
- }
10157
- var LANGUAGE_CONFIGS = {
10162
+ var DEFAULT_LANGUAGE_CONFIGS = {
10158
10163
  python: {
10159
10164
  extension: "py",
10160
10165
  templateFile: "solution.py",
10161
- runCommand: "python3",
10162
- bojLangId: 28
10163
- // Python 3
10166
+ runCommand: "python3"
10164
10167
  },
10165
10168
  cpp: {
10166
10169
  extension: "cpp",
10167
10170
  templateFile: "solution.cpp",
10168
- // 절대 경로로 에러를 표시해서 에디터에서 문제 디렉토리의 파일로 바로 이동할 수 있도록 함
10169
10171
  compileCommand: "g++ -fdiagnostics-absolute-paths -o solution solution.cpp",
10170
- runCommand: "./solution",
10171
- bojLangId: 84
10172
- // C++17
10172
+ runCommand: "./solution"
10173
10173
  }
10174
10174
  };
10175
+ function getSupportedLanguages() {
10176
+ const projectConfig = getProjectConfigSync();
10177
+ const customLanguages = Object.keys(projectConfig?.languages || {});
10178
+ const defaultLanguages = Object.keys(DEFAULT_LANGUAGE_CONFIGS);
10179
+ return Array.from(/* @__PURE__ */ new Set([...defaultLanguages, ...customLanguages]));
10180
+ }
10181
+ function getSupportedLanguagesString() {
10182
+ return getSupportedLanguages().join(", ");
10183
+ }
10175
10184
  function getLanguageConfig(language) {
10176
- return LANGUAGE_CONFIGS[language];
10185
+ const projectConfig = getProjectConfigSync();
10186
+ const customConfig = projectConfig?.languages?.[language];
10187
+ if (customConfig) {
10188
+ const templateFile = (
10189
+ // snake_case 우선
10190
+ customConfig.template_file || // 혹시나 camelCase로 들어온 기존 값을 대비
10191
+ customConfig.templateFile?.toString() || `solution.${customConfig.extension}`
10192
+ );
10193
+ return {
10194
+ extension: customConfig.extension,
10195
+ templateFile,
10196
+ compileCommand: customConfig.compile,
10197
+ runCommand: customConfig.run
10198
+ };
10199
+ }
10200
+ return DEFAULT_LANGUAGE_CONFIGS[language] || DEFAULT_LANGUAGE_CONFIGS["python"];
10177
10201
  }
10178
10202
  function detectLanguageFromFile(filename) {
10179
10203
  const ext = filename.split(".").pop()?.toLowerCase();
10180
10204
  if (!ext) return null;
10205
+ const languages = getSupportedLanguages();
10206
+ for (const lang of languages) {
10207
+ const config2 = getLanguageConfig(lang);
10208
+ if (config2.extension === ext) {
10209
+ return lang;
10210
+ }
10211
+ }
10181
10212
  switch (ext) {
10182
10213
  case "py":
10183
10214
  return "python";
@@ -11321,8 +11352,26 @@ var logger = {
11321
11352
  hex: source_default.hex
11322
11353
  };
11323
11354
 
11355
+ // src/utils/version.ts
11356
+ import { readFileSync as readFileSync2 } from "fs";
11357
+ import { join as join4, dirname as dirname2 } from "path";
11358
+ import { fileURLToPath } from "url";
11359
+ function getVersion() {
11360
+ try {
11361
+ const __filename = fileURLToPath(import.meta.url);
11362
+ const __dirname = dirname2(__filename);
11363
+ const packageJsonPath = join4(__dirname, "../../package.json");
11364
+ const packageJson = JSON.parse(readFileSync2(packageJsonPath, "utf-8"));
11365
+ return packageJson.version;
11366
+ } catch {
11367
+ return "";
11368
+ }
11369
+ }
11370
+
11324
11371
  // src/utils/help.ts
11325
11372
  function generateGlobalHelp(commands) {
11373
+ const version = getVersion();
11374
+ const versionInfo = version ? source_default.dim(` v${version}`) : "";
11326
11375
  const title = psGradient.multiline(`
11327
11376
 
11328
11377
  \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557
@@ -11331,7 +11380,7 @@ function generateGlobalHelp(commands) {
11331
11380
  \u2588\u2588\u2554\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551
11332
11381
  \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551
11333
11382
  \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D
11334
- `);
11383
+ `) + "\n" + versionInfo;
11335
11384
  const usage = `
11336
11385
  ${logger.bold("\uC0AC\uC6A9\uBC95:")}
11337
11386
  $ ps ${source_default.hex(colors.primary)("<\uBA85\uB839\uC5B4>")} [\uC778\uC790] [\uC635\uC158]
@@ -11526,6 +11575,7 @@ export {
11526
11575
  source_default,
11527
11576
  icons,
11528
11577
  logger,
11578
+ getVersion,
11529
11579
  generateGlobalHelp,
11530
11580
  CommandDef,
11531
11581
  CommandBuilder,
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runSolution
4
- } from "./chunk-YZUGYJA4.js";
4
+ } from "./chunk-GV265WOR.js";
5
5
  import {
6
6
  Command,
7
7
  CommandBuilder,
@@ -13,7 +13,7 @@ import {
13
13
  icons,
14
14
  resolveLanguage,
15
15
  resolveProblemContext
16
- } from "./chunk-Q5NECGFA.js";
16
+ } from "./chunk-AHE4QHJD.js";
17
17
 
18
18
  // src/commands/test.tsx
19
19
  import { Alert, Spinner } from "@inkjs/ui";