projectops 4.84.0 → 4.85.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -13
- package/package.json +1 -1
- package/src/cli/errors.js +4 -0
- package/src/commands/doctor.js +1 -1
- package/src/core/assets.js +1 -1
- package/src/core/breaking-check.js +2 -1
- package/src/core/copy/workflows.js +2 -1
- package/src/core/fsutil.js +21 -5
- package/src/core/ide/adapters/claude.js +2 -2
- package/src/core/ide/adapters/codex.js +1 -1
- package/src/core/ide/home-skills.js +2 -1
- package/src/core/ide/legacy.js +4 -4
- package/src/core/ide/skills-copy.js +4 -6
- package/src/core/run-trace.js +1 -1
- package/src/i18n/core.en.js +2 -0
- package/src/i18n/core.ko.js +2 -0
- package/src/i18n/ide.en.js +1 -0
- package/src/i18n/ide.ko.js +1 -0
package/README.md
CHANGED
|
@@ -8,10 +8,10 @@
|
|
|
8
8
|
|
|
9
9
|
[](https://www.npmjs.com/package/projectops) [](https://github.com/Cassiiopeia/projectops/releases) [](LICENSE) [](https://cassiiopeia.github.io/projectops/)
|
|
10
10
|
|
|
11
|
-
**Status: actively maintained.** npm `latest` is exactly what is on the `main` branch; work in progress on `develop` is never published. Versions can still ship several times a day.
|
|
11
|
+
**Status: actively maintained.** npm `latest` is exactly what is on the `main` branch; work in progress on `develop` is never published. Versions can still ship several times a day. Note that `npx projectops@<version>` pins the installer only (workflow templates always come from the current `main`) ([releases](https://github.com/Cassiiopeia/projectops/releases)).
|
|
12
12
|
|
|
13
13
|
<!-- AUTO-VERSION-SECTION: DO NOT EDIT MANUALLY -->
|
|
14
|
-
## Latest version : v4.
|
|
14
|
+
## Latest version : v4.84.0 (2026-11-04)
|
|
15
15
|
|
|
16
16
|
[View full version history](CHANGELOG.md)
|
|
17
17
|
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
| Install Agent Skills only | `npx projectops --mode skills` |
|
|
29
29
|
| Check the install state (read-only) | `npx projectops --mode doctor` |
|
|
30
30
|
|
|
31
|
-
> You
|
|
31
|
+
> You need Node.js 20.12+ and Git (Agent Skills also need Python 3). An interactive wizard runs with no separate install.
|
|
32
32
|
|
|
33
33
|

|
|
34
34
|
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
|
|
41
41
|
This project automates your development workflow on two axes.
|
|
42
42
|
|
|
43
|
-
**① GitHub Actions**:
|
|
43
|
+
**① GitHub Actions**: a develop-to-main release PR handles versioning and changelogs; merging it runs CI/CD deployment.
|
|
44
44
|
**② Agent Skills**: commands such as `/pro-github`, `/pro-commit`, and `/pro-report` let an AI agent drive each step of that automation for you: issues, commits in your own style, reports, and release PRs.
|
|
45
45
|
|
|
46
46
|
| The usual way | With Projectops |
|
|
@@ -64,15 +64,15 @@ If you only need one piece of this, a smaller tool may suit you better.
|
|
|
64
64
|
| Version decided from | Commit titles (`feat` → minor, `feat!` → major) | Conventional Commits | Conventional Commits (configurable) | Changeset files written in each PR |
|
|
65
65
|
| Review step before a release | A release PR (develop → main), merged automatically | A release PR you merge | None by default, releases on push | A "Version Packages" PR |
|
|
66
66
|
| Changelog | Written in the release PR (commit analysis, or an AI summary) | Generated | Generated (plugin) | Assembled from changeset files |
|
|
67
|
-
| CI/CD workflows for your project type | Yes (Spring, Flutter, React,
|
|
67
|
+
| CI/CD workflows for your project type | Yes (Spring, Flutter, React, Python; npm publish for Node) | No | No | No |
|
|
68
68
|
| Agent skills that run the cycle (issues, worktrees, commits in your style, reports, release PRs, real-device QA) | Yes | No | No | No |
|
|
69
|
-
| What it adds to your repo | About
|
|
69
|
+
| What it adds to your repo | About 60 files (below) | A workflow and a config file | A config file and a CI step | A `.changeset/` folder and a CI step |
|
|
70
70
|
|
|
71
71
|
- Want only versioning and a changelog? release-please or semantic-release is smaller.
|
|
72
72
|
- Publishing npm packages from a monorepo where each PR should say what changed? changesets fits better.
|
|
73
73
|
- Want the whole cycle (issue → branch → release PR → deploy) in one install, with agent skills on top? That is what projectops is for.
|
|
74
74
|
|
|
75
|
-
**Footprint, measured.** With v4.
|
|
75
|
+
**Footprint, measured.** With v4.84.0 on 2026-11-05, `npx projectops --mode full --type basic --force` in an empty repository added 56 files: 8 workflows, 30 helper scripts under `.github/scripts/`, issue, PR and discussion templates, `version.yml` and a setup guide. `--type spring` added 60 files (12 workflows).
|
|
76
76
|
|
|
77
77
|
---
|
|
78
78
|
|
|
@@ -128,10 +128,9 @@ We ran `/pro-oss-consult` on this repo, then fixed what it found (measured 2026-
|
|
|
128
128
|
|---|---|---|
|
|
129
129
|
| Skill count stated in README and manifests | inconsistent (15 vs 20 stated, actual 15) | consistent: 14 core + 1 in the optional extras plugin |
|
|
130
130
|
| Longest skill description | 1,183 chars; 6 over 1,000 | 237 chars; 0 over 300 |
|
|
131
|
-
| Skills with no tests (all 15 skills) | 6 | 0 (56 contract test cases cover all 15 skills, 14 core + 1 extras) |
|
|
132
131
|
| Commit format | hardcoded in `pro-commit` | configurable via preferences and `version.yml` |
|
|
133
132
|
|
|
134
|
-
What it changed: descriptions were cut to short English triggers, a
|
|
133
|
+
What it changed: descriptions were cut to short English triggers, a guard test now checks every core skill's docs, and `pro-commit` follows your team's `version.yml` commit template.
|
|
135
134
|
|
|
136
135
|
---
|
|
137
136
|
|
|
@@ -139,7 +138,7 @@ What it changed: descriptions were cut to short English triggers, a shared contr
|
|
|
139
138
|
|
|
140
139
|
| Part | What it does | Docs |
|
|
141
140
|
|---|---|---|
|
|
142
|
-
| **GitHub Actions** |
|
|
141
|
+
| **GitHub Actions** | A develop-to-main release PR handles versioning and changelogs; merging it runs CI/CD deployment | [Versioning](https://cassiiopeia.github.io/projectops/version-control) |
|
|
143
142
|
| **Agent Skills** (15) | `/pro-github`, `/pro-commit`, `/pro-report` and more let an AI agent drive each step: issues, commits in your style, reports, release PRs | [Skills guide](https://cassiiopeia.github.io/projectops/skills) |
|
|
144
143
|
| **npx CLI** | Installs and updates workflows in an existing project, and diagnoses its state | [CLI reference](https://cassiiopeia.github.io/projectops/cli) |
|
|
145
144
|
|
|
@@ -270,7 +269,7 @@ npx projectops --mode skills
|
|
|
270
269
|
| `spring` | build.gradle | SSH + Docker deploy, Nexus |
|
|
271
270
|
| `flutter` | pubspec.yaml | TestFlight, Play Store |
|
|
272
271
|
| `react` (including Next.js) | package.json | Docker |
|
|
273
|
-
| `node` | package.json |
|
|
272
|
+
| `node` | package.json | npm publish (`--publish npm`) |
|
|
274
273
|
| `python` | pyproject.toml | SSH + Docker deploy |
|
|
275
274
|
| `react-native` | Info.plist + build.gradle | — |
|
|
276
275
|
| `react-native-expo` | app.json | — |
|
|
@@ -334,8 +333,8 @@ We would rather tell you up front when this is not a fit.
|
|
|
334
333
|
- **GitHub only.** It assumes GitHub Actions and GitHub issues/PRs, so GitLab and others are not supported.
|
|
335
334
|
- **Releases assume a develop branch → default branch PR flow.** Branch names can be changed in `version.yml`, but it does not suit a repo that does not use two branches.
|
|
336
335
|
- **A personal access token is optional.** You need one only to merge past branch protection or to sync a Projects board. See [Setup](#setup).
|
|
337
|
-
- **It adds about
|
|
338
|
-
- **New versions ship often.** `latest` follows every push to `main` with no delay.
|
|
336
|
+
- **It adds about 60 files to your repository** (workflows, helper scripts, templates). See [the measurement](#compared-with-other-tools).
|
|
337
|
+
- **New versions ship often.** `latest` follows every push to `main` with no delay. `npx projectops@<version>` pins the installer only; workflow templates always come from the current `main`.
|
|
339
338
|
- **Server deploy workflows assume a Docker server reachable over SSH.**
|
|
340
339
|
|
|
341
340
|
---
|
package/package.json
CHANGED
package/src/cli/errors.js
CHANGED
|
@@ -14,6 +14,10 @@ export function describeError(err) {
|
|
|
14
14
|
}
|
|
15
15
|
// 템플릿 내려받기 실패 — execFileSync 가 "Command failed: git clone ..." 를 던진다
|
|
16
16
|
if (/Command failed: git clone/.test(msg)) {
|
|
17
|
+
// Windows 경로 길이 한계 — 네트워크 탓으로 안내하면 엉뚱한 곳을 보게 된다
|
|
18
|
+
if (/Filename too long|cannot stat/i.test(msg)) {
|
|
19
|
+
return { message: t("errors.clone.pathTooLong.message"), hint: t("errors.clone.pathTooLong.hint") };
|
|
20
|
+
}
|
|
17
21
|
return {
|
|
18
22
|
message: t("errors.clone.message"),
|
|
19
23
|
hint: t("errors.clone.hint"),
|
package/src/commands/doctor.js
CHANGED
|
@@ -154,7 +154,7 @@ export function localChecks(cwd = ".") {
|
|
|
154
154
|
// 다른 워크플로우를 깨우는 파일만 — 주석 줄의 언급(깨워지는 쪽 설명)은 호출이 아니다
|
|
155
155
|
const code = body.split("\n").filter((line) => !/^\s*#/.test(line)).join("\n");
|
|
156
156
|
if (!code.includes("dispatch_downstream.py")) continue;
|
|
157
|
-
const perm = body.match(/^permissions:\n((?:\s+.*\n)+)/m);
|
|
157
|
+
const perm = body.match(/^permissions:\r?\n((?:\s+.*\r?\n)+)/m);
|
|
158
158
|
const hasActionsWrite = perm ? /^\s+actions:\s*write/m.test(perm[1]) : false;
|
|
159
159
|
if (!hasActionsWrite) needsActionsWrite.push(f);
|
|
160
160
|
}
|
package/src/core/assets.js
CHANGED
|
@@ -26,7 +26,7 @@ export function acquireTemplate({ tempDir, source = { type: "git" }, keep = [] }
|
|
|
26
26
|
// clone 은 stdio 를 버려 실패 원인이 사라진다 — 폴더가 읽기 전용이어도 "내려받지 못했다"로 오도되므로
|
|
27
27
|
// 먼저 만들어 권한 오류(EACCES/EPERM/EROFS)를 그대로 올린다 (#720). 빈 폴더에는 clone 이 가능하다.
|
|
28
28
|
mkdirSync(tempDir, { recursive: true });
|
|
29
|
-
execFileSync("git", ["clone", "--depth", "1", "--quiet", repo, tempDir], { stdio: "ignore" });
|
|
29
|
+
execFileSync("git", ["clone", "-c", "core.longpaths=true", "--depth", "1", "--quiet", repo, tempDir], { stdio: ["ignore", "ignore", "pipe"] });
|
|
30
30
|
}
|
|
31
31
|
applyExclusions(tempDir, { keep });
|
|
32
32
|
}
|
|
@@ -5,8 +5,9 @@ import { join } from "node:path";
|
|
|
5
5
|
import { collectBreaking, localizeBreakingEntry } from "./breaking.js";
|
|
6
6
|
import { parseExisting } from "./version-yml.js";
|
|
7
7
|
import { t, getLang } from "../i18n/index.js";
|
|
8
|
+
import { TEMPLATE_RAW_URL } from "./paths.js";
|
|
8
9
|
|
|
9
|
-
const BC_URL =
|
|
10
|
+
const BC_URL = `${TEMPLATE_RAW_URL}/.github/config/breaking-changes.json`;
|
|
10
11
|
|
|
11
12
|
// 원격 우선(3초 타임아웃) → clone된 템플릿의 번들본 폴백 → 둘 다 실패 시 null(조용히 스킵)
|
|
12
13
|
export async function loadBreakingJson(tempDir) {
|
|
@@ -308,8 +308,9 @@ function recordBaseline(workflowsDir, targetRoot, counters, previous, templateVe
|
|
|
308
308
|
entries,
|
|
309
309
|
previous,
|
|
310
310
|
});
|
|
311
|
-
} catch {
|
|
311
|
+
} catch (e) {
|
|
312
312
|
// 기준점 기록 실패는 통합 실패가 아니다
|
|
313
|
+
trace?.event("baseline", "baseline-failed", "", { message: e?.message || String(e) });
|
|
313
314
|
}
|
|
314
315
|
}
|
|
315
316
|
|
package/src/core/fsutil.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// 파일시스템 공용 유틸 (LF 보존 바이트 복사). 텍스트는 그대로 복사해 원본 줄바꿈 유지.
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
readdirSync, rmSync,
|
|
3
|
+
copyFileSync as copyFileBytes, existsSync, lstatSync, readFileSync, readlinkSync, symlinkSync,
|
|
4
|
+
writeFileSync, mkdirSync, readdirSync, rmSync,
|
|
5
5
|
} from "node:fs";
|
|
6
|
-
import { dirname } from "node:path";
|
|
6
|
+
import { dirname, join } from "node:path";
|
|
7
7
|
|
|
8
8
|
export const exists = (p) => existsSync(p);
|
|
9
9
|
export const readText = (p) => readFileSync(p, "utf8");
|
|
@@ -16,13 +16,29 @@ export function writeText(p, s) {
|
|
|
16
16
|
// 단일 파일 복사 (부모 디렉토리 자동 생성, 바이트 그대로)
|
|
17
17
|
export function copyFileSync(src, dst) {
|
|
18
18
|
mkdirSync(dirname(dst), { recursive: true });
|
|
19
|
-
|
|
19
|
+
copyFileBytes(src, dst);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// 파일·폴더·심볼릭 링크 재귀 복사. fs.cpSync 는 쓰지 않는다:
|
|
23
|
+
// Windows + Node 22 이상에서 경로에 한글이 있으면 메시지 없이 프로세스가 죽는다.
|
|
24
|
+
export function copyPathSync(src, dst, filter) {
|
|
25
|
+
if (filter && !filter(src)) return;
|
|
26
|
+
const stat = lstatSync(src);
|
|
27
|
+
if (stat.isSymbolicLink()) {
|
|
28
|
+
rmSync(dst, { force: true });
|
|
29
|
+
symlinkSync(readlinkSync(src), dst);
|
|
30
|
+
} else if (stat.isDirectory()) {
|
|
31
|
+
mkdirSync(dst, { recursive: true });
|
|
32
|
+
for (const name of readdirSync(src)) copyPathSync(join(src, name), join(dst, name), filter);
|
|
33
|
+
} else {
|
|
34
|
+
copyFileSync(src, dst);
|
|
35
|
+
}
|
|
20
36
|
}
|
|
21
37
|
|
|
22
38
|
// 디렉토리 재귀 복사 (내용을 dst 하위로)
|
|
23
39
|
export function copyDirSync(src, dst, { filter } = {}) {
|
|
24
40
|
mkdirSync(dst, { recursive: true });
|
|
25
|
-
|
|
41
|
+
copyPathSync(src, dst, filter);
|
|
26
42
|
}
|
|
27
43
|
|
|
28
44
|
// 파일/폴더 삭제 (없어도 무해)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Claude Code 어댑터 (플러그인 설치·제거, 플러그인 데이터 정리).
|
|
2
2
|
// 마켓플레이스 Cassiiopeia/projectops, 플러그인 projectops@projectops-marketplace.
|
|
3
3
|
import { join } from "node:path";
|
|
4
|
-
import { existsSync, readdirSync, mkdirSync,
|
|
4
|
+
import { existsSync, readdirSync, mkdirSync, copyFileSync, rmSync } from "node:fs";
|
|
5
5
|
import { compareCacheName } from "../util.js";
|
|
6
6
|
import { migrateConfigRoot } from "../legacy.js";
|
|
7
7
|
import { t } from "../../../i18n/index.js";
|
|
@@ -107,7 +107,7 @@ function migrateConfig(io, oldCache, newCache) {
|
|
|
107
107
|
try {
|
|
108
108
|
mkdirSync(newCfg, { recursive: true });
|
|
109
109
|
let copied = 0;
|
|
110
|
-
for (const f of readdirSync(oldCfg)) if (f.endsWith(".json")) {
|
|
110
|
+
for (const f of readdirSync(oldCfg)) if (f.endsWith(".json")) { copyFileSync(join(oldCfg, f), join(newCfg, f)); copied++; }
|
|
111
111
|
if (copied) io.log(t("ide.claude.configMigrated"));
|
|
112
112
|
} catch { /* 무해 */ }
|
|
113
113
|
}
|
|
@@ -38,7 +38,7 @@ function remove(io) {
|
|
|
38
38
|
const tgt = nativeTarget(io);
|
|
39
39
|
let removed = false;
|
|
40
40
|
if (existsSync(tgt) || isSymlink(tgt)) {
|
|
41
|
-
try { rmSync(tgt, { recursive: true, force: true }); io.log(t("ide.codex.skillsRemoved", { path: tgt })); removed = true; } catch {
|
|
41
|
+
try { rmSync(tgt, { recursive: true, force: true }); io.log(t("ide.codex.skillsRemoved", { path: tgt })); removed = true; } catch (e) { removed = true; io.log(t("ide.codex.removeFailed", { path: tgt, error: e.message })); }
|
|
42
42
|
}
|
|
43
43
|
if (!removed) io.log(t("ide.codex.removeNone"));
|
|
44
44
|
if (io.which("codex")) io.log(t("ide.codex.unregisterManual", { plugin: PLUGIN }));
|
|
@@ -23,8 +23,9 @@ export function applyHomeSkills(io, ctx, { skillsDest, metaFileName, messagePref
|
|
|
23
23
|
// 공용 파이썬이 없으면 스킬 CLI 가 import 에 실패 → 알림만 (문서형 스킬은 동작)
|
|
24
24
|
if (!hasSharedScripts) io.log(t("ide.skillsCopy.noScripts"));
|
|
25
25
|
io.log(t(`${messagePrefix}.installed`, { dest: skillsDest, version: ctx.templateVersion || "unknown" }));
|
|
26
|
-
} catch {
|
|
26
|
+
} catch (e) {
|
|
27
27
|
io.log(t(`${messagePrefix}.copyFailed`));
|
|
28
|
+
io.log(` ${e?.message || e}`);
|
|
28
29
|
return false;
|
|
29
30
|
}
|
|
30
31
|
installStableEntrypoints(io, skillsSrc, scriptsSrc);
|
package/src/core/ide/legacy.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// IDE 어댑터 공용 레거시 유틸 — 버전 판정 + config 루트 이관.
|
|
2
2
|
// 리브랜딩(#459) 전 설치본(cassiiopeia/SUH-DEVOPS-TEMPLATE)을 신규(projectops)로 넘길 때 공용.
|
|
3
|
-
import { join
|
|
4
|
-
import { existsSync, readFileSync
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
5
|
+
import { copyFileSync } from "../fsutil.js";
|
|
5
6
|
import { compareCacheName } from "./util.js";
|
|
6
7
|
|
|
7
8
|
// version <= maxLegacy 이면 레거시. null/빈문자열은 판정 불가 → false(안전).
|
|
@@ -31,8 +32,7 @@ export function migrateConfigRoot(io) {
|
|
|
31
32
|
const src = sources.find(hasNonEmptyJson);
|
|
32
33
|
if (!src) return { migrated: false, reason: "no-source" };
|
|
33
34
|
try {
|
|
34
|
-
|
|
35
|
-
cpSync(src, target);
|
|
35
|
+
copyFileSync(src, target);
|
|
36
36
|
io.log(` config 마이그레이션 완료: ${src} → ~/.projectops/config/config.json`);
|
|
37
37
|
return { migrated: true, from: src };
|
|
38
38
|
} catch (e) {
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
// 설치 모양은 플러그인 캐시와 같다: <설치 루트>/skills/pro-*/scripts/x_cli.py + <설치 루트>/scripts/common
|
|
4
4
|
// (스킬 CLI bootstrap 이 x_cli.py 기준 3단계 위의 scripts/ 를 import 경로로 쓴다)
|
|
5
5
|
import { dirname, join, relative } from "node:path";
|
|
6
|
-
import { existsSync, readFileSync, mkdirSync,
|
|
6
|
+
import { existsSync, readFileSync, mkdirSync, rmSync, writeFileSync, readdirSync } from "node:fs";
|
|
7
|
+
import { copyPathSync } from "../fsutil.js";
|
|
7
8
|
import { TEMPLATE_REPO_WEB_URL } from "../paths.js";
|
|
8
9
|
|
|
9
10
|
// 스킬을 쓰는 사람에게 필요 없는 것. projectops 자신을 검사하는 테스트다.
|
|
@@ -53,11 +54,8 @@ function copyEntriesWithoutTests(src, dest, skipNames = new Set()) {
|
|
|
53
54
|
const copiedNames = [];
|
|
54
55
|
for (const e of readdirSync(src, { withFileTypes: true })) {
|
|
55
56
|
if (SKIP_IN_COPY.has(e.name) || TEST_PATH.test(e.name) || skipNames.has(e.name)) continue;
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
// 이 저장소 자기 코드를 검사하는 테스트는 남의 컴퓨터로 나갈 이유가 없다 (#591).
|
|
59
|
-
filter: (p) => !TEST_PATH.test(relative(src, p)),
|
|
60
|
-
});
|
|
57
|
+
// 이 저장소 자기 코드를 검사하는 테스트는 남의 컴퓨터로 나갈 이유가 없다 (#591).
|
|
58
|
+
copyPathSync(join(src, e.name), join(dest, e.name), (p) => !TEST_PATH.test(relative(src, p)));
|
|
61
59
|
copiedNames.push(e.name);
|
|
62
60
|
}
|
|
63
61
|
return copiedNames;
|
package/src/core/run-trace.js
CHANGED
|
@@ -51,7 +51,7 @@ function elapsed(t0, clockIso) {
|
|
|
51
51
|
const ERROR_ACTIONS = new Set(["error", "failed"]);
|
|
52
52
|
const WARN_ACTIONS = new Set([
|
|
53
53
|
"unresolved", "cancelled", "skipped-conflict", "leftover-old-gen",
|
|
54
|
-
"neutralized", "detected", "replaced-bak", "incoming-failed",
|
|
54
|
+
"neutralized", "detected", "replaced-bak", "incoming-failed", "baseline-failed",
|
|
55
55
|
]);
|
|
56
56
|
const DEBUG_ACTIONS = new Set([
|
|
57
57
|
"copied", "skipped-unchanged", "excluded", "substituted", "branch-substituted",
|
package/src/i18n/core.en.js
CHANGED
|
@@ -21,6 +21,8 @@ export default {
|
|
|
21
21
|
"errors.git.hint": "Check that git is installed and on your PATH.",
|
|
22
22
|
"errors.clone.message": "Could not download the template.",
|
|
23
23
|
"errors.clone.hint": "Check your network, proxy settings and GitHub access, then run again.",
|
|
24
|
+
"errors.clone.pathTooLong.message": "This folder path is too long for Windows to hold the template.",
|
|
25
|
+
"errors.clone.pathTooLong.hint": "Move the project to a shorter path (for example C:/dev/my-app) and run again.",
|
|
24
26
|
"errors.write.message": "Cannot write the file{where}.",
|
|
25
27
|
"errors.write.hint": "Check write permission (and read-only status) of the project folder and the .github folder.",
|
|
26
28
|
"errors.disk.message": "Not enough disk space.",
|
package/src/i18n/core.ko.js
CHANGED
|
@@ -21,6 +21,8 @@ export default {
|
|
|
21
21
|
"errors.git.hint": "git 이 설치되어 있고 PATH 에 있는지 확인하세요.",
|
|
22
22
|
"errors.clone.message": "템플릿을 내려받지 못했습니다.",
|
|
23
23
|
"errors.clone.hint": "네트워크·프록시 설정과 GitHub 접근 가능 여부를 확인한 뒤 다시 실행하세요.",
|
|
24
|
+
"errors.clone.pathTooLong.message": "폴더 경로가 너무 길어 Windows에서 템플릿을 받을 수 없습니다.",
|
|
25
|
+
"errors.clone.pathTooLong.hint": "프로젝트를 더 짧은 경로(예: C:/dev/my-app)로 옮긴 뒤 다시 실행하세요.",
|
|
24
26
|
"errors.write.message": "파일을 쓸 수 없습니다{where}.",
|
|
25
27
|
"errors.write.hint": "프로젝트 폴더와 .github 폴더의 쓰기 권한(읽기 전용 여부)을 확인하세요.",
|
|
26
28
|
"errors.disk.message": "디스크 공간이 부족합니다.",
|
package/src/i18n/ide.en.js
CHANGED
|
@@ -26,6 +26,7 @@ export default {
|
|
|
26
26
|
"ide.codex.marketError": " Codex marketplace error. Manual: codex plugin marketplace add {market}",
|
|
27
27
|
"ide.codex.skillsRemoved": " Codex native skills removed ({path})",
|
|
28
28
|
"ide.codex.removeNone": " No Codex skills to remove, skipping",
|
|
29
|
+
"ide.codex.removeFailed": " Could not remove {path}: {error}",
|
|
29
30
|
"ide.codex.unregisterManual": " To unregister the marketplace, run manually: codex plugin marketplace remove {plugin}",
|
|
30
31
|
"ide.codex.legacy": " Removed legacy Codex skills: {name}",
|
|
31
32
|
"ide.cursor.noSource": " Could not find the skills source (a skills/ folder is required).",
|
package/src/i18n/ide.ko.js
CHANGED
|
@@ -26,6 +26,7 @@ export default {
|
|
|
26
26
|
"ide.codex.marketError": " Codex marketplace 관리 오류 — 수동: codex plugin marketplace add {market}",
|
|
27
27
|
"ide.codex.skillsRemoved": " Codex native skills 제거 완료 ({path})",
|
|
28
28
|
"ide.codex.removeNone": " 제거할 Codex skills가 없어 건너뜁니다",
|
|
29
|
+
"ide.codex.removeFailed": " {path} 삭제 실패: {error}",
|
|
29
30
|
"ide.codex.unregisterManual": " marketplace 등록 해제는 수동: codex plugin marketplace remove {plugin}",
|
|
30
31
|
"ide.codex.legacy": " 레거시 Codex skills 정리: {name}",
|
|
31
32
|
"ide.cursor.noSource": " 설치할 스킬 소스를 찾지 못했습니다 (skills/ 폴더 필요).",
|