@kaydash9999/banker-plugins 0.18.0 → 0.19.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.
@@ -6,7 +6,7 @@
6
6
  },
7
7
  "metadata": {
8
8
  "description": "Claude Code skills + commands — QA, audit, docs, architecture, dependency setup, and wiki; the banker plugin marketplace.",
9
- "version": "0.18.0"
9
+ "version": "0.19.0"
10
10
  },
11
11
  "plugins": [
12
12
  {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "banker",
3
- "version": "0.18.0",
3
+ "version": "0.19.0",
4
4
  "description": "Claude Code plugin: QA/audit/docs/architecture skills + commands, a /banker:setup installer for OS dependencies (playwright, etc.), and wiki compaction.",
5
5
  "author": {
6
6
  "name": "smallOpenSource",
package/CHANGELOG.md CHANGED
@@ -1,5 +1,57 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.19.0] - 2026-10-15
4
+
5
+ npm 에는 0.18.1 을 게시하지 않았다. npm 에서는 이 판이 0.18.0 다음이며, 아래 [0.18.1] 의 변경도 함께 담는다.
6
+
7
+ ### Added
8
+ - `theme-selection`: 프로젝트에 테마 74종을 라이트와 다크 한 쌍씩(148 조합) CSS 사용자 지정 속성으로 입힌다. 대비 보정을 거친 값을 내고, 테마 고르개(마크업과 스크립트 둘)와 대비 감사(`check`)도 낸다. 프로젝트의 DESIGN.md 를 읽어 테마로 더하거나 같은 이름의 번들 테마를 덮는다. Node 만 쓰고 인터넷을 쓰지 않는다.
9
+ - `theme-selection`: 번들 팔레트는 VoltAgent/awesome-design-md(MIT)의 DESIGN.md 에서 색 값을 읽어 만들었다. 원본 라이선스와 출처 고지는 `assets/LICENSE`, `assets/NOTICE.md` 에 있다. 테마 이름의 상표는 각 소유자의 것이다.
10
+
11
+ ### Changed
12
+ - README: 첫 부분을 □ 개조식으로 정리했다. Codex 설명은 실제 동작에 맞췄다. 스킬과 커맨드는 Codex CLI 에 모두 설치되고, 도구 의존성이 있는 스킬은 실행할 때 그 도구가 필요하다.
13
+ - 유지보수자용: smoke 시험이 스킬 63개와 `theme-selection` 의 Codex 설치본(스크립트, 팔레트, 고지 파일)을 보고, 설치본을 한 번 실행한다. CI 의 manifest 개수 단언을 63 으로 고쳤다. 0.18.0 부터 61 로 남아 있었다.
14
+
15
+ ## [0.18.1] - 2026-10-15
16
+
17
+ ### Fixed
18
+ - `omc-patch`: 모르는 인자를 받지 않는다. 예전에는 말없이 넘겨 `--dry-run` 을 줘도 실제로 적용했고, `--root=<폴더>` 꼴은 `--root` 가 무시돼 `--revert` 가 모든 판을 되돌리고 고정까지 풀었다. 이제 아는 인자 밖이면 아무것도 읽거나 쓰지 않고 사용법과 함께 종료 1 로 멈춘다. `--help` 는 사용법을 낸다.
19
+ - `omc-patch`: 출력 정화를 유니코드 속성 기준으로 넓혔다. 단어 결합자, 태그 문자(보이지 않는 ASCII), 빈 글자(U+3164 등), 점자 빈칸, ASCII 밖 공백을 `?` 로 바꾼다. `--root` 이름표 출력도 정화한다. 출력하는 경로(`--root` 폴더, 마켓플레이스, 캐시), 판 이름, 문법 오류 줄도 정화한다.
20
+ - `omc-patch`: 새 임시 파일과 rename 으로 쓴다. 하드 링크로 이어진 폴더 밖 파일이 바뀌지 않고, 백업은 이미 있으면 실패하는 복사로 만들어 확인과 복사 사이에 바뀌지 않는다. Windows 에서 잠시 거부된 rename 은 다시 한다. 쓰지 못한 파일(installed_plugins.json, PINNED 포함)은 이름을 대고 실패로 센다. 예전에는 예외로 멈췄다.
21
+ - `omc-patch`: origin 의 인증 정보를 출력에서 `***` 로 가린다(사용자 정보의 공백, 탭, 비밀번호 안의 `@`, 쿼리의 토큰 포함). PINNED 에 URL 을 남기지 않고 이 계정만 읽게 한다(0600). 옛 판이 남긴 PINNED 의 URL 칸은 `--check` 가 알리고(모두 적용된 상태로 보지 않음) 다음 적용 때 지운다. 지우지 못하면(기록이 링크, JSON 이 아님, 쓰기 실패, 읽지 못함) `[!]` 로 그 경로를 알리고 실패로 센다. 링크는 따라가 쓰지 않는다.
22
+ - `omc-patch`: origin 을 설정 값 그대로 읽는다. 전역 `insteadOf` 가 펼친 URL 이 고정되거나 되돌린 뒤 남지 않고, `-` 로 시작하는 origin 도 옵션으로 읽지 않는다.
23
+ - `omc-patch`: 실행 폴더를 정하지 않던 git, tar 호출을 홈 폴더에서 실행한다. Windows 에서 현재 폴더(프로젝트 폴더)의 `git.exe` 가 먼저 실행되지 않는다. 마켓플레이스 저장소를 다루는 git 은 그 폴더에서 실행한다.
24
+ - `omc-patch`: 고친 hooks.json 이 다시 읽어 JSON 이 아니면 원본으로 되돌리는데, 이 되돌림을 실패로 센다. 예전에는 `완료. 실패 0건.` 과 종료 0 이었다.
25
+ - `omc-patch`: 되돌리기가 PINNED 를 지우지 못하면(읽기 전용 폴더, 폴더인 PINNED) `[!]` 로 알리고 실패로 센다. origin 은 그대로 되돌린다. 예전에는 스택 트레이스로 멈춰 origin 이 고정된 채 남았다. 링크인 PINNED 너머에 옛 URL 칸이 있으면 링크를 두고 알리고 실패로 센다. 예전에는 링크만 지우고 `되돌리기 완료.` 로 끝났다.
26
+ - `omc-patch`: origin 을 바꾸지 못하면 git 의 원인 줄(`fatal:`, `error:`)과 함께 `[!]` 로 알리고 종료 1 이다. 예전에는 되돌리기가 성공이라고 했고, 고정은 기록만 남기고 예외로 멈췄다.
27
+ - `omc-patch`: 손 수정 판정이 실제 손 패치 모양(최상위의 `await Promise.race([import(`)만 본다.
28
+ - `tone-compact`, `anti-drm`: 지침 파일 자리(AGENTS.md, AGENTS.override.md, 규칙 파일)에 폴더, FIFO, 소켓, 링크 고리가 있으면 읽지 않는다. 예전에는 FIFO 에서 `status` 와 `off` 가 멈췄고, 폴더와 소켓, 링크 고리에서는 종료 2 로 끝났다. 이제 `on`, `off` 는 거부(종료 1)하고 `status` 는 그 사실과 그 파일의 경로를 보인다.
29
+ - `tone-compact`, `anti-drm`: UTF-8 이 아닌 파일이나 표시 짝이 맞지 않는 파일이 있으면 `status` 가 그 파일의 경로를 보인다. 예전에는 블록이 들어갈 파일을 보였다.
30
+ - `tone-compact`, `anti-drm`: AGENTS.override.md 가 AGENTS.md 의 링크나 하드 링크면 한 파일로 다룬다. 예전에는 `on` 을 할 때마다 블록이 들어갔다 빠졌다 했다. 같은 파일인지는 실제 경로나 inode 로 보고, inode 번호 0 은 믿지 않는다.
31
+ - `tone-compact`, `anti-drm`: AGENTS.md 가 끊어진 링크면 `on` 이 거부한다. 예전에는 링크를 따라 대상 자리에 파일을 만들었다.
32
+ - `tone-compact`, `anti-drm`: 두 스킬의 `on`, `off` 가 동시에 돌아도 블록이 사라지지 않는다. Codex 폴더의 잠금 파일(`.banker-agents.lock`)로 차례를 지키고, 1분 넘은 잠금은 넘어간다. 죽은 실행이 남긴 잠금을 두 실행이 같은 순간에 넘기는 드문 경우는 보장하지 못한다.
33
+ - `tone-compact`, `anti-drm`: 메시지의 경로에서 빈 글자(U+3164 등), 점자 빈칸, ASCII 밖 공백도 `?` 로 바꾼다.
34
+ - `anti-drm`: 설정 파일의 TSV 구분자도 대소문자를 가리지 않는다(`"Tab"`). 채운 규칙에 `{{` 가 남으면 오류로 멈춘다.
35
+ - `lineage` 3.0.5: 공백이나 보이지 않는 글자(BOM, 폭 없는 공백, 한글 채움 문자, 점자 빈칸, 제어 문자 등)만 든 요약 캐시는 읽지 못한 것으로 보고 다시 요약한다.
36
+ - `scripts/gen-skill-changes.js`(유지보수자용): npm 묶음에 들어가지 않는 파일(시험, `__pycache__`, `.omc`)만 바뀐 스킬은 바뀐 스킬로 세지 않는다.
37
+ - `/progress`: 늦게 끝난 TaskList, TaskGet 이 그 결과에만 있는 작업을 버리지 않는다. 겹친 조회와 상태 갱신은 나중에 시작한 것이 남고, 삭제보다 먼저 시작한 조회나 갱신은 지운 작업을 되살리지 않는다.
38
+ - `/progress`: 알림 턴이 대답 없이 끝나면(중단, 거절, 오류) 단계 아래에 그 사실을 보인다.
39
+ - `/progress`: Claude Code 2.1.289 아래 판에서는 즉시 실행 없이 일반 명령으로 등록한다.
40
+ - `/progress`, `/graceful-pause`: 하위 에이전트, 포크, 팀원의 턴 시작을 단계나 주 턴으로 보지 않는다. Claude Code 2.1.300 은 그 턴에도 `turn.start` 를 보내, 예전에는 포크의 지시문이 단계로 생겨 다음 요청 전까지 진행 중으로 남았고 `/graceful-pause` 는 포크를 멈출 턴으로 잘못 기억했다.
41
+ - `/progress`: 진행 중인 단계가 바뀌거나 패널을 다시 열면 패널 창을 그 행으로 옮긴다. 예전에는 긴 목록에서 진행 단계가 창 밖에 남았다.
42
+
43
+ ### Changed
44
+ - `anti-drm`: 설정 값을 표준 입력(`--stdin`, 줄마다 `deny=`, `alt=`, `tsv=`)으로 받는다. 스킬은 따옴표 친 heredoc 으로 넘겨 사용자가 고른 값이 셸을 거치지 않고, 넘기기 전에 heredoc 줄마다 꼴을 확인한다. 입력은 64KiB 를 넘는 순간 읽기를 멈추고, 설정 줄이 없으면 `on` 과 `config` 모두 거부하며, 값 앞뒤 공백은 지운다. `--deny`, `--alt`, `--tsv` 도 그대로 받는다.
45
+ - `tone-compact`, `anti-drm`: 문제 해결 표가 사용자 파일을 치우거나 지우라고 하지 않는다. 무엇인지 보이고 물은 뒤 다시 실행한다.
46
+ - `tone-compact`, `anti-drm`: Codex `off` 결과에 지우기 전 파일(`<파일>.<스킬>.bak`)을 알린다. 다른 banker 블록 때문에 Codex 가 AGENTS.md 를 읽지 않으면 `on` 의 첫 문장이 그렇다고 말한다.
47
+ - `update-banker`: Claude Code 가 캐시의 옛 판을 지우는 규칙을 확인된 사실로 적었다(`.orphaned_at` 뒤 14일, 그 판을 쓰는 세션 없음, 링크 판 제외).
48
+ - `omc-patch`: `--check` 가 쓸 수 없는 훅과 hooks.json 을 미리 알린다. JSON 이 아닌 hooks.json 은 `읽지 못함` 으로 알리고 모두 적용됐다고 하지 않는다. 폴더 밖 링크 때문에 되돌리지 못한 파일은 손 복구 방법을 안내한다.
49
+ - `omc-patch`: 파일을 새 임시 파일과 rename 으로 바꾸므로, 폴더는 쓸 수 없고 파일만 쓸 수 있는 곳에서는 `쓰지 못함: EACCES` 로 알리고 실패로 센다. 예전에는 파일 자리에 그대로 썼다.
50
+ - `omc-patch`: 지울 git 변수에 이 PC 의 `git rev-parse --local-env-vars` 결과를 더한다. 업데이트 경로의 fetch 는 환경 변수로 준 git 설정 가운데 프록시와 TLS 신뢰 설정(`http.proxy`, `http.sslCAInfo`, `http.sslVerify`, `http.proxyAuthMethod`)만 쓴다. `url.*.insteadOf`, `core.hooksPath` 같은 나머지는 예전처럼 지운다.
51
+ - smoke 시험: banker 작업 파일 검사가 대소문자를 가리지 않고 `skills/`, `commands/` 의 모든 글 파일을 본다.
52
+ - `/progress`: 위치와 상관없이 `prd.json` 과 `ultragoal/goals.json` 을 PRD 나 목표 모양일 때 계획으로 본다. 검토 문서 이름(`-critic`, `-review` 등)의 파일은 다른 계획이 없을 때만 계획으로 보인다.
53
+ - 유지보수자용: npm pack 대조 시험과 smoke 시험의 npm 이 레지스트리에 접속하지 않는다. smoke 의 DRM 이름 검사가 긴 줄에서도 선형 시간이다. `scripts/gen-skill-changes.js`, `hooks/obsidize-hook.mjs`, `hooks/update-checkin.mjs` 의 main 을 함수 규칙(복잡도 10) 안으로 나눴다(동작 그대로).
54
+
3
55
  ## [0.18.0] - 2026-10-14
4
56
 
5
57
  ### Added
package/README.md CHANGED
@@ -8,11 +8,18 @@
8
8
 
9
9
  [빠른 시작](#빠른-시작) · [워크플로 예시](#워크플로-사용-예시) · [구성](#구성) · [설치 상세](#설치-상세-npm--codex) · [설정 변경 지점](#설정-변경-지점-claude-code--codex) · [요구사항](#요구사항) · [업데이트 / 제거](#업데이트--제거) · [업데이트 확인](#업데이트-확인-및-사용량-카운팅) · [라이선스 / 서드파티](#라이선스--서드파티)
10
10
 
11
- banker는 QA·보안 감사·문서·아키텍처·위키·미디어 작업과 의존성·개발환경(OS별) 설치를 아우르는 **스킬 62개 + 커맨드 2개**(총 64개 구성요소)와 Claude Code 즉시 명령 `/graceful-pause`, `/progress` 를 묶은 Claude Code 플러그인입니다.\
12
- 설치하면 스킬과 커맨드가 `/banker:<이름>` 네임스페이스로 노출됩니다.\
13
- 이 저장소 자체가 Claude Code 마켓플레이스(`.claude-plugin/marketplace.json`)이자 플러그인(`.claude-plugin/plugin.json`, name `banker`)이며, 도구에 무관한 스킬은 Codex CLI에도 설치됩니다.
11
+ □ banker는 다음을 포함하는 Claude Code 및 Codex CLI 플러그인입니다.
12
+ - QA·보안 감사·문서·아키텍처·위키·미디어 작업과 의존성·개발환경(OS별) 설치를 아우르는 **스킬 63개 + 커맨드 2개**(총 65개 구성요소)
13
+ - Claude Code 즉시 명령 `/graceful-pause`, `/progress`
14
14
 
15
- > npm 패키지(`@kaydash9999/banker-plugins`)와 GitHub 저장소(`smallOpenSource/banker_plugins`)는 같은 메인테이너가 관리합니다.
15
+ □ 설치하면 스킬과 커맨드가 `/banker:<이름>` 네임스페이스로 노출됩니다.
16
+
17
+ □ 이 저장소 자체가 Claude Code 마켓플레이스(`.claude-plugin/marketplace.json`)이자,\
18
+ 플러그인(`.claude-plugin/plugin.json`, name `banker`)이며,\
19
+ 스킬과 커맨드는 Codex CLI에도 모두 구성됩니다.\
20
+ 도구 의존성이 있는 스킬은 실행할 때 그 도구가 필요합니다.
21
+
22
+ > npm 패키지(`@kaydash9999/banker-plugins`)와 GitHub 저장소(`smallOpenSource/banker_plugins`)는 같은 메인테이너가 관리
16
23
 
17
24
  ## 빠른 시작
18
25
 
@@ -102,6 +109,7 @@ Claude Code 2.1.296 은 Claude 5 모델(Opus 5.5 등)에 작업 목록 도구(Ta
102
109
  | `make-notion-guide` | API 호출 가이드를 노션 양식 문서로 작성 |
103
110
  | `pdf-vision-extract` | 비주얼 PDF를 고해상도 PNG로 변환(비전 입력) |
104
111
  | `nothing-design` | Nothing 스타일 UI 디자인 적용 |
112
+ | `theme-selection` | 테마 74종을 라이트와 다크 CSS 변수로 입힘(대비 보정 포함). 테마 고르개와 대비 감사도 냄 |
105
113
  | `rfp-author` | 외주 제안요청서(RFP) 저작 (범용 프레임워크) |
106
114
  | `humanizer` | AI 글 흔적 제거(자연스러운 문체로 윤문) |
107
115
  | `lineage` | 세션 대화를 카카오톡 스타일 단일 HTML로 export. 세션 모델이 턴마다 1줄 요약을 쓰고 남길 턴을 고름(`--rulebase` 는 규칙만), 마크다운 렌더, 다중 세션 병합 |
@@ -197,7 +205,7 @@ banker uninstall # 제거
197
205
 
198
206
  - `--scope project` 로 프로젝트 로컬(`./.codex`)에 설치하고, `--dry-run` 으로 미리 볼 수 있습니다.
199
207
  - non-root 전용입니다(전역 sudo 설치 시 root 소유 파일을 방지). postinstall이 없으므로 `banker setup` 을 직접 실행합니다.
200
- - Codex에는 스킬 62개가 `~/.codex/skills/banker-<name>/` 에, 커맨드 2개가 `~/.codex/prompts/banker-<name>.md` 에 설치됩니다(`codex/manifest.json`). \
208
+ - Codex에는 스킬 63개가 `~/.codex/skills/banker-<name>/` 에, 커맨드 2개가 `~/.codex/prompts/banker-<name>.md` 에 설치됩니다(`codex/manifest.json`). \
201
209
  디렉터리명과 일치하도록 프론트매터 `name:` 이 `banker-<name>` 으로 재작성되어 Codex가 `banker-<name>` 으로 인식합니다.
202
210
  - OMC/Claude 에 결합됐던 오케스트레이터·설치·유틸 표면(all-in-one·ultra-chain·ultra-init·front-qa·setup·setup-omc·setup-omc-hud·setup-stitch·omc-reference·compact-copy)은 본문이 **런타임 인식**이라 Codex에서도 동작합니다.
203
211
  - `payload-mon` 은 Codex에서 실행해도 같은 머신의 Claude Code HUD 래퍼만 켜고 끕니다. \
@@ -352,14 +360,17 @@ Codex CLI는 샌드박스가 네트워크를 차단하므로 알림·카운팅
352
360
 
353
361
  banker 자체는 **MIT** ([LICENSE](LICENSE)). Owner: [smallOpenSource](https://github.com/smallOpenSource).
354
362
 
355
- **번들된 코드 (이 패키지가 재배포)**
363
+ **번들된 코드와 데이터 (이 패키지가 재배포)**
356
364
  - `skills/humanizer`: [blader/humanizer](https://github.com/blader/humanizer) 기반, **MIT License**(© 2025 Siqi Chen).\
357
365
  원본 라이선스 고지는 `skills/humanizer/LICENSE` 에 포함.\
358
366
  패턴 목록은 Wikipedia [*Signs of AI writing*](https://en.wikipedia.org/wiki/Wikipedia:Signs_of_AI_writing)(WikiProject AI Cleanup, **CC BY-SA**)에 기반합니다.
359
367
  - `skills/3d-intro-build/references`: [oso95/scroll-world](https://github.com/oso95/scroll-world) 의 스크럽 엔진(`scrub-engine.js`·`index-template.html`)을 그대로 벤더링, **MIT License**(© 2026 cyw).\
360
368
  원본 라이선스 고지는 `skills/3d-intro-build/references/LICENSE` 와 `NOTICE.md` 에 포함.
369
+ - `skills/theme-selection/assets`: 번들 팔레트(`palettes.json`)는 [VoltAgent/awesome-design-md](https://github.com/VoltAgent/awesome-design-md) 의 DESIGN.md 에서 색 값을 읽어 만든 것, **MIT License**(© 2026 VoltAgent).\
370
+ 원본 라이선스 고지는 `skills/theme-selection/assets/LICENSE` 와 `NOTICE.md` 에 포함.\
371
+ 테마 이름의 상표는 각 소유자에게 있으며, banker 는 그 회사들과 관계가 없습니다.
361
372
 
362
- 코드로 포함(재배포)하는 서드파티는 `humanizer` 와 `scroll-world`(`3d-intro-build`) 둘입니다.\
373
+ 코드로 포함(재배포)하는 서드파티는 `humanizer` 와 `scroll-world`(`3d-intro-build`) 둘이고, 데이터로 포함하는 것은 `awesome-design-md`(`theme-selection`) 하나입니다.\
363
374
  아래는 스킬이 **런타임에 의존하거나 연동**하는 외부 요소로, banker 가 재배포하지 않으며 각 라이선스·상표는 소유자에게 있습니다.
364
375
 
365
376
  **의존 라이브러리·도구 (사용 시 별도 설치, 라이선스는 각 프로젝트 소유)**
@@ -71,6 +71,7 @@
71
71
  { "name": "trouble-shooting", "type": "skill", "target": "both", "reason": "investigates a problem and reports symptom, problem, cause, fix and action plan in one table, one row per problem; --no-plan stops at the fix; report only, never fixes", "supportingFiles": [] },
72
72
  { "name": "ultra-chain", "type": "skill", "target": "both", "reason": "orchestrates nine stages in order: deep-research, ultra-interview, ralplan --deliberate followed by a ralph-qa plan quorum of 3+ reviewers (ralplan has two reviewers and no way to add more), a mock the user approves, ralph --critic=critic (Codex: OMX ralph plus a critic loop, since OMX ralph has no --critic), tests on the registered OS boxes fed to a ralph-qa quorum, visual review (machine diff against the mock, screenshots, an independent verdict), a process report rendered from its own ledger, and local sharing; Claude=OMC 5, Codex=OMX; body runtime-aware; pure Node helpers, no deps", "supportingFiles": ["references/chain-ledger.mjs", "references/chain-report.mjs", "references/capture.mjs", "references/serve.mjs", "references/preview-lib.mjs"], "caveat": "uses the sibling banker skills deep-research, ultra-interview, ralph-qa and remains (boxes.mjs); box runs need ssh, scp and git with key-only logins in ~/.config/banker/test-boxes.json; screenshots need Playwright with Chromium; serve.mjs and preview-lib.mjs are byte-identical copies of 3d-intro-build's (scripts/sync-adapter.js); never pushes, opens a PR or posts outside without an explicit request" },
73
73
  { "name": "anti-drm", "type": "skill", "target": "both", "reason": "turns on or off rules that steer the agent away from the file extensions a network-separated PC's DRM encrypts (default .txt .pdf .ppt .pptx .doc .docx .hwp .hwpx .xls .xlsx .csv) toward replacements (.md .html .tsv); asks the extensions on first use and keeps them in ~/.config/banker/anti-drm.json; pure Node, no deps", "supportingFiles": ["scripts/anti-drm.mjs", "scripts/instruction-toggle.mjs"], "caveat": "the same places as tone-compact (shared module instruction-toggle.mjs): Claude Code gets <config>/rules/banker-anti-drm.md; Codex gets one marked block wrapped in USER:OMX:POLICY at the end of AGENTS.md, or AGENTS.override.md when it has content of its own. The settings are shared by both runtimes; on and off act on one runtime, while config and on with settings refresh every runtime that holds the rules. It never decrypts or converts files DRM already protects; it only picks the extensions of files the agent newly creates. The organization's security rules come first" },
74
+ { "name": "theme-selection", "type": "skill", "target": "both", "reason": "applies 74 themes to a project as CSS custom properties, light and dark (148 combinations), with contrast correction; also emits a theme picker (markup and two scripts) and a contrast audit (check), and reads the project's DESIGN.md as more themes; pure Node, no deps, no network", "supportingFiles": ["scripts/themes.mjs", "assets/palettes.json", "assets/LICENSE", "assets/NOTICE.md", "references/integrate.md", "references/contrast.md"], "caveat": "the bundled palettes derive from VoltAgent/awesome-design-md (MIT; LICENSE and NOTICE.md in assets/); theme names only point at the sites the designs reference, and the trademarks belong to their owners; --out overwrites the file it names (refused when that file itself is a symbolic link), so the skill asks first when that file exists" },
74
75
 
75
76
  { "name": "front-qa", "type": "command", "target": "both", "reason": "ralplan->ralph frontend-QA pipeline; Claude=OMC, Codex=OMX", "supportingFiles": [] },
76
77
  { "name": "setup", "type": "command", "target": "both", "reason": "installer orchestrator; Claude AskUserQuestion multi-select, Codex prompt-based selection", "supportingFiles": [] }
@@ -47,6 +47,7 @@ The generator (`banker setup --codex`) applies the rules below for `target: both
47
47
  - `omc-patch` — acts on the Claude Code OMC plugin cache (`~/.claude/plugins/`) even when run from Codex; Codex's own OMX is untouched. The skill always passes `--no-update` (a plain apply would switch the active OMC to the tool's hard-coded `TARGET_VERSION`). `--revert --root` restores only the active plugin folder when an older kit left the timeout helper inside a block, and `scripts/probe-pm.mjs` runs OMC's project-memory hook in a temp scratch project with its own home and state folder.
48
48
  - `remains` — the same procedure in both runtimes; box runs go through `scripts/boxes.mjs` (Codex: `~/.codex/skills/banker-remains/scripts/boxes.mjs`), which needs `ssh`, `scp` and `git` on the machine and key-only logins to the boxes in `~/.config/banker/test-boxes.json`. It reads and runs tests only: no fix, no commit, no push.
49
49
  - `ultra-chain` — the same nine stages in both runtimes. Claude=OMC 5 (`ralplan --deliberate`, `ralph --critic=critic`); Codex=OMX (`$ralplan --deliberate`, then `$ralph` with the skill's own critic loop through `spawn_agent`, because OMX `ralph` has no `--critic`). Both add a `ralph-qa` plan quorum after ralplan (two reviewers, no option to add more), run OS tests through the sibling `remains/scripts/boxes.mjs` (Codex: `banker-remains`), judge screenshots with a fresh agent (OMX 0.20.2's `visual-verdict` is a deprecated stub), and render the process report from the skill's own ledger (`lineage` reads Claude Code sessions only). Box runs need `ssh`, `scp` and `git`; screenshots need Playwright with Chromium; under Codex's `workspace-write` sandbox the ssh calls and the review seats' home writes may ask for approval.
50
+ - `theme-selection` — the same procedure in both runtimes; the engine is `scripts/themes.mjs` (Codex: `~/.codex/skills/banker-theme-selection/scripts/themes.mjs`), which reads `assets/palettes.json` beside it. Pure Node with no network; it writes only the file `--out` names (refused when that file itself is a symbolic link), and the skill asks before it overwrites one that exists.
50
51
  - `/graceful-pause` (not a manifest surface) — a Claude Code function-hooks command (`hooks/register.mjs`, 2.1.289+) registered `immediate`, so it runs mid-turn; it appends one hidden user row the running turn reads at its next model request. Codex has no equivalent (no function hooks), and the earlier `graceful_pause` skill was removed because a typed skill waits until the turn ends.
51
52
 
52
53
  신규 스킬(0.7.0)도 `both`·런타임 인식:
@@ -124,8 +124,9 @@ const fresh = () => ({ main: null, step: -1, pending: null, background: 0, queue
124
124
  const listed = (v) => (Array.isArray(v) ? v.length : 0);
125
125
  const backgroundCount = (e) => listed(e.background_tasks) + listed(e.session_crons);
126
126
 
127
- // The main turn in flight and its latest model request; subagent loops raise no turn.start and
128
- // end with an agentId. `queued`: a report prompt not started yet. One per loaded module.
127
+ // The main turn in flight and its latest model request; a subagent's, a fork's or a teammate's loop starts
128
+ // and ends with an agentId (Claude Code 2.1.300 raises turn.start for them too) and is not the main turn.
129
+ // `queued`: a report prompt not started yet. One per loaded module.
129
130
  const state = fresh();
130
131
 
131
132
  // The command and the events only this feature hooks. register.mjs hooks the events every banker
@@ -167,6 +168,7 @@ export function pauseReset() {
167
168
  }
168
169
 
169
170
  export function pauseTurnStarted(e) {
171
+ if (e.agentId) return;
170
172
  Object.assign(state, { main: e.turnId, step: -1, queued: false });
171
173
  }
172
174
 
@@ -103,43 +103,53 @@ function resolvePages(wikiDir, toolResponse) {
103
103
  .filter((path) => existsSync(path));
104
104
  }
105
105
 
106
- async function main() {
107
- let payload = null;
108
- let stdinError = null;
106
+ // The hook payload, or the error that kept it from being read.
107
+ async function readPayload() {
109
108
  try {
110
- payload = JSON.parse(await readStdin());
109
+ return { payload: JSON.parse(await readStdin()), error: null };
111
110
  } catch (err) {
112
- stdinError = err;
111
+ return { payload: null, error: err };
112
+ }
113
+ }
114
+
115
+ // Why a canonicalizer run failed, or null when it ran and reported JSON.
116
+ function runFailure(run) {
117
+ if (run.error) return `canonicalizer did not run: ${run.error.message}`;
118
+ if (run.status !== 0) return `canonicalizer exited ${run.status}: ${run.stderr || run.stdout}`;
119
+ try {
120
+ JSON.parse(run.stdout);
121
+ return null;
122
+ } catch {
123
+ return 'canonicalizer report was not json';
113
124
  }
125
+ }
114
126
 
115
- // A write can be redirected with workingDirectory; fall back to the session cwd.
116
- const root = payload?.tool_input?.workingDirectory || payload?.cwd || process.cwd();
117
- const wikiDir = findArmedWikiDir(root);
127
+ // Canonicalizes one page; a failure appends its one log line.
128
+ function canonicalize(wikiDir, tool, page) {
129
+ const run = spawnSync(process.execPath, [CANONICALIZER, page, '--profile=omc', '--json'], {
130
+ encoding: 'utf8',
131
+ timeout: CANONICALIZE_TIMEOUT_MS,
132
+ windowsHide: true,
133
+ });
134
+ const why = runFailure(run);
135
+ if (why) log(wikiDir, tool, `${basename(page)}: ${why}`);
136
+ }
137
+
138
+ // A write can be redirected with workingDirectory; fall back to the session cwd.
139
+ function writeRoot(payload) {
140
+ return payload?.tool_input?.workingDirectory || payload?.cwd || process.cwd();
141
+ }
142
+
143
+ async function main() {
144
+ const { payload, error } = await readPayload();
145
+ const wikiDir = findArmedWikiDir(writeRoot(payload));
118
146
  if (!wikiDir) return; // Not armed: change nothing, log nothing.
119
147
 
120
148
  const tool = payload?.tool_name ?? 'unknown';
121
149
  try {
122
- if (stdinError) return log(wikiDir, tool, `unreadable hook payload: ${stdinError.message}`);
150
+ if (error) return log(wikiDir, tool, `unreadable hook payload: ${error.message}`);
123
151
  if (!existsSync(CANONICALIZER)) return log(wikiDir, tool, `canonicalizer missing at ${CANONICALIZER}`);
124
-
125
- for (const page of resolvePages(wikiDir, payload.tool_response)) {
126
- const run = spawnSync(process.execPath, [CANONICALIZER, page, '--profile=omc', '--json'], {
127
- encoding: 'utf8',
128
- timeout: CANONICALIZE_TIMEOUT_MS,
129
- windowsHide: true,
130
- });
131
- if (run.error) {
132
- log(wikiDir, tool, `${basename(page)}: canonicalizer did not run: ${run.error.message}`);
133
- } else if (run.status !== 0) {
134
- log(wikiDir, tool, `${basename(page)}: canonicalizer exited ${run.status}: ${run.stderr || run.stdout}`);
135
- } else {
136
- try {
137
- JSON.parse(run.stdout);
138
- } catch {
139
- log(wikiDir, tool, `${basename(page)}: canonicalizer report was not json`);
140
- }
141
- }
142
- }
152
+ for (const page of resolvePages(wikiDir, payload.tool_response)) canonicalize(wikiDir, tool, page);
143
153
  } catch (err) {
144
154
  log(wikiDir, tool, `unexpected: ${err.message}`);
145
155
  }
@@ -183,18 +183,24 @@ const PLAN_PATHS = [
183
183
  /\/\.omc\/plans\/[^/]+\.md$/,
184
184
  /\/docs\/superpowers\/plans\/[^/]+\.md$/,
185
185
  /\/\.claude\/plans\/[^/]+\.md$/,
186
- /\/\.omc\/(?:state\/(?:[^/]+\/)*)?prd\.json$/,
187
- /\/\.omc\/ultragoal\/goals\.json$/,
186
+ // A ralph PRD and ultragoal's goals wherever they sit: OMC_STATE_DIR moves OMC's state out of .omc (a mod cannot
187
+ // read that variable), and a project may keep its PRD at the top. Only a file that parses as one becomes the plan.
188
+ /\/prd\.json$/,
189
+ /\/ultragoal\/goals\.json$/,
188
190
  ];
189
191
  // Plan folders keep a plan's review rounds beside it (ralplan's `<plan>-critic-r2.md`,
190
- // `architect-review-r1.md`) and OMC's open questions: a name that ends so is no plan.
191
- const NOT_A_PLAN = [/(?:^|[-_])(?:critic|architect|review|verdict|feedback)(?:-r\d+)?\.md$/i, /^open-questions\.md$/i];
192
+ // `architect-review-r1.md`) and OMC's open questions: a name that ends so is a weak plan, the plan only while the
193
+ // pane has no other.
194
+ const WEAK_NAMES = [/(?:^|[-_])(?:critic|architect|review|verdict|feedback)(?:-r\d+)?\.md$/i, /^open-questions\.md$/i];
192
195
 
193
- export const isPlanPath = (path) => {
196
+ /** What a path is to the pane: 'plan', 'weak' (a review round or open questions beside a plan), or null. */
197
+ export function planKind(path) {
194
198
  const p = String(path ?? '').replaceAll('\\', '/');
195
- const name = p.split('/').at(-1);
196
- return PLAN_PATHS.some((re) => re.test(p)) && !NOT_A_PLAN.some((re) => re.test(name));
197
- };
199
+ if (!PLAN_PATHS.some((re) => re.test(p))) return null;
200
+ return WEAK_NAMES.some((re) => re.test(p.split('/').at(-1))) ? 'weak' : 'plan';
201
+ }
202
+
203
+ export const isPlanPath = (path) => planKind(path) === 'plan';
198
204
 
199
205
  // ── a plan file ──────────────────────────────────────────────────────────────
200
206