@kaydash9999/banker-plugins 0.16.2 → 0.17.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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +44 -0
- package/README.md +15 -10
- package/bin/banker.js +2 -2
- package/codex/manifest.json +2 -1
- package/codex/transform-matrix.md +2 -1
- package/commands/setup.md +2 -2
- package/hooks/progress-plan.mjs +716 -0
- package/hooks/progress.mjs +378 -34
- package/hooks/register.mjs +24 -1
- package/package.json +1 -1
- package/skills/3d-intro-build/references/assemble.mjs +10 -2
- package/skills/3d-intro-build/references/curate.mjs +10 -2
- package/skills/3d-intro-build/references/preview-lib.mjs +2 -0
- package/skills/3d-intro-build/references/serve.mjs +10 -2
- package/skills/3d-intro-build/references/verify-intro.mjs +10 -2
- package/skills/motion-graphic-make/references/curate.mjs +10 -2
- package/skills/motion-graphic-make/references/preview-lib.mjs +2 -0
- package/skills/motion-graphic-make/references/serve.mjs +10 -2
- package/skills/obsidizer/obsidize.mjs +10 -2
- package/skills/omc-patch/SKILL.md +96 -21
- package/skills/omc-patch/scripts/omc-patch.mjs +164 -62
- package/skills/omc-patch/scripts/probe-pm.mjs +192 -0
- package/skills/ultra-chain/SKILL.md +475 -0
- package/skills/ultra-chain/references/capture.mjs +232 -0
- package/skills/ultra-chain/references/chain-ledger.mjs +491 -0
- package/skills/ultra-chain/references/chain-report.mjs +257 -0
- package/skills/ultra-chain/references/preview-lib.mjs +258 -0
- package/skills/ultra-chain/references/serve.mjs +139 -0
- package/skills/vertical-pptx/verify_a4p.mjs +10 -2
|
@@ -601,7 +601,15 @@ async function main() {
|
|
|
601
601
|
return serveMain(dir, o);
|
|
602
602
|
}
|
|
603
603
|
|
|
604
|
-
|
|
605
|
-
|
|
604
|
+
// Node resolves links for import.meta.url but not for process.argv[1], so both go through realpath:
|
|
605
|
+
// compared as given, a run through a linked folder would exit 0 without doing anything.
|
|
606
|
+
const invokedDirectly = () => {
|
|
607
|
+
try {
|
|
608
|
+
return fs.realpathSync(process.argv[1]) === fs.realpathSync(fileURLToPath(import.meta.url));
|
|
609
|
+
} catch {
|
|
610
|
+
return false;
|
|
611
|
+
}
|
|
612
|
+
};
|
|
613
|
+
if (invokedDirectly()) {
|
|
606
614
|
main().catch((e) => { console.error(String(e?.message || e)); process.exit(1); });
|
|
607
615
|
}
|
|
@@ -38,6 +38,8 @@ export const MIME = {
|
|
|
38
38
|
'.mjs': 'text/javascript;charset=utf-8', '.json': 'application/json;charset=utf-8', '.png': 'image/png',
|
|
39
39
|
'.jpg': 'image/jpeg', '.jpeg': 'image/jpeg', '.webp': 'image/webp', '.gif': 'image/gif', '.svg': 'image/svg+xml',
|
|
40
40
|
'.mp4': 'video/mp4', '.webm': 'video/webm', '.mov': 'video/quicktime', '.woff2': 'font/woff2',
|
|
41
|
+
// Notes and logs a report links to open as text in the browser instead of downloading.
|
|
42
|
+
'.md': 'text/plain;charset=utf-8', '.txt': 'text/plain;charset=utf-8', '.log': 'text/plain;charset=utf-8', '.jsonl': 'text/plain;charset=utf-8',
|
|
41
43
|
};
|
|
42
44
|
|
|
43
45
|
// `strict` is the policy above; any other text is a policy as written; nothing means no header.
|
|
@@ -125,7 +125,15 @@ async function main() {
|
|
|
125
125
|
process.on('SIGTERM', quit);
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
-
|
|
129
|
-
|
|
128
|
+
// Node resolves links for import.meta.url but not for process.argv[1], so both go through realpath:
|
|
129
|
+
// compared as given, a run through a linked folder would exit 0 without doing anything.
|
|
130
|
+
const invokedDirectly = () => {
|
|
131
|
+
try {
|
|
132
|
+
return fs.realpathSync(process.argv[1]) === fs.realpathSync(fileURLToPath(import.meta.url));
|
|
133
|
+
} catch {
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
if (invokedDirectly()) {
|
|
130
138
|
main().catch((e) => { console.error(String(e?.message || e)); process.exit(1); });
|
|
131
139
|
}
|
|
@@ -468,8 +468,16 @@ export function parseArgs(argv) {
|
|
|
468
468
|
return o;
|
|
469
469
|
}
|
|
470
470
|
|
|
471
|
-
|
|
472
|
-
|
|
471
|
+
// Node resolves links for import.meta.url but not for process.argv[1], so both go through realpath:
|
|
472
|
+
// compared as given, a run through a linked folder would exit 0 without doing anything.
|
|
473
|
+
const invokedDirectly = () => {
|
|
474
|
+
try {
|
|
475
|
+
return fs.realpathSync(process.argv[1]) === fs.realpathSync(fileURLToPath(import.meta.url));
|
|
476
|
+
} catch {
|
|
477
|
+
return false;
|
|
478
|
+
}
|
|
479
|
+
};
|
|
480
|
+
if (invokedDirectly()) {
|
|
473
481
|
let o;
|
|
474
482
|
try { o = parseArgs(process.argv.slice(2)); } catch (e) { console.error(e.message); process.exit(2); }
|
|
475
483
|
if (!o.url) {
|
|
@@ -601,7 +601,15 @@ async function main() {
|
|
|
601
601
|
return serveMain(dir, o);
|
|
602
602
|
}
|
|
603
603
|
|
|
604
|
-
|
|
605
|
-
|
|
604
|
+
// Node resolves links for import.meta.url but not for process.argv[1], so both go through realpath:
|
|
605
|
+
// compared as given, a run through a linked folder would exit 0 without doing anything.
|
|
606
|
+
const invokedDirectly = () => {
|
|
607
|
+
try {
|
|
608
|
+
return fs.realpathSync(process.argv[1]) === fs.realpathSync(fileURLToPath(import.meta.url));
|
|
609
|
+
} catch {
|
|
610
|
+
return false;
|
|
611
|
+
}
|
|
612
|
+
};
|
|
613
|
+
if (invokedDirectly()) {
|
|
606
614
|
main().catch((e) => { console.error(String(e?.message || e)); process.exit(1); });
|
|
607
615
|
}
|
|
@@ -38,6 +38,8 @@ export const MIME = {
|
|
|
38
38
|
'.mjs': 'text/javascript;charset=utf-8', '.json': 'application/json;charset=utf-8', '.png': 'image/png',
|
|
39
39
|
'.jpg': 'image/jpeg', '.jpeg': 'image/jpeg', '.webp': 'image/webp', '.gif': 'image/gif', '.svg': 'image/svg+xml',
|
|
40
40
|
'.mp4': 'video/mp4', '.webm': 'video/webm', '.mov': 'video/quicktime', '.woff2': 'font/woff2',
|
|
41
|
+
// Notes and logs a report links to open as text in the browser instead of downloading.
|
|
42
|
+
'.md': 'text/plain;charset=utf-8', '.txt': 'text/plain;charset=utf-8', '.log': 'text/plain;charset=utf-8', '.jsonl': 'text/plain;charset=utf-8',
|
|
41
43
|
};
|
|
42
44
|
|
|
43
45
|
// `strict` is the policy above; any other text is a policy as written; nothing means no header.
|
|
@@ -125,7 +125,15 @@ async function main() {
|
|
|
125
125
|
process.on('SIGTERM', quit);
|
|
126
126
|
}
|
|
127
127
|
|
|
128
|
-
|
|
129
|
-
|
|
128
|
+
// Node resolves links for import.meta.url but not for process.argv[1], so both go through realpath:
|
|
129
|
+
// compared as given, a run through a linked folder would exit 0 without doing anything.
|
|
130
|
+
const invokedDirectly = () => {
|
|
131
|
+
try {
|
|
132
|
+
return fs.realpathSync(process.argv[1]) === fs.realpathSync(fileURLToPath(import.meta.url));
|
|
133
|
+
} catch {
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
if (invokedDirectly()) {
|
|
130
138
|
main().catch((e) => { console.error(String(e?.message || e)); process.exit(1); });
|
|
131
139
|
}
|
|
@@ -542,9 +542,17 @@ function main(argv) {
|
|
|
542
542
|
return 0;
|
|
543
543
|
}
|
|
544
544
|
|
|
545
|
+
// Node resolves links for import.meta.url but not for process.argv[1], so both go through realpath:
|
|
546
|
+
// compared as given, a run through a linked folder would exit 0 without doing anything.
|
|
545
547
|
// fileURLToPath, not URL.pathname: the latter yields "/C:/..." on Windows and never matches argv[1].
|
|
546
|
-
const invoked =
|
|
547
|
-
|
|
548
|
+
const invoked = () => {
|
|
549
|
+
try {
|
|
550
|
+
return fs.realpathSync(process.argv[1]) === fs.realpathSync(fileURLToPath(import.meta.url));
|
|
551
|
+
} catch {
|
|
552
|
+
return false;
|
|
553
|
+
}
|
|
554
|
+
};
|
|
555
|
+
if (invoked()) {
|
|
548
556
|
try {
|
|
549
557
|
process.exit(main(process.argv.slice(2)));
|
|
550
558
|
} catch (err) {
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: omc-patch
|
|
3
|
-
description: "OMC 플러그인이 자동 업데이트된 뒤 사라진 훅 패치를 활성 버전에 다시 적용하고 OMC 마켓플레이스 자동 업데이트를 막음. 진단, 적용, 검증, 되돌리기. 'omc-patch'/'OMC 패치'/'OMC 업데이트 뒤 패치'/'훅 timed out'/'훅 프로세스 누적'/'PC 느려짐' 시 사용."
|
|
3
|
+
description: "OMC 플러그인이 자동 업데이트된 뒤 사라진 훅 패치를 활성 버전에 다시 적용하고 OMC 마켓플레이스 자동 업데이트를 막음. 옛 킷이 남긴 헬퍼 자리 결함(project-memory 꺼짐)도 찾아 고침. 진단, 적용, 검증, 되돌리기. 'omc-patch'/'OMC 패치'/'OMC 업데이트 뒤 패치'/'훅 timed out'/'훅 프로세스 누적'/'PC 느려짐'/'project-memory 안 됨' 시 사용."
|
|
4
4
|
argument-hint: "[check | revert]"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# omc-patch — OMC 훅 패치 재적용과 자동 업데이트 고정
|
|
8
8
|
|
|
9
9
|
OMC(oh-my-claudecode)가 새 버전으로 자동 업데이트되면 로컬 훅 패치가 사라진다. 그러면 도구 호출마다 훅 프로세스가 많이 생기고, Windows 에서는 커널 풀(paged pool)이 계속 늘어 PC 가 느려진다.
|
|
10
|
-
이 스킬은 같은 폴더의 `scripts/omc-patch.mjs` 로 패치를 다시
|
|
10
|
+
이 스킬은 같은 폴더의 `scripts/omc-patch.mjs` 로 패치를 다시 적용하고, `scripts/probe-pm.mjs` 로 훅이 실제로 일하는지 확인한다. 답변은 한글.
|
|
11
11
|
|
|
12
12
|
패치 내용은 두 가지다.
|
|
13
13
|
- 훅 스크립트 최상위의 `await import(...)` 에 10초 시간 제한을 건다. 로드가 멈춰도 훅이 끝까지 가고 프로세스가 남지 않는다.
|
|
@@ -15,6 +15,14 @@ OMC(oh-my-claudecode)가 새 버전으로 자동 업데이트되면 로컬 훅
|
|
|
15
15
|
|
|
16
16
|
추가로 OMC 마켓플레이스 저장소의 `origin` 을 `omc-pinned://<원래 URL>` 로 바꿔 자동 업데이트를 막는다.
|
|
17
17
|
|
|
18
|
+
## 헬퍼 자리 결함
|
|
19
|
+
|
|
20
|
+
- 패치는 시간 제한 헬퍼(`__omcRaceImport`)를 훅 파일에 넣는다. 이 도구는 헬퍼를 모듈 맨 앞에 넣는다.
|
|
21
|
+
- 이 스킬 밖에서 쓰던 이전 판의 패치 도구(아래 옛 킷)는 헬퍼를 첫 사용 지점 앞에 넣었다. 그 자리가 최상위 `try { }` 안이면 헬퍼도 그 블록에 갇힌다.
|
|
22
|
+
- 그러면 다른 블록의 import 가 ReferenceError 로 실패하고, 훅의 `catch` 가 그 오류를 삼킨다. 예: `project-memory-session` 은 종료 코드 0 으로 끝나지만 project-memory 를 만들지 않는다.
|
|
23
|
+
- banker 0.16.x 의 도구는 새로 패치할 때 맨 앞에 넣었지만, 옛 킷이 남긴 이 결함은 진단하지 못하고 `결과: 모두 적용된 상태입니다.` 를 냈다.
|
|
24
|
+
- 지금 도구의 `--check` 는 이 결함을 `헬퍼 자리 결함` 으로 알린다. 이미 감싼 파일이라 다시 적용만으로는 고쳐지지 않는다. 활성 폴더를 되돌린 뒤 다시 적용한다.
|
|
25
|
+
|
|
18
26
|
## 인자
|
|
19
27
|
|
|
20
28
|
| 인자 | 동작 |
|
|
@@ -26,8 +34,9 @@ OMC(oh-my-claudecode)가 새 버전으로 자동 업데이트되면 로컬 훅
|
|
|
26
34
|
## 규칙
|
|
27
35
|
|
|
28
36
|
- 이 작업은 사용자 설정 폴더(`~/.claude`)의 플러그인 캐시를 고치는 설정 변경이다. 서브에이전트에 맡기지 않고 메인 세션에서 직접 실행하고 직접 검증한다.
|
|
29
|
-
- 적용은 `--no-update` 로만 실행한다. 인자 없는 apply 는 쓰지 않는다. 활성 OMC 를 도구의 `TARGET_VERSION`(5.
|
|
30
|
-
- 도구가 출력하는 `인자 없이 다시 실행하십시오.` 문구는 따르지 않는다. 이 스킬에서는 항상 `--no-update` 를 붙인다.
|
|
37
|
+
- 적용은 `--no-update` 로만 실행한다. 인자 없는 apply 는 쓰지 않는다. 활성 OMC 를 도구의 `TARGET_VERSION`(5.7.0)으로 바꾸고, `revert` 로도 버전이 돌아오지 않는다.
|
|
38
|
+
- 도구가 출력하는 `인자 없이 다시 실행하십시오.` 문구는 따르지 않는다. 이 스킬에서는 적용과 진단에 항상 `--no-update` 를 붙인다.
|
|
39
|
+
- 헬퍼 자리 결함과 함께 나오는 `--revert 로 되돌린 뒤 다시 적용하십시오.` 도 그대로 따르지 않는다. 인자 없는 `--revert` 는 설치된 모든 버전을 되돌리고 고정까지 푼다. 이 스킬은 활성 폴더만 `--revert --root` 로 되돌린다(3단계 1).
|
|
31
40
|
- 패치 규칙은 OMC 훅 코드의 모양에 맞춰져 있다. 처음 보는 OMC 버전이면 반드시 `check` 를 먼저 실행한다.
|
|
32
41
|
- `실패 N건` 이 1건 이상이면 멈추고 출력을 그대로 보고한다. 문법 오류가 난 파일은 도구가 원본으로 자동 롤백한다.
|
|
33
42
|
- 판정은 출력 문구로 한다. 종료 코드 0 만으로 완료라고 보고하지 않는다.
|
|
@@ -37,7 +46,18 @@ OMC(oh-my-claudecode)가 새 버전으로 자동 업데이트되면 로컬 훅
|
|
|
37
46
|
|
|
38
47
|
## 절차
|
|
39
48
|
|
|
40
|
-
|
|
49
|
+
스크립트는 `<이 스킬 디렉터리 절대경로>/scripts/` 의 `omc-patch.mjs` 와 `probe-pm.mjs` 다. Node 18 이상과 `git` 이 필요하다.
|
|
50
|
+
활성 플러그인 폴더(아래 `R`, `$r`)는 명령마다 다시 구한다. 명령마다 새 셸일 수 있다.
|
|
51
|
+
|
|
52
|
+
bash:
|
|
53
|
+
```bash
|
|
54
|
+
R=$(node -e 'const j=require(require("path").join(require("os").homedir(),".claude/plugins/installed_plugins.json"));console.log(j.plugins["oh-my-claudecode@omc"][0].installPath)')
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
PowerShell:
|
|
58
|
+
```powershell
|
|
59
|
+
$r = (Get-Content "$env:USERPROFILE\.claude\plugins\installed_plugins.json" -Raw | ConvertFrom-Json).plugins.'oh-my-claudecode@omc'[0].installPath
|
|
60
|
+
```
|
|
41
61
|
|
|
42
62
|
### 1. 진단
|
|
43
63
|
|
|
@@ -48,7 +68,13 @@ node "<이 스킬 디렉터리 절대경로>/scripts/omc-patch.mjs" --check --no
|
|
|
48
68
|
- `활성 버전: X (installed_plugins.json)` 줄로 실제 활성 버전을 확인한다.
|
|
49
69
|
- 그 줄이 `(추정: ...)` 로 끝나면 도구가 `installed_plugins.json` 에서 활성 버전을 찾지 못한 것이다. 적용하지 않고 출력을 그대로 보고하고 끝낸다. 추정한 폴더를 패치하면 실제 활성 버전은 그대로 남는데 `check` 는 적용된 것으로 보일 수 있다.
|
|
50
70
|
- `패치 필요 N건` 은 설치된 모든 버전 폴더를 합친 수다. 판정은 맨 아래 `결과:` 줄로 한다.
|
|
51
|
-
|
|
71
|
+
|
|
72
|
+
| `결과:` 줄 | 다음 |
|
|
73
|
+
|---|---|
|
|
74
|
+
| `모두 적용된 상태입니다.` | 4단계 검증으로 건너뜀 |
|
|
75
|
+
| `헬퍼 자리 결함 N건이 있습니다.` | 2단계 확인 뒤 3단계에서 활성 폴더부터 되돌림 |
|
|
76
|
+
| `적용되지 않은 항목이 있습니다.` | 2단계 확인 뒤 3단계 적용 |
|
|
77
|
+
|
|
52
78
|
- `참고: 비활성 버전 ...` 은 지금 쓰지 않는 버전이라 판정에 들어가지 않는다.
|
|
53
79
|
- 인자가 `check` 이면 여기서 결과만 보고하고 끝낸다.
|
|
54
80
|
|
|
@@ -56,41 +82,64 @@ node "<이 스킬 디렉터리 절대경로>/scripts/omc-patch.mjs" --check --no
|
|
|
56
82
|
|
|
57
83
|
`--check` 결과를 보여 주고 사용자에게 적용해도 되는지 묻는다. 묻기 전에 아래를 알린다.
|
|
58
84
|
- 활성 OMC 버전의 `scripts/*.mjs` 와 `hooks/hooks.json` 을 고친다. 원본은 `.omcbak` 로 남는다.
|
|
85
|
+
- 헬퍼 자리 결함이 있으면 활성 폴더를 `.omcbak` 원본으로 먼저 되돌린 뒤 다시 패치한다.
|
|
59
86
|
- OMC 마켓플레이스 `origin` 을 `omc-pinned://` 로 바꾼다. OMC 가 더 이상 자동 업데이트되지 않는다. 되돌리기는 `revert`.
|
|
60
87
|
- 승인이 없으면 적용하지 않는다.
|
|
61
88
|
|
|
62
89
|
### 3. 적용
|
|
63
90
|
|
|
64
|
-
|
|
65
|
-
node "<이 스킬 디렉터리 절대경로>/scripts/omc-patch.mjs" --no-update
|
|
66
|
-
```
|
|
91
|
+
1. 1단계가 헬퍼 자리 결함을 냈으면 활성 폴더만 먼저 되돌린다. `--root` 는 그 폴더의 훅과 `hooks.json` 만 다룬다. 마켓플레이스 고정과 다른 버전 폴더는 건드리지 않는다.
|
|
67
92
|
|
|
68
|
-
|
|
69
|
-
-
|
|
93
|
+
```bash
|
|
94
|
+
R=$(node -e 'const j=require(require("path").join(require("os").homedir(),".claude/plugins/installed_plugins.json"));console.log(j.plugins["oh-my-claudecode@omc"][0].installPath)')
|
|
95
|
+
node "<이 스킬 디렉터리 절대경로>/scripts/omc-patch.mjs" --revert --root "$R"
|
|
96
|
+
```
|
|
70
97
|
|
|
71
|
-
|
|
98
|
+
PowerShell:
|
|
99
|
+
```powershell
|
|
100
|
+
$r = (Get-Content "$env:USERPROFILE\.claude\plugins\installed_plugins.json" -Raw | ConvertFrom-Json).plugins.'oh-my-claudecode@omc'[0].installPath
|
|
101
|
+
node "<이 스킬 디렉터리 절대경로>\scripts\omc-patch.mjs" --revert --root $r
|
|
102
|
+
```
|
|
72
103
|
|
|
73
|
-
|
|
104
|
+
- `되돌림 <훅 이름>` 줄과 `되돌리기 완료.` 를 확인한다. 끝의 `재시작해야 반영됩니다` 는 이 중간 단계에서는 무시한다. 2 에서 바로 다시 패치한다.
|
|
105
|
+
- 결함이 있던 훅 이름이 `되돌림` 줄에 없으면 그 파일에 `.omcbak` 백업이 없는 것이다. 이 도구로는 되돌릴 원본이 없으니 멈추고 보고한다. 원본은 같은 버전의 OMC 저장소에서 다시 받아야 한다. 파이프 대신 파일을 거친다(Windows PowerShell 5.1 의 파이프는 바이너리를 텍스트로 바꿔 파일을 깨뜨린다): `git -C "<마켓플레이스 폴더>" archive -o "<임시 tar>" v<버전> scripts/<이름>.mjs` 뒤 `tar -xf "<임시 tar>" -C "<활성 폴더>"`. 이 명령은 사용자 승인 뒤에만 실행한다.
|
|
106
|
+
|
|
107
|
+
2. 적용한다.
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
node "<이 스킬 디렉터리 절대경로>/scripts/omc-patch.mjs" --no-update
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
- `패치 N건 / 실패 0건`, `[3/4]` 의 PostToolUse 제거, `[4/4]` 의 고정 결과를 확인한다.
|
|
114
|
+
- 실패가 1건 이상이면 멈추고 출력 그대로 보고한다.
|
|
115
|
+
- `[!] 헬퍼 자리 결함 N건은 고치지 않았습니다.` 가 나오면 1 을 건너뛰었거나 1 이 그 파일을 되돌리지 못한 것이다. 1 과 2 를 한 번만 다시 한다. 다시 해도 같으면 멈추고 보고한다.
|
|
116
|
+
|
|
117
|
+
### 4. 검증 (다섯 가지 모두)
|
|
118
|
+
|
|
119
|
+
1. 다시 진단한다. `결과: 모두 적용된 상태입니다.` 가 나와야 하고, 활성 버전에 `헬퍼 자리 결함` 줄이 없어야 한다.
|
|
74
120
|
|
|
75
121
|
```bash
|
|
76
122
|
node "<이 스킬 디렉터리 절대경로>/scripts/omc-patch.mjs" --check --no-update
|
|
77
123
|
```
|
|
78
124
|
|
|
79
|
-
2. 패치된 훅의
|
|
125
|
+
2. 패치된 훅의 문법과 헬퍼 자리를 확인한다. `*.omcbak` 와 짝인 파일마다 `node --check` 의 종료 코드가 0 이고, `--scan` 이 낸 헬퍼 깊이가 모두 0 이면 정상이다.
|
|
80
126
|
|
|
81
127
|
bash:
|
|
82
128
|
```bash
|
|
83
129
|
R=$(node -e 'const j=require(require("path").join(require("os").homedir(),".claude/plugins/installed_plugins.json"));console.log(j.plugins["oh-my-claudecode@omc"][0].installPath)')
|
|
84
|
-
for b in "$R"/scripts/*.omcbak; do [ -e "$b" ] || continue; f="${b%.omcbak}"; node --check "$f"; rc=$?; echo "$(basename "$f") syntax=$rc"; done
|
|
130
|
+
set --; for b in "$R"/scripts/*.omcbak; do [ -e "$b" ] || continue; f="${b%.omcbak}"; node --check "$f"; rc=$?; echo "$(basename "$f") syntax=$rc"; set -- "$@" "$f"; done
|
|
131
|
+
node "<이 스킬 디렉터리 절대경로>/scripts/omc-patch.mjs" --scan "$@" | node -e 'let s="";process.stdin.on("data",(d)=>{s+=d}).on("end",()=>{for(const x of JSON.parse(s))console.log(require("path").basename(x.file),"depth="+x.helperDecls.map((d)=>d.depth).join(","))})'
|
|
85
132
|
```
|
|
86
133
|
|
|
87
134
|
PowerShell:
|
|
88
135
|
```powershell
|
|
89
136
|
$r = (Get-Content "$env:USERPROFILE\.claude\plugins\installed_plugins.json" -Raw | ConvertFrom-Json).plugins.'oh-my-claudecode@omc'[0].installPath
|
|
90
|
-
Get-ChildItem "$r\scripts\*.omcbak" | % { $
|
|
137
|
+
$f = @(Get-ChildItem "$r\scripts\*.omcbak" | % { $_.FullName -replace '\.omcbak$','' })
|
|
138
|
+
$f | % { node --check $_; "{0} syntax={1}" -f (Split-Path $_ -Leaf), $LASTEXITCODE }
|
|
139
|
+
(node "<이 스킬 디렉터리 절대경로>\scripts\omc-patch.mjs" --scan @f | ConvertFrom-Json) | % { "{0} depth={1}" -f (Split-Path $_.file -Leaf), (@($_.helperDecls | % depth) -join ',') }
|
|
91
140
|
```
|
|
92
141
|
|
|
93
|
-
3. 패치된 훅 하나를 플러그인의 `scripts/run.cjs` 로 실제 실행한다.
|
|
142
|
+
3. 패치된 훅 하나를 플러그인의 `scripts/run.cjs` 로 실제 실행한다.
|
|
94
143
|
`OMC_NOTIFY=0` 은 이 시험 실행이 사용자의 알림 채널로 `session-idle` 알림을 보내지 않게 한다.
|
|
95
144
|
|
|
96
145
|
bash:
|
|
@@ -109,7 +158,29 @@ node "<이 스킬 디렉터리 절대경로>/scripts/omc-patch.mjs" --no-update
|
|
|
109
158
|
|
|
110
159
|
`{"continue":true,...}` 형태의 출력과 종료 코드 0 이면 정상. 훅 이름이 없으면 `*.omcbak` 와 짝인 다른 훅으로 바꾼다.
|
|
111
160
|
|
|
112
|
-
4.
|
|
161
|
+
4. project-memory 훅이 실제로 일하는지 확인한다. 이 확인은 임시 폴더의 스크래치 프로젝트에서 훅을 돌린다. 홈, 설정 폴더, 상태 폴더도 그 안을 가리키게 하고 끝나면 지운다. 사용자의 `~/.claude` 와 작업 폴더의 `.omc` 는 건드리지 않는다.
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
R=$(node -e 'const j=require(require("path").join(require("os").homedir(),".claude/plugins/installed_plugins.json"));console.log(j.plugins["oh-my-claudecode@omc"][0].installPath)')
|
|
165
|
+
node "<이 스킬 디렉터리 절대경로>/scripts/probe-pm.mjs" --plugin "$R"
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
PowerShell:
|
|
169
|
+
```powershell
|
|
170
|
+
$r = (Get-Content "$env:USERPROFILE\.claude\plugins\installed_plugins.json" -Raw | ConvertFrom-Json).plugins.'oh-my-claudecode@omc'[0].installPath
|
|
171
|
+
node "<이 스킬 디렉터리 절대경로>\scripts\probe-pm.mjs" --plugin $r
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
| 결과 | 뜻과 다음 |
|
|
175
|
+
|---|---|
|
|
176
|
+
| `PROBE GREEN` | 정상 |
|
|
177
|
+
| `PROBE RED: no project-memory.json` | 훅이 돌았지만 아무 일도 안 했다. 1단계나 4.1, 4.2 가 헬퍼 자리 결함을 보였고 2단계 승인이 있으면 3단계를 한 번만 다시 한다. 결함이 보이지 않거나 다시 해도 RED 면 출력을 그대로 보고하고 멈춘다. 느린 PC 에서 import 가 10초 제한에 걸린 경우처럼 원인이 다를 수 있다 |
|
|
178
|
+
| 그 밖의 `PROBE RED` | 출력을 그대로 보고하고 멈춘다 |
|
|
179
|
+
| 종료 코드 2 와 `훅 스크립트가 없습니다` 줄 | 그 버전에 project-memory 훅이 없다. 해당 없음으로 적는다 |
|
|
180
|
+
| 그 밖의 `probe-pm:` 줄(종료 코드 2) | 명령 오류다. 경로를 다시 구해 한 번만 다시 실행한다. 같으면 출력을 보고하고 멈춘다 |
|
|
181
|
+
| 판정 줄 뒤의 `probe-pm: 임시 폴더를 지우지 못함` | 판정은 그대로 쓴다. 남은 임시 폴더 경로를 보고에 적어 사용자가 지우게 한다 |
|
|
182
|
+
|
|
183
|
+
5. 마켓플레이스 고정을 확인한다. `omc-pinned://` 로 시작하면 고정된 것이다.
|
|
113
184
|
|
|
114
185
|
```bash
|
|
115
186
|
git -C "$HOME/.claude/plugins/marketplaces/omc" remote get-url origin
|
|
@@ -119,10 +190,11 @@ node "<이 스킬 디렉터리 절대경로>/scripts/omc-patch.mjs" --no-update
|
|
|
119
190
|
|
|
120
191
|
### 5. 보고
|
|
121
192
|
|
|
122
|
-
- 활성 버전, 패치 건수, PostToolUse 제거 목록, 고정
|
|
193
|
+
- 활성 버전, 패치 건수, 헬퍼 자리 결함 처리 여부, PostToolUse 제거 목록, 고정 상태, project-memory 확인 결과
|
|
123
194
|
- 훅 스크립트 패치는 바로 적용된다. 훅이 호출될 때마다 파일을 새로 읽기 때문이다.
|
|
124
195
|
- PostToolUse 제거는 `hooks.json` 변경이라 각 세션을 다시 시작해야 적용된다.
|
|
125
196
|
- Windows 에서 이미 쌓인 커널 풀은 재부팅으로만 회수된다. 재부팅은 사용자가 직접 한다.
|
|
197
|
+
- Windows 에서 효과를 재려면 부하가 비슷한 24시간끼리 커널 풀 증가량을 비교한다. 유휴 시간에 늘지 않은 것은 증거가 아니다.
|
|
126
198
|
|
|
127
199
|
## 되돌리기 (인자 `revert`)
|
|
128
200
|
|
|
@@ -130,14 +202,17 @@ node "<이 스킬 디렉터리 절대경로>/scripts/omc-patch.mjs" --no-update
|
|
|
130
202
|
node "<이 스킬 디렉터리 절대경로>/scripts/omc-patch.mjs" --revert
|
|
131
203
|
```
|
|
132
204
|
|
|
133
|
-
- `.omcbak` 백업으로 훅 스크립트와 `hooks.json` 을 되돌리고 마켓플레이스 `origin` 을 원래 URL 로 복구한다.
|
|
205
|
+
- `.omcbak` 백업으로 설치된 모든 버전의 훅 스크립트와 `hooks.json` 을 되돌리고 마켓플레이스 `origin` 을 원래 URL 로 복구한다.
|
|
134
206
|
- 되돌린 뒤 Claude Code 를 다시 시작해야 반영된다.
|
|
135
207
|
- `이 도구가 만들지 않은 수정이 남아 있습니다` 가 나오면 백업이 없는 손 수정이다. 출력에 적힌 복구 명령을 그대로 보고하고, 사용자 승인 없이 실행하지 않는다.
|
|
136
208
|
|
|
137
209
|
## 함정
|
|
138
210
|
|
|
139
|
-
- 도구의 `TARGET_VERSION`(5.
|
|
211
|
+
- 도구의 `TARGET_VERSION`(5.7.0)은 소스에 고정돼 있다. 인자 없는 apply 만 이 값을 쓰고, 이 스킬은 그 apply 를 쓰지 않는다.
|
|
140
212
|
- OMC 가 훅 코드 구조를 바꾸면 패치 대상이 0건으로 나오거나 변환이 실패할 수 있다. 이때 `실패 N건` 과 `변환 실패` 를 그대로 보고한다.
|
|
213
|
+
- 헬퍼 자리 결함이 남은 채 `revert` 없이 적용을 다시 돌려도 바뀌는 것이 없다. 이미 감싼 파일은 건너뛰기 때문이다.
|
|
214
|
+
- `--root` 와 `--revert --root` 는 그 폴더만 다룬다. 고정 해제까지 하려면 인자 없는 `--revert` 를 쓴다.
|
|
141
215
|
- 고정을 풀지 않고 OMC 를 올리려면 먼저 `revert` 한다. 그렇지 않으면 마켓플레이스 fetch 가 계속 실패한다.
|
|
142
216
|
- 고정 기록(`PINNED`)은 `~/.claude/omc-local-patches/PINNED` 에 생긴다. 기록일 뿐이라 지워도 고정은 풀리지 않고, 이미 고정된 상태에서는 다시 만들어지지 않는다. `revert` 는 origin 값에서 원래 URL 을 되찾는다.
|
|
217
|
+
- `--scan` 은 읽기만 한다. 플러그인 캐시도 `installed_plugins.json` 도 읽지 않고 준 파일만 본다.
|
|
143
218
|
- 도구의 주석과 출력 문구는 한글이다.
|