@kaydash9999/banker-plugins 0.22.0 → 0.23.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 +41 -0
- package/PRIVACY.md +1 -0
- package/README.md +39 -13
- package/bin/banker.js +118 -22
- package/bin/lib/codex-hooks.mjs +116 -18
- package/bin/lib/codex-names.mjs +4 -0
- package/bin/lib/codex-routes.mjs +93 -1
- package/bin/lib/command-skill.cjs +37 -6
- package/codex/command-skills/front-qa/SKILL.md +1 -1
- package/codex/command-skills/setup/SKILL.md +4 -4
- package/codex/hooks.json +5 -5
- package/codex/manifest.json +18 -15
- package/codex/skills/progress/scripts/progress.mjs +44 -14
- package/codex/skills/teamwork/SKILL.md +137 -0
- package/codex/skills/teamwork/scripts/teamwork.mjs +957 -0
- package/codex/transform-matrix.md +5 -3
- package/hooks/obsidize-hook.mjs +75 -32
- package/hooks/telemetry-count-codex.mjs +238 -57
- package/hooks/update-fetch.mjs +2 -1
- package/hooks/update-notify.mjs +82 -20
- package/package.json +3 -1
- package/skills/3d-intro-build/SKILL.md +101 -20
- package/skills/3d-intro-build/references/NOTICE.md +9 -2
- package/skills/3d-intro-build/references/assemble.mjs +113 -22
- package/skills/3d-intro-build/references/azure-adapter.mjs +110 -24
- package/skills/3d-intro-build/references/clip-post.mjs +443 -0
- package/skills/3d-intro-build/references/dive-mode.mjs +299 -0
- package/skills/3d-intro-build/references/intro-fixes.css +11 -0
- package/skills/3d-intro-build/references/prompts.md +51 -4
- package/skills/3d-intro-build/references/scrub-engine.js +1 -0
- package/skills/3d-intro-build/references/step-nav.css +29 -0
- package/skills/3d-intro-build/references/step-nav.js +277 -106
- package/skills/3d-intro-build/references/verify-intro.mjs +373 -32
- package/skills/3d-intro-build/references/verify.md +6 -0
- package/skills/3d-intro-build/references/video-pool.mjs +142 -12
- package/skills/3d-intro-setup/SKILL.md +20 -7
- package/skills/3d-intro-setup/references/azure-adapter.mjs +110 -24
- package/skills/3d-intro-setup/references/video-pool.mjs +142 -12
- package/skills/all-in-one/SKILL.md +125 -86
- package/skills/omc-patch/SKILL.md +1 -1
- package/skills/payload-mon/SKILL.md +1 -1
- package/skills/play-qa/SKILL.md +6 -4
- package/skills/progress-mon/README.md +162 -0
- package/skills/progress-mon/SKILL.md +165 -0
- package/skills/progress-mon/assets/fixture/README.md +1 -0
- package/skills/progress-mon/assets/fixture/arch.json +33 -0
- package/skills/progress-mon/assets/fixture/commits.json +7 -0
- package/skills/progress-mon/assets/fixture/config.json +30 -0
- package/skills/progress-mon/assets/fixture/events.jsonl +7 -0
- package/skills/progress-mon/assets/fixture/flow.json +44 -0
- package/skills/progress-mon/assets/fixture/items.json +14 -0
- package/skills/progress-mon/assets/fixture/req-spec.json +31 -0
- package/skills/progress-mon/assets/fixture/reqs.json +11 -0
- package/skills/progress-mon/assets/fixture/variants/arch-auto/arch.json +58 -0
- package/skills/progress-mon/assets/fixture/variants/check-auto/arch.json +15 -0
- package/skills/progress-mon/assets/fixture/variants/check-overlap/arch.json +14 -0
- package/skills/progress-mon/assets/fixture/variants/history-manual/config.json +13 -0
- package/skills/progress-mon/assets/fixture/variants/history-manual/items.json +7 -0
- package/skills/progress-mon/assets/fixture/variants/workflow-wide/flow.json +35 -0
- package/skills/progress-mon/assets/fixture/workflows/wf_ex1/agent-a01.jsonl +1 -0
- package/skills/progress-mon/assets/fixture/workflows/wf_ex1/agent-a02.jsonl +1 -0
- package/skills/progress-mon/assets/fixture/workflows/wf_ex1/agent-a03.jsonl +1 -0
- package/skills/progress-mon/assets/fixture/workflows/wf_ex1/agent-a04.jsonl +1 -0
- package/skills/progress-mon/assets/fixture/workflows/wf_ex1/journal.jsonl +7 -0
- package/skills/progress-mon/references/arch.md +280 -0
- package/skills/progress-mon/references/authoring.md +199 -0
- package/skills/progress-mon/references/config.md +115 -0
- package/skills/progress-mon/references/flow.md +75 -0
- package/skills/progress-mon/references/inventory.md +58 -0
- package/skills/progress-mon/references/items.md +74 -0
- package/skills/progress-mon/references/req-spec.md +74 -0
- package/skills/progress-mon/references/reqs.md +30 -0
- package/skills/progress-mon/scripts/index.js +31 -0
- package/skills/progress-mon/scripts/pm-check.mjs +526 -0
- package/skills/progress-mon/scripts/pm-config.mjs +341 -0
- package/skills/progress-mon/scripts/pm-data.mjs +394 -0
- package/skills/progress-mon/scripts/pm-html.mjs +77 -0
- package/skills/progress-mon/scripts/pm-memory.mjs +308 -0
- package/skills/progress-mon/scripts/pm-render.mjs +1644 -0
- package/skills/progress-mon/scripts/pm-server.mjs +735 -0
- package/skills/progress-mon/scripts/pm-sources.mjs +501 -0
- package/skills/progress-mon/scripts/progress-mon.mjs +167 -0
- package/skills/ralph-qa/SKILL.md +104 -15
- package/skills/ralph-qa/references/gate-evidence.mjs +457 -0
- package/skills/ralph-qa/references/payload-scan.mjs +19 -2
- package/skills/ralph-qa/references/run-folder.mjs +299 -0
- package/skills/ralph-qa/references/seat-payload.mjs +60 -13
- package/skills/ralph-qa/references/seat-run.mjs +159 -155
- package/skills/remains/SKILL.md +1 -0
- package/skills/remains/scripts/boxes.mjs +6 -2
- package/skills/setup-bypass-permissions/scripts/codex-config.mjs +19 -8
- package/skills/setup-mcp/SKILL.md +1 -1
- package/skills/setup-omc-hud/SKILL.md +2 -1
- package/skills/setup-omc-hud/assets/codex-config.mjs +19 -8
- package/skills/ultra-chain/SKILL.md +32 -14
- package/skills/ultra-chain/references/chain-ledger.mjs +111 -3
- package/skills/ultra-init/SKILL.md +30 -22
- package/skills/ultraqa/NOTICE.md +34 -0
- package/skills/ultraqa/SKILL.md +196 -0
- package/skills/ultraqa/references/gate-evidence.mjs +457 -0
- package/skills/ultraqa/references/run-folder.mjs +299 -0
- package/skills/ultraqa/references/tmux-drive.md +52 -0
- package/skills/ultraqa/references/uqa-run.mjs +339 -0
- package/skills/update-banker/SKILL.md +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "banker",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.23.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,46 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.23.0] - 2026-10-30
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- 새 스킬 `teamwork`(Codex 전용): 같은 기기의 Codex CLI 세션끼리 피어 협업을 켜고 끈다(`on` 기본, `off`, `status`). 켜면 열린 세션과 새 세션이 모두 팀으로 동작하고, 역할은 각 세션에 말로 주며, 요청과 결과는 Codex 내장 `codex queue` 로 오간다. npm 길 `$banker-teamwork`, 플러그인 길 `$banker:teamwork`.
|
|
7
|
+
- 승인 규칙은 래퍼의 `peers`, `role`, `send`, `reply`, `status`, `version` 만 허용하고 `on`, `off`, `uninstall` 은 승인을 받는다.
|
|
8
|
+
- 래퍼와 훅은 `on` 때 찾은 `node`, `codex`, `ps`, `sh` 의 절대 경로만 쓰고, 임시 폴더, 작업 폴더, `writable_roots` 아래의 프로그램과 Codex 홈은 거부한다. `hooks.json` 은 banker 훅 설치와 같은 잠금으로 고친다.
|
|
9
|
+
- Codex 0.149.0 이상, Linux 와 macOS. Windows 는 `on` 이 까닭을 밝히고 끝난다(승인 규칙이 PowerShell 로 부르는 래퍼에 맞지 않아 쓸 때마다 승인을 물어야 함).
|
|
10
|
+
- 새 스킬 `progress-mon`: 프로젝트 진척도를 4탭 웹 화면(진척도, 구현요건, workflow, 구성도)으로 로컬 서버(기본 127.0.0.1)에 띄운다. `init` 이 코드를 읽어 탭 자료를 쓰고, `export` 는 서버 없는 단일 HTML 을 만든다. Node 18 이상, npm 의존 없음. 두 런타임에서 쓴다. 세션 작업 목록 패널은 지금처럼 `/progress` 다.
|
|
11
|
+
- 새 스킬 `ultraqa`(Claude Code 전용, `/banker:ultraqa`): OMX ultraqa 를 본뜬 적대적 동적 e2e QA 순환. 9분류 시나리오 행렬과 실행기가 돌린 게이트 증거로 최대 5회 진단, 고침, 재시험한다. Codex 에는 설치하지 않는다(Codex 는 OMX `$ultraqa`).
|
|
12
|
+
- `3d-intro-build` 의 dive 모드: 장면마다 그 장면 스틸에서 시작하는 클립을 만든다. Step 1 에서 a(chain), b(dive 나가기 없음), c(dive 나가기 있음) 가운데 고르고, 기본은 b 다. 비용 추정과 첫 쌍 게이트의 기본 선택도 b 기준이다(6장면 약 $4.8). WAN 실행이면 dive 가 미측정이라고 알린다.
|
|
13
|
+
- `3d-intro-build` 결과 페이지의 장면 단위 이동(스크롤 스냅)이 기본으로 켜진다. 매니페스트 `stepNav: false` 로 끈다.
|
|
14
|
+
- 휠 1칸과 방향키 1번은 다음 장면까지 절반, 2번이면 한 장면. PageUp, PageDown, Space, 스와이프는 한 장면.
|
|
15
|
+
- Home 은 첫 장면 시작, End 는 마지막 장면 끝, 장면 점은 그 장면 시작으로 애니메이션 없이 바로 간다.
|
|
16
|
+
- 장면 사이에서 멈추면 가까운 장면 시작으로 붙는다. 멈춘 자리에서 그 장면의 문구가 보인다.
|
|
17
|
+
- 포스터 디코드를 150ms 넘게 기다리면 화면 가운데에 불러오는 중 표시가 보이고, 이동하면 바로 사라진다.
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
- `ralph-qa`: 실행기가 직접 돌린 게이트 증거(`--gates`, 출력 sha256 과 작업 트리 지문), 적대 관점과 scenarios, 같은 이슈 기준, 흔들림 재실행을 더한다. 좌석에 도구 규칙을 고정 앞머리로 넘기고, 역할 좌석 모델은 `agents/<역할>.toml` 에서 읽는다.
|
|
21
|
+
- `ralph-qa` send 가 같은 폴더에서 둘 동시에 불려도 페이로드를 한 번만 보낸다. Windows 에서 지우는 중인 잠금 자리의 `EPERM` 도 잠금 있음으로 보고 다시 시도한다.
|
|
22
|
+
- `all-in-one` Stage 3, `ultra-init` Phase 3 의 마지막 QA 게이트가 두 런타임 모두 `ralph-qa --gates` 단독이다. `ultra-chain` 6단계 로컬 게이트도 실행기 증거로 판정한다. git 없는 폴더는 시작 전에 `not-a-git-tree` 로 멈추고, STOPPED 뒤에는 어떤 파일도 고치지 않는다. Codex 에서 OMX 단계가 tmux 밖이면 기록한 대체 실행을 쓰고, 그것도 못 하면 STOPPED 로 끝난다.
|
|
23
|
+
- Codex 의 스킬 이름과 설명이 OMC 대신 OMX 를 적는다. `setup-omc`, `omc-reference`, `setup-omc-hud` 는 Codex 에서 `setup-omx`, `omx-reference`, `setup-omx-hud` 다. npm 길은 갱신 때 옛 폴더를 지우고 `이름 바뀜:` 줄로 알린다. 플러그인 스킬 목록은 스킬마다 경로를 적는다.
|
|
24
|
+
- `remains` 의 박스 도구(`boxes.mjs`)가 Windows `--cmd` 에서 한글 인자를 깨뜨리지 않는다(`chcp 65001`). `for`, `if`, `(` 로 시작하는 명령은 `call` 없이 돈다.
|
|
25
|
+
- `3d-intro-build` 의 측정(`verify-intro`)이 화면 캡처 10초, 페이지 load 15초, `intro.js` 받기 15초까지만 기다린다. 넘으면 그 결과는 이유와 함께 미측정으로 남고 통과로 세지 않는다.
|
|
26
|
+
- `3d-intro-build` 의 그 밖 수정
|
|
27
|
+
- Sora 퇴역(410)을 알아보고 같은 배포로 다시 보내지 않는다. 배포 확인은 과금 없는 GET 으로 한다.
|
|
28
|
+
- 클립 후처리를 공통 인코딩 하나로 한다(역재생, 판 착지). 톤 맞춤은 고칠 톤이 없어 뺐다.
|
|
29
|
+
- git 이 추적하는 키 파일에서는 endpoint 와 key 를 읽지 않는다. 섹션 id 와 자산 경로가 프로젝트나 출력 폴더 밖을 가리키지 못한다.
|
|
30
|
+
- 즉시 이동과 클립이 나타나는 순간의 빈 화면, 느린 적재의 첫 경계 포스터 튐, 밝은 장면의 유리 패널 대비를 고친다.
|
|
31
|
+
- `play-qa` 설명이 Godot 대신 웹 기반 동작 컨텐츠를 적는다.
|
|
32
|
+
- 그 밖 하자 수정
|
|
33
|
+
- Codex 훅이 `writable_roots` 아래면 돌지 않고 이유를 한 줄로 알린다. Windows 에서 지금 폴더에 심은 `codex.cmd` 를 돌리지 않는다.
|
|
34
|
+
- Codex 사용량 카운팅의 턴 셈 틈을 닫고, 턴 시작이 기록 끝 32 MB 밖이어도 센다. 홈 밖 네트워크 마운트 PATH 항목에서 멈추지 않는다.
|
|
35
|
+
- obsidize 훅이 셸 규칙(Windows 는 PowerShell)대로 명령을 나눈다. `config.toml` 머리 주석 뒤에 새 키를 바르게 넣는다.
|
|
36
|
+
- `progress --follow` 가 계획 파일만 바뀌어도 2초 안에 다시 그리고, `banker doctor` 가 첫 턴 전 기록에 오경고를 내지 않는다. 지울 수 없는 낡은 `hooks.json` 잠금은 까닭과 함께 끝난다.
|
|
37
|
+
|
|
38
|
+
### Notes
|
|
39
|
+
- Codex 플러그인 사용자: 훅 코드가 바뀌어 `banker-hooks-rev` 해시가 바뀐다(`625aade934d2` 에서 `7fad90560d65`). 다음 세션에서 `/hooks` 신뢰를 다시 묻고, 신뢰하기 전에는 훅이 돌지 않는다.
|
|
40
|
+
- Codex npm 길 사용자: npm 을 올린 뒤 `banker setup --codex` 를 다시 해야 새 훅 사본과 바뀐 Codex 스킬 이름이 들어간다. `config.toml` 의 `[[skills.config]]` 로 옛 이름을 꺼 두었다면 새 이름으로 다시 적는다.
|
|
41
|
+
- 실측: 테스트박스 3대(macOS, Windows, Rocky Linux 8)에서 시험을 돌렸다. Node 18 은 `progress-mon` 만 재었다(Rocky 8 박스의 v18.20.8). Codex 는 0.165.0(Linux)과 0.160.1(Windows)에서 확인했다.
|
|
42
|
+
- dive 모드의 실제 클립 측정은 Sora 로 장면 한 세트만 했다. 유료 WAN 검증은 하지 않았고, WAN 에서 dive 는 재지 않았다.
|
|
43
|
+
|
|
3
44
|
## [0.22.0] - 2026-10-29
|
|
4
45
|
|
|
5
46
|
### Added
|
package/PRIVACY.md
CHANGED
|
@@ -102,6 +102,7 @@ Codex 카운팅이 읽는 것과 남기는 것은 다음과 같습니다.
|
|
|
102
102
|
- 보지 않는 것: 사용자가 입력한 글, 모델의 답, 도구 결과, 스킬 본문.
|
|
103
103
|
- 로컬에 남기는 것: Claude Code 와 같은 `usage-log`, `used-skills.json` 의 스킬 이름과 시간대, 같은 턴을 두 번 세지 않게 하는 최근 턴 키(`codex-count-turns`, Codex 세션 ID 와 턴 ID, 최근 100개).
|
|
104
104
|
- 로컬에 남기는 것(추가): 세션 시작 알림을 낸 Codex 세션 ID 를 이름으로 한 빈 폴더(`codex-sessions/`, 이틀 뒤 지움). npm 설치와 플러그인 설치의 훅이 함께 돌 때 같은 세션에 두 번 알리지 않는 데만 쓰고 전송하지 않습니다.
|
|
105
|
+
- 로컬에 남기는 것(추가): 센 턴마다 빈 표지 파일(`codex-count-turns.d/`, 이름은 세션 ID, 턴 ID, 스킬 이름의 sha256 앞 32자, 이틀 뒤 지움)과, 턴 시작이 기록 끝 256 MB 밖이라 세지 않은 마지막 한 번의 시각, 세션 ID, 턴 ID 한 줄(`codex-count-note`). 같은 턴을 두 번 세지 않는 데와 진단에만 쓰고 전송하지 않습니다.
|
|
105
106
|
- 로컬에 남기는 것(추가): 이 훅이 기록 형식을 읽지 못한 Codex 버전(`codex-shape-miss.json`, 버전과 알림 여부만). 다음 세션 시작 때 경고를 한 번 보이는 데만 쓰고 전송하지 않습니다.
|
|
106
107
|
- 전송하는 것: Claude Code 와 같은 체크인 `{version, os, counts}` 입니다. 세션 ID 와 턴 ID 는 전송하지 않습니다.
|
|
107
108
|
|
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
[빠른 시작](#빠른-시작) · [워크플로 예시](#워크플로-사용-예시) · [구성](#구성) · [설치 상세](#설치-상세-npm--codex) · [설정 변경 지점](#설정-변경-지점-claude-code--codex) · [요구사항](#요구사항) · [업데이트 / 제거](#업데이트--제거) · [업데이트 확인](#업데이트-확인-및-사용량-카운팅) · [오프라인](#오프라인에서-쓰기) · [라이선스 / 서드파티](#라이선스--서드파티)
|
|
10
10
|
|
|
11
11
|
□ banker는 다음을 포함하는 Claude Code 및 Codex CLI 플러그인입니다.
|
|
12
|
-
- QA·보안 감사·문서·아키텍처·위키·미디어 작업과 의존성·개발환경(OS별) 설치를 아우르는 **스킬
|
|
12
|
+
- QA·보안 감사·문서·아키텍처·위키·미디어 작업과 의존성·개발환경(OS별) 설치를 아우르는 **스킬 66개 + 커맨드 2개**(총 68개 구성요소. Codex 는 Claude Code 전용 `ultraqa` 를 뺀 스킬 65개와 Codex 전용 스킬 3개)
|
|
13
13
|
- Claude Code 즉시 명령 `/graceful-pause`, `/progress`
|
|
14
14
|
|
|
15
15
|
□ 설치하면 스킬과 커맨드가 `/banker:<이름>` 네임스페이스로 노출됩니다.
|
|
@@ -75,7 +75,7 @@ Claude Code는 `/banker:<이름>`, Codex는 `$banker-<이름>`(플러그인 설
|
|
|
75
75
|
| `ultra-interview` | 처음 프로젝트 아이디어를 구체화할 때 | 최신 정보를 반영한 소크라테스식 인터뷰 |
|
|
76
76
|
| `ultra-init` | 프로젝트 기획이 충분히 구체적일 때 | 데모를 구현 |
|
|
77
77
|
| `curation` | 질문에 답하기 어렵거나 의사결정이 어려울 때 | 합리적 선택지 제공 (`--perf` = 품질 우선, `--deep` = 확신 0.80 초과까지 추가 조사) |
|
|
78
|
-
| `all-in-one` | 요건이 명확한 단계에서 | 계획 → 구현 → 검증 |
|
|
78
|
+
| `all-in-one` | 요건이 명확한 단계에서 | 계획 → 구현 → `ralph-qa` 검증 |
|
|
79
79
|
| `ralph-qa` | 검증이 충분하지 않을 때 | 세션 모델로 띄운 독립 검토 에이전트 3개 이상의 합의 루프 (+ 플래그로 고른 CLI 좌석) |
|
|
80
80
|
| `smart-compact` | 컨텍스트 임계 초과로 맥락 단절이 걱정될 때 | 맥락을 더 잘 이어서 진행 |
|
|
81
81
|
| `refresh-readme` | 프로젝트 배포 전 | README 최신화 |
|
|
@@ -100,6 +100,7 @@ Claude Code는 `/banker:<이름>`, Codex는 `$banker-<이름>`(플러그인 설
|
|
|
100
100
|
| `/banker:front-qa` | 스펙(note) 기반 프론트엔드 구현 + parity QA |
|
|
101
101
|
| `/banker:setup` | 구성요소·의존성 설치 오케스트레이터 (multi-select) |
|
|
102
102
|
| `/graceful-pause` | 작업 중에도 바로 실행되는 정지 요청. 지금 단계만 끝내고 멈춘 뒤 보고하고 지시를 기다림 (Claude Code 2.1.289 이상, mod. Codex 는 작업 중에 `$banker-graceful-pause` 를 보내면 실행 중인 도구 호출이 끝난 뒤 멈춤) |
|
|
103
|
+
| `$banker-teamwork` (Codex 전용 스킬) | 같은 기기의 Codex CLI 세션끼리 피어 협업을 켜고 끔(`on` 기본, `off`, `status`). 켜면 열린 세션과 새 세션이 모두 팀으로 동작하고, 역할은 각 세션에 말로 주며, 요청과 결과는 Codex 내장 `codex queue` 로 오감. 플러그인 길은 `$banker:teamwork` |
|
|
103
104
|
| `/progress` | 진행 상황 패널을 켜고 끔(`show` 기본 토글, `on`, `off`). 맨 위는 이 세션이 쓰거나 읽은 마지막 계획 파일(`.omc/plans/*.md`, `docs/superpowers/plans/*.md`, `~/.claude/plans/*.md`, ralph `prd.json`, ultragoal `goals.json`) 전체. Notion 토글 목록처럼 제목이 그 아래 내용을, 목록 항목이 하위 항목을, 표와 코드 블록이 행과 줄을 품고, 처음에는 큰 제목만 접힌 채 보임. 체크박스는 완료와 대기, 제목은 그 아래 체크 수(`2/5`). 그 아래 단계는 할 일 목록(Claude 의 작업 목록이나 `mcp__banker__todo`), 없으면 이 세션의 요청이고, 하위 목록은 그 단계가 진행 중일 때 한 도구 호출 한 단계까지. 작업 중에도 바로 실행됨(2.1.289 이상에서 확인) (mod. Codex 는 `$banker-progress` 스킬이 지금 세션의 계획 트리, `update_plan` 단계, 최근 도구 호출을 텍스트로 보이고, tmux 안이면 `--pane` 으로 오른쪽 칸에 갱신) |
|
|
104
105
|
|
|
105
106
|
Claude Code 2.1.296 은 Claude 5 모델(Opus 5.5 등)에 작업 목록 도구(TaskCreate, TodoWrite)를 주지 않습니다. 그래서 `/progress` 를 켜면 모델에게 할 일 도구 `mcp__banker__todo` 를 줍니다(다음 요청부터). 모델이 여러 단계 작업을 시작할 때 할 일 목록을 보내면 그 목록이 단계가 됩니다. 한 단계로 끝나는 일에는 쓰지 않으므로 그때는 요청이 단계입니다. 내장 작업 목록 도구가 있는 세션(옛 모델, `CLAUDE_CODE_ENABLE_TODO_TOOLS=1`)에는 이 도구를 더하지 않습니다. 도구는 `/progress off` 뒤에도 세션이 끝날 때까지 남고, 그동안 부르면 패널이 꺼져 있다고 답합니다.
|
|
@@ -113,7 +114,7 @@ Claude Code 2.1.296 은 Claude 5 모델(Opus 5.5 등)에 작업 목록 도구(Ta
|
|
|
113
114
|
| `audit-security` | 보안 취약점(CVE·SAST·시크릿) 진단 (read-only) |
|
|
114
115
|
| `audit-mock` | 하드코딩·mock/stub·열거형 정적 검출 (read-only) |
|
|
115
116
|
| `audit-web-page` | 라이브 웹 페이지 점검 (playwright·WebGL 캔버스) |
|
|
116
|
-
| `play-qa` |
|
|
117
|
+
| `play-qa` | 웹 기반 동작 컨텐츠를 실제 브라우저에서 직접 플레이하는 QA |
|
|
117
118
|
| `ultra-ui-qa` | UI를 기준(디자인 PDF/스펙)과 1:1 대조 QA |
|
|
118
119
|
| `visual-ralph` | 레퍼런스(생성/정적/URL) 기준 프론트 UI를 Visual Verdict(≥90)로 측정 빌드 |
|
|
119
120
|
|
|
@@ -144,14 +145,15 @@ Claude Code 2.1.296 은 Claude 5 모델(Opus 5.5 등)에 작업 목록 도구(Ta
|
|
|
144
145
|
|
|
145
146
|
| 스킬 | 설명 |
|
|
146
147
|
|---|---|
|
|
147
|
-
| `all-in-one` | 계획→구현→검증 end-to-end
|
|
148
|
-
| `ultra-init` | 아이디어→빌드→테스트 원샷 자동
|
|
148
|
+
| `all-in-one` | 계획→구현→검증 end-to-end 오케스트레이터. 마지막 QA 는 두 런타임 모두 `ralph-qa` |
|
|
149
|
+
| `ultra-init` | 아이디어→빌드→테스트 원샷 자동 실행. 마지막 QA 는 두 런타임 모두 `ralph-qa` |
|
|
149
150
|
| `ready-compact` | 이어가기 상태 저장 + resume 프롬프트만 출력(`--hand-off` = 새 세션용 자급식 노트·프롬프트) |
|
|
150
151
|
| `compact-copy` | 설명·코드펜스가 섞인 resume 프롬프트 출력에서 본문만 추출(지금의 ready-compact 는 처음부터 프롬프트만 출력) |
|
|
151
152
|
| `refresh-git-ignore` | `.gitignore` 비파괴·반복가능 갱신 |
|
|
152
153
|
| `omc-reference` | OMC/OMX 에이전트·툴·스킬 레퍼런스(양 런타임 병기) |
|
|
153
154
|
| `curation` | 의사결정을 선택지·권고·확신수준으로 큐레이션(--perf=품질 우선, --deep=확신 0.80 이하는 추가 조사·검토 후 제시) |
|
|
154
155
|
| `ralph-qa` | 세션 모델로 띄운 독립 검토 에이전트 3개 이상이 합의할 때까지 검증 반복. `--codex`·`--gemini`·`--opencode` 를 주면 그 CLI 에서 가장 뛰어난 모델이 좌석으로 합류 |
|
|
156
|
+
| `ultraqa` | Claude Code 전용(`/banker:ultraqa`). OMX ultraqa 를 본뜬 적대적 동적 e2e QA 순환. 9분류 시나리오 행렬과 실행기가 돌린 게이트 증거로 최대 5회 진단, 고침, 재시험. Codex 는 OMX `$ultraqa` 를 그대로 씀 |
|
|
155
157
|
| `smart-compact` | 컨텍스트 임계 초과 시 위키·resume 저장 게이트 자동 무장 |
|
|
156
158
|
| `deep-research` | 다중 소스 팬아웃 + 적대적 검증 인용 리서치 |
|
|
157
159
|
| `lfm` | learn from master. 그 분야 최고 전문가 그룹이 일하는 방식을 1차 자료로 조사해 계획 적용 항목으로 정리(ultra-interview, ultra-chain, deep-research, rfp-author 의 리서치에서도 씀) |
|
|
@@ -168,13 +170,14 @@ Claude Code 2.1.296 은 Claude 5 모델(Opus 5.5 등)에 작업 목록 도구(Ta
|
|
|
168
170
|
| `remains` | 남은 버그, 하자, 미검증 항목을 찾아 표로 보여 줌. 테스트박스(`~/.config/banker/test-boxes.json`)가 등록돼 있으면 각 OS 에서 시험을 돌려 확인(읽기와 시험만, 고치지 않음) |
|
|
169
171
|
| `trouble-shooting` | 문제를 조사해 현상, 문제점, 원인, 해결방법, 조치계획을 표 하나로 간결히 보고(문제마다 한 행, `--no-plan` 은 해결방법까지, 고치지 않고 보고만) |
|
|
170
172
|
| `ultra-chain` | 자료 조사, 모호성 제거, 검토자 3명 이상의 합의 계획, 목업 승인, 비판 검증 구현, 실제 OS 테스트박스 시험과 합의 검증, 시각 검토, 과정 시각화, 결과 공유를 한 명령으로 잇는 9단계 연쇄. 사람이 볼 곳은 인터뷰의 취향 질문과 목업 승인으로 줄임. 실행 기록과 단일 HTML 보고서를 남기고, push 나 외부 게시는 요청할 때만 |
|
|
173
|
+
| `progress-mon` | 프로젝트 진척도를 4탭 웹 화면(진척도, 구현요건, workflow, 구성도)으로 로컬 서버(기본 127.0.0.1)에 띄움. `init` 이 코드를 읽어 탭 자료를 쓰고 프로젝트 메모리에 갱신 규칙 한 줄을 등록, `export` 는 서버 없는 단일 HTML. 세션 작업 목록 패널은 `/progress` |
|
|
171
174
|
|
|
172
175
|
### 스킬: 미디어 (모션 그래픽 · 3D 인트로)
|
|
173
176
|
|
|
174
177
|
| 스킬 | 설명 |
|
|
175
178
|
|---|---|
|
|
176
179
|
| `motion-graphic-make` | 10초 내외 내레이션 없는 무료 모션 그래픽 제작 (hyperframes 위임). 계획 승인, 스냅숏과 렌더 검토 페이지, 독립 검증, 사이트 배치는 선택 |
|
|
177
|
-
| `3d-intro-build` | 스크롤-스크럽 3D 인트로 사이트 제작 (Azure gpt-image 스틸 + WAN 키 풀 영상, 소진 시 Sora-2 폴백, 유료). 단계별 검토 페이지, 엄격한 CSP 에서 도는 페이지, 실제 브라우저 독립 검증. 장면 단위
|
|
180
|
+
| `3d-intro-build` | 스크롤-스크럽 3D 인트로 사이트 제작 (Azure gpt-image 스틸 + WAN 키 풀 영상, 소진 시 Sora-2 폴백, 유료). 단계별 검토 페이지, 엄격한 CSP 에서 도는 페이지, 실제 브라우저 독립 검증. 영상 모드는 chain, dive 나가기 없음(기본), dive 나가기 있음 가운데 고름. 장면 단위 이동(장면 시작점에 멈춤, Home, End, 장면 점은 바로 이동)은 기본 켬이고 끌 수 있음, 기존 사이트 통합은 선택 |
|
|
178
181
|
|
|
179
182
|
### 스킬: 개발환경 setup (OS별 · 런타임별)
|
|
180
183
|
|
|
@@ -224,26 +227,43 @@ banker uninstall # 제거
|
|
|
224
227
|
|
|
225
228
|
- `--scope project` 로 프로젝트 로컬(`./.codex`)에 설치하고, `--dry-run` 으로 미리 볼 수 있습니다.
|
|
226
229
|
- non-root 전용입니다(전역 sudo 설치 시 root 소유 파일을 방지). postinstall이 없으므로 `banker setup` 을 직접 실행합니다.
|
|
227
|
-
- Codex에는 스킬
|
|
230
|
+
- Codex에는 스킬 65개와 Codex 전용 스킬 3개(`graceful-pause`, `progress`, `teamwork`)가 `~/.codex/skills/banker-<name>/` 에, 커맨드 2개가 `~/.codex/prompts/banker-<name>.md` 에 설치됩니다(`codex/manifest.json`). \
|
|
228
231
|
`CODEX_HOME` 을 설정했으면 `~/.codex` 대신 그 폴더에 설치합니다(Codex 가 읽는 곳). \
|
|
229
232
|
`lineage`, `progress`, 사용량 카운팅은 Codex 의 대화 기록(rollout)을 읽습니다. Codex 는 이 형식을 공개 약속으로 내놓지 않아 업데이트로 바뀔 수 있습니다. \
|
|
230
233
|
Codex 를 업데이트한 뒤에는 `banker doctor` 로 형식을 점검합니다. 읽지 못하면 lineage 는 빈 페이지 대신 오류로 멈추고, progress 는 경고 줄을 보이며, 카운팅은 다음 세션 시작 때 경고를 한 번 보입니다. \
|
|
231
234
|
Codex 0.144 이상에는 사용자 프롬프트가 없으므로 커맨드 2개는 스킬로도 설치되어 `$banker-front-qa`, `$banker-setup` 으로 부릅니다. \
|
|
232
235
|
디렉터리명과 일치하도록 프론트매터 `name:` 이 `banker-<name>` 으로 재작성되어 Codex가 `banker-<name>` 으로 인식합니다.
|
|
233
236
|
- Codex 플러그인 설치(`codex plugin add banker@banker-plugins`)는 저장소를 `~/.codex/plugins/cache/banker-plugins/banker/<판>/` 에 두고 `.codex-plugin/plugin.json` 을 읽습니다. \
|
|
234
|
-
스킬
|
|
237
|
+
스킬 65개, Codex 전용 스킬 3개, 커맨드 2개(스킬로)가 `$banker:<name>` 으로 보이고, 업데이트 알림과 사용량 카운팅 훅은 `codex/hooks.json` 에서 옵니다. \
|
|
235
238
|
Codex 는 세션을 시작할 때 마켓플레이스를 스스로 올려 새 판을 설치합니다. 훅 명령 앞에는 훅이 실행하는 파일의 해시가 붙어 있어, 훅 코드가 바뀐 판에서는 `/hooks` 가 다시 신뢰를 묻고 신뢰하기 전에는 훅이 돌지 않습니다. 훅 코드가 그대로인 판은 신뢰도 그대로입니다. 스킬 파일은 신뢰 확인 없이 새 판으로 바뀝니다. \
|
|
236
239
|
obsidizer 훅은 npm 설치와 같이 `obsidizer --enable` 할 때만 사용자 범위에 설치됩니다(셸 호출마다 node 를 띄우므로). \
|
|
237
|
-
훅은 Codex 샌드박스 밖에서 돌므로, PATH 의 node 가 임시 폴더나 작업 폴더 안에 있으면(샌드박스가 바꿀 수 있는 곳) 아무것도 돌리지 않고 그 이유를 세션 시작 알림으로 보입니다. 작업 폴더가 홈 폴더 자체이면 홈 아래의 node(nvm 등)는 그대로 씁니다. \
|
|
240
|
+
훅은 Codex 샌드박스 밖에서 돌므로, PATH 의 node 가 임시 폴더나 작업 폴더 안에 있으면(샌드박스가 바꿀 수 있는 곳) 아무것도 돌리지 않고 그 이유를 세션 시작 알림으로 보입니다. 작업 폴더가 홈 폴더 자체이면 홈 아래의 node(nvm 등)는 그대로 씁니다. 훅 스크립트, 플러그인 폴더, node 가 `config.toml` 의 `[sandbox_workspace_write] writable_roots` 아래(그 항목 맨 위 `.codex` 제외)면 훅은 다른 일을 하지 않고 그 이유를 한 줄로 알립니다. 이 검사는 훅 파일 안에서 하므로, 샌드박스가 이미 그 파일을 고친 뒤에는 막지 못합니다. writable_roots 에 Codex 홈이나 node 가 든 폴더를 넣지 마십시오. \
|
|
238
241
|
node 를 찾은 뒤에는 PATH 에서 임시 폴더와 작업 폴더 아래 항목을 빼므로, 프로젝트의 `.venv/bin` 이나 `node_modules/.bin` 에 있는 프로그램은 훅에서 돌지 않습니다(작업 폴더가 홈 폴더 자체이면 홈 아래 항목은 남깁니다). Windows 는 네트워크 드라이브와 UNC 경로의 PATH 항목을 읽지 않습니다. macOS 데스크톱에서 연 Codex 처럼 PATH 에 node 가 없으면 Homebrew(`/opt/homebrew/bin`)와 공식 설치(`/usr/local/bin`)의 node 를 씁니다. \
|
|
239
242
|
Volta, mise, snap 처럼 이름을 보고 동작하는 node 와 Windows 의 `node.cmd` shim(mise)은 그 도구가 고른 node 를 씁니다. 훅은 플러그인 폴더에서 돌므로 asdf, nodenv 는 전역 버전(`asdf set -u nodejs <판>`, asdf 0.16 미만은 `asdf global nodejs <판>`, `nodenv global <판>`)이 있어야 합니다. \
|
|
240
243
|
이 설치에는 `banker` 명령이 없습니다. `banker doctor`, `banker telemetry` 가 필요하면 npm 으로도 설치하되 `banker setup`(인자 없음)과 `banker setup --codex` 는 돌리지 않습니다(Codex 에 npm 길이 함께 설치됨). Claude Code 에 넣으려면 `banker setup --claude` 만 씁니다.
|
|
244
|
+
- Codex 에서는 OMC 를 OMX 로 바꿔 부르거나 설명하는 스킬이 있습니다. npm 길과 플러그인 길의 이름이 같습니다.
|
|
245
|
+
|
|
246
|
+
| Claude Code 이름 | Codex 이름 | Codex 에서 바뀐 것 |
|
|
247
|
+
|---|---|---|
|
|
248
|
+
| `setup-omc` | `setup-omx` | 이름, 설명 |
|
|
249
|
+
| `omc-reference` | `omx-reference` | 이름, 설명 |
|
|
250
|
+
| `setup-omc-hud` | `setup-omx-hud` | 이름, 설명 |
|
|
251
|
+
| `append_wiki` | `append_wiki` | 설명 |
|
|
252
|
+
| `compact-wiki` | `compact-wiki` | 설명 |
|
|
253
|
+
| `setup-tmux` | `setup-tmux` | 설명 |
|
|
254
|
+
| 커맨드 `setup` | `setup` | 설명 |
|
|
255
|
+
|
|
256
|
+
Codex 에서는 npm 길이 `$banker-setup-omx`, 플러그인 길이 `$banker:setup-omx` 처럼 부릅니다. `omc-patch`, `payload-mon` 은 Codex 에서도 이름이 같습니다. 둘 다 Claude Code 의 OMC 를 다룹니다. `ultraqa` 는 Claude Code 전용이라 Codex 에는 없습니다(Codex 는 OMX `$ultraqa`). \
|
|
257
|
+
npm 길은 갱신할 때 옛 폴더(`banker-setup-omc` 등)를 지우고 새 이름으로 설치한 뒤 `이름 바뀜:` 줄로 알립니다. 플러그인 길은 새 판으로 바뀔 때 옛 이름이 사라집니다. \
|
|
258
|
+
`config.toml` 의 `[[skills.config]]` 로 옛 이름을 꺼 두었다면 그 설정은 새 이름에 닿지 않습니다. 새 이름으로 다시 적습니다. \
|
|
259
|
+
플러그인 길의 스킬 목록(`.codex-plugin/plugin.json` 의 `skills`)은 스킬마다 경로를 적습니다. 이 형식은 Codex 0.160.1 이상에서 확인했습니다(0.160.1 Windows, 0.165.0 Linux). 0.144.5 같은 낮은 판은 재지 않았고, banker 스킬이 거의 다 안 보일 수 있습니다. \
|
|
260
|
+
플러그인 길이고 Codex 가 0.160.1 보다 낮으면 `banker doctor` 와 세션 시작 알림이 한 줄로 알립니다. 세션 시작 알림은 `/hooks` 에서 훅을 신뢰한 뒤에만 나옵니다.
|
|
241
261
|
- OMC/Claude 에 결합됐던 오케스트레이터·설치·유틸 표면(all-in-one·ultra-chain·ultra-init·front-qa·setup·setup-omc·setup-omc-hud·setup-stitch·omc-reference·compact-copy)은 본문이 **런타임 인식**이라 Codex에서도 동작합니다.
|
|
242
262
|
- `payload-mon` 은 Codex에서 실행해도 같은 머신의 Claude Code HUD 래퍼만 켜고 끕니다. \
|
|
243
263
|
32MB 요청 한도는 Claude Code 의 것이라 Codex 자신의 요청 크기는 재지 않습니다.
|
|
244
264
|
- `omc-patch` 도 Codex에서 실행하면 같은 머신의 Claude Code OMC 플러그인 캐시(`~/.claude/plugins/`)만 다룹니다. Codex 의 OMX 는 건드리지 않습니다.
|
|
245
|
-
- Codex에선 OMC 대신 **oh-my-codex(OMX)** 의 동명 스킬(ralplan·ralph·
|
|
246
|
-
-
|
|
265
|
+
- Codex에선 OMC 대신 **oh-my-codex(OMX)** 의 동명 스킬(ralplan·ralph·hud 등)과 `codex mcp`·내장 `/copy` 를 사용합니다(Codex는 `omx setup` 전제).
|
|
266
|
+
- `all-in-one`·`ultra-init` 의 마지막 QA 게이트는 두 런타임 모두 banker `ralph-qa` 입니다. 독립 검토자 3명 이상이 실행기가 돌린 `--qa` 목표의 게이트 기록으로 판정합니다.
|
|
247
267
|
- 설치기는 `~/.codex/AGENTS.md` 를 건드리지 않습니다(omx가 재생성하므로 `~/.codex/skills/` 자동 검색에 의존). \
|
|
248
268
|
예외는 사용자가 켠 `tone-compact` 와 `anti-drm` 입니다. 각각 그 파일 끝에 `USER:OMX:POLICY` 로 감싼 블록 1개를 넣고, `off` 로 뺍니다. \
|
|
249
269
|
`omx setup --merge-agents` 와 기본 `omx setup` 은 이 블록을 남깁니다. `--force` 나 team 모드를 끈 `omx setup` 처럼 AGENTS.md 를 새로 만들면 사라지므로, 그 뒤 `on` 을 다시 실행합니다.
|
|
@@ -299,14 +319,20 @@ banker uninstall # 제거
|
|
|
299
319
|
- Claude Code (마켓플레이스 경로): 스킬이 `/banker:*` 로 동작.
|
|
300
320
|
- 또는 Node.js ≥ 16.7 (npm 전역 설치 경로): `banker` CLI 제공.
|
|
301
321
|
- 일부 스킬은 별도 의존성이 필요하며 `/banker:setup` 으로 설치합니다. 의존성이 없으면 각 스킬이 실행 전에 설치부터 안내합니다.
|
|
302
|
-
- `all-in-one`, `ultra-chain`, `ultra-init`, `/banker:front-qa`: oh-my-claudecode(OMC) 5 와 같은 버전대의 `omc` CLI(`ralph` 가 `omc ralph verify` 를 부르므로 4.x CLI 로는 멈춤). Codex에서는 OMX.
|
|
322
|
+
- `all-in-one`, `ultra-chain`, `ultra-init`, `/banker:front-qa`: oh-my-claudecode(OMC) 5 와 같은 버전대의 `omc` CLI(`ralph` 가 `omc ralph verify` 를 부르므로 4.x CLI 로는 멈춤). Codex에서는 OMX. 마지막 QA 의 `ralph-qa` 는 banker 에 들어 있습니다.
|
|
303
323
|
- `audit-web-page`, `play-qa`, `ultra-ui-qa`: playwright. `3d-intro-build` 의 독립 검증(`verify-intro.mjs`)도 Node 용 playwright 패키지와 Chromium 을 씁니다(`npm i -g playwright && npx playwright install chromium`).
|
|
304
324
|
- `payload-mon`: OMC 커스텀 HUD 래퍼(`setup-omc-hud` 로 설치).
|
|
305
325
|
- `omc-patch`: Node 18 이상과 `git`(OMC 마켓플레이스 고정과 확인에 사용).
|
|
326
|
+
- `progress-mon`: Node 18 이상(npm 의존 없음). 커밋 기록을 보이려면 `git`. 서버는 기본 127.0.0.1 에만 바인드하고, `--host` 는 사설 IPv4 만 받습니다.
|
|
306
327
|
- `remains`: 테스트박스를 쓰려면 이 머신에 `ssh`, `scp`, `git`, 박스에 `tar` 와 시험에 필요한 런타임(예: Node)이 있어야 하고, SSH 키로 암호 없이 접속돼야 합니다.
|
|
307
328
|
- `ultra-chain`: 위 OMC(Codex 는 OMX), 웹 조사 수단, 시각 검토의 캡처에는 Node 용 playwright 패키지와 Chromium, OS 시험에는 `remains` 와 같은 테스트박스 조건.
|
|
308
329
|
- `/graceful-pause`: Claude Code 2.1.289 이상(mod). 그보다 오래된 Claude Code 는 명령을 등록하지 않고 한 줄로 알립니다. Codex 는 스킬 `$banker-graceful-pause` 입니다(0.144.5 에서 확인).
|
|
309
330
|
- `/progress`: mod 를 지원하는 Claude Code(2.1.286 과 2.1.296 에서 확인). 작업 중 즉시 실행은 2.1.289 이상에서 확인했습니다. mod 가 없는 Claude Code(2.1.250 에서 확인)에서는 "mod 를 지원하지않는 claude code 버전입니다" 만 보이고 모델은 호출되지 않습니다. Codex 는 스킬 `$banker-progress` 입니다(상시 패널이 아니라 부를 때마다 보임, tmux 칸은 선택).
|
|
331
|
+
- `teamwork`(Codex 전용): Node 18 이상, Codex 0.149.0 이상(`codex queue`), Linux 와 macOS. Windows 는 `on` 이 까닭을 밝히고 끝납니다. Codex 0.160.1 Windows 에서 승인 규칙 판정(`codex execpolicy check`)이 PowerShell 로 부르는 래퍼에는 맞지 않아(래퍼를 바로 부르는 꼴만 맞음) 쓸 때마다 승인을 물어야 하기 때문입니다. \
|
|
332
|
+
처음 `on` 뒤 새 세션에서 훅을 한 번 신뢰합니다(Hooks need review). 엔진 판이 오르면 훅 명령의 해시가 바뀌어 한 번 다시 묻습니다. 설치 전부터 열려 있던 세션(`on` 을 돌린 세션 포함)은 다시 열어야 훅과 승인 규칙이 적용되고(그 전에는 `role`, `send`, `reply` 마다 승인을 물음), 훅을 신뢰하기 전에는 `codex exec` 가 멈출 수 있습니다. \
|
|
333
|
+
승인 규칙은 래퍼의 `peers`, `role`, `send`, `reply`, `status`, `version` 만 허용하고 `on`, `off`, `uninstall` 은 승인을 받습니다. 래퍼와 훅은 샌드박스 밖에서 돌므로 `node`, `codex`, `ps`, `sh` 는 `on` 때 찾은 절대 경로만 쓰고, 임시 폴더, 작업 폴더와 그 git 저장소, `writable_roots` 아래의 프로그램과 Codex 홈은 거부합니다. `hooks.json` 은 banker 훅 설치와 같은 잠금과 같은 규칙(링크이거나 꼴이 다르면 바꾸지 않음)으로 고칩니다. 기록한 프로그램은 훅과 `send` 때마다 그 세션 기준으로 다시 봅니다. 피어 목록의 폴더는 훅이 기록한 세션 폴더만 제어 문자를 바꿔 보여 주고, `send --file` 은 그 세션 폴더와 임시 폴더 안의 파일만 읽습니다. `codex queue` 는 15초 시간 제한이 있습니다. \
|
|
334
|
+
남은 위험: 샌드박스 안 세션이 저장소 파일의 지시를 받으면 `send` 로 같은 기기의 더 넓은 권한 세션에 사용자 턴을 넣을 수 있습니다. 받는 쪽 방어는 훅이 넣는 규칙(피어 본문은 데이터, 위험 동작은 그 세션 사용자 확인)과 피어 턴의 `send` 금지뿐입니다. 래퍼를 거치지 않은 `codex queue` 직접 호출로 머리말을 위조할 수 있는지는 재지 않았습니다. Codex 0.165.0 은 TUI 를 `/quit` 으로 닫아도 대화를 상주 서버에서 이어 가므로, 닫은 세션도 피어 목록에 남아 받은 요청을 화면 없이 처리합니다(목록에서 빠지는 것은 24시간 활동이 없을 때). \
|
|
335
|
+
`banker uninstall --codex` 는 다른 banker 설치 길(사용자 범위 npm 스킬, Codex 플러그인)이 남아 있지 않을 때만 teamwork 도 지웁니다. 두 길이 모두 없어지면 훅은 멈추고 정리 명령을 한 번 안내합니다.
|
|
310
336
|
- `lineage`: Python 3.7+ (표준 라이브러리만 사용). RHEL8/Rocky8은 기본 `python3` 가 3.6이라 `setup-python` 등으로 3.11을 설치해 지정해야 합니다.
|
|
311
337
|
|
|
312
338
|
## 업데이트 / 제거
|
|
@@ -478,7 +504,7 @@ banker 자체는 **MIT** ([LICENSE](LICENSE)). Owner: [smallOpenSource](https://
|
|
|
478
504
|
|
|
479
505
|
| 분류 | 항목 | 라이선스 | 사용/설치 스킬 |
|
|
480
506
|
|---|---|---|---|
|
|
481
|
-
| 프레임워크 | oh-my-claudecode(OMC)·oh-my-codex(OMX), by [Yeachan-Heo](https://github.com/Yeachan-Heo) | MIT | `all-in-one`·`ultra-chain`·`ultra-init`·`/banker:front-qa`·`setup-omc` |
|
|
507
|
+
| 프레임워크 | oh-my-claudecode(OMC)·oh-my-codex(OMX), by [Yeachan-Heo](https://github.com/Yeachan-Heo) | MIT | `all-in-one`·`ultra-chain`·`ultra-init`·`/banker:front-qa`·`setup-omc`·`ultraqa`(OMX ultraqa 를 본뜸, `skills/ultraqa/NOTICE.md`) |
|
|
482
508
|
| 플러그인 | insane-search (© fivetaku, [fivetaku/gptaku_plugins](https://github.com/fivetaku/gptaku_plugins)) | MIT | `setup-insane-search` |
|
|
483
509
|
| 팀 아키텍처 팩토리 | revfactory/harness (© Minho Hwang, [revfactory/harness](https://github.com/revfactory/harness)) · Codex 포트 SaehwanPark/meta-harness | Apache-2.0 | `setup-harness-factory`(설치·구성만 안내) |
|
|
484
510
|
| 서비스(독점·상표) | Notion | 독점 | `make-notion-guide` |
|
package/bin/banker.js
CHANGED
|
@@ -12,7 +12,7 @@ const os = require('os');
|
|
|
12
12
|
const path = require('path');
|
|
13
13
|
const cp = require('child_process');
|
|
14
14
|
const { pathToFileURL } = require('url');
|
|
15
|
-
const { commandSkillText } = require('./lib/command-skill.cjs');
|
|
15
|
+
const { codexFrontmatter, commandSkillText } = require('./lib/command-skill.cjs');
|
|
16
16
|
|
|
17
17
|
const PKG_ROOT = path.resolve(__dirname, '..');
|
|
18
18
|
const MANIFEST = path.join(PKG_ROOT, 'codex', 'manifest.json');
|
|
@@ -34,15 +34,22 @@ function isoTime(t) {
|
|
|
34
34
|
return Number.isNaN(d.getTime()) ? '' : d.toISOString();
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
// What banker starts by bare name (gh, claude) runs from the home folder with Windows' search of the current folder off:
|
|
38
|
+
// on Windows the program search (cmd, and CreateProcess through libuv) looks in the current folder before PATH, and the
|
|
39
|
+
// current folder may be a project with a planted gh.exe or claude.cmd.
|
|
40
|
+
function bareSpawnOpts() {
|
|
41
|
+
return { cwd: os.homedir(), env: { ...process.env, NoDefaultCurrentDirectoryInExePath: '1' } };
|
|
42
|
+
}
|
|
43
|
+
|
|
37
44
|
// GitHub 저장소에 별을 단다 (gh CLI 인증 사용). star 는 repo 쓰기 권한이 필요 없어 인증된 어느 계정으로도
|
|
38
45
|
// 가능하다. gh 미설치/미인증/실패는 {ok:false, reason} 로 반환해 호출부가 URL 안내로 폴백하게 한다.
|
|
39
46
|
// spawn 은 테스트 주입용(기본 cp.spawnSync). 자체 timeout·오류삼킴으로 setup 을 절대 막지 않는다.
|
|
40
47
|
function starRepo(spawn = cp.spawnSync) {
|
|
41
48
|
try {
|
|
42
|
-
const v = spawn('gh', ['--version'], { stdio: 'ignore', timeout: 3000, windowsHide: true });
|
|
49
|
+
const v = spawn('gh', ['--version'], { stdio: 'ignore', timeout: 3000, windowsHide: true, ...bareSpawnOpts() });
|
|
43
50
|
if (v.error || v.status !== 0) return { ok: false, reason: 'gh CLI 없음' };
|
|
44
51
|
const r = spawn('gh', ['api', '-X', 'PUT', `/user/starred/${REPO_SLUG}`],
|
|
45
|
-
{ encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], timeout: 10000, windowsHide: true });
|
|
52
|
+
{ encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], timeout: 10000, windowsHide: true, ...bareSpawnOpts() });
|
|
46
53
|
if (r.error) return { ok: false, reason: r.error.message };
|
|
47
54
|
if (r.status !== 0) {
|
|
48
55
|
const msg = (`${r.stderr || r.stdout || ''}`).trim().split('\n')[0] || `gh exited ${r.status}`;
|
|
@@ -151,23 +158,31 @@ function readSkillName(skillMd) {
|
|
|
151
158
|
|
|
152
159
|
// Codex discovers skills by directory and expects the SKILL.md frontmatter `name:` to equal the
|
|
153
160
|
// directory name. Our Codex dir is `banker-<name>` (prefixed to avoid colliding with omx/system
|
|
154
|
-
// skills), so rewrite ONLY the first `name:` line inside the YAML frontmatter to match
|
|
155
|
-
|
|
156
|
-
|
|
161
|
+
// skills), so rewrite ONLY the first `name:` line inside the YAML frontmatter to match, and the
|
|
162
|
+
// `description:` line when the manifest gives the skill a Codex one (codexDescription).
|
|
163
|
+
function setCodexSkillName(skillMd, newName, dryRun, description) {
|
|
164
|
+
if (dryRun) { log(` [dry-run] set frontmatter name: ${newName}${description ? ' and the Codex description' : ''}`); return; }
|
|
157
165
|
let src;
|
|
158
166
|
try { src = fs.readFileSync(skillMd, 'utf8'); } catch { return; }
|
|
159
|
-
const
|
|
160
|
-
if (
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
167
|
+
const out = codexFrontmatter(src, newName, description); // no frontmatter: left untouched
|
|
168
|
+
if (out !== src) fs.writeFileSync(skillMd, out);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// The name Codex gives a skill (manifest codexName: setup-omc is setup-omx there), and Claude name to Codex name.
|
|
172
|
+
function codexNameOf(s) { return s.codexName || s.name; }
|
|
173
|
+
function codexRenames(m) { return Object.fromEntries(eligible(m).filter(s => s.codexName).map(s => [s.name, s.codexName])); }
|
|
174
|
+
|
|
175
|
+
// Installed banker-<old> skill folders whose skill Codex now names apart, as [old, new] folder names (found before the sweep).
|
|
176
|
+
function renamedInstalls(skillsDir, m) {
|
|
177
|
+
return eligible(m).filter(s => s.codexName && fs.existsSync(path.join(skillsDir, `banker-${s.name}`, 'SKILL.md')))
|
|
178
|
+
.map(s => [`banker-${s.name}`, `banker-${s.codexName}`]);
|
|
164
179
|
}
|
|
165
180
|
|
|
166
181
|
// A command as a Codex skill (bin/lib/command-skill.cjs, shared with the Codex plugin's codex/command-skills/).
|
|
167
|
-
function writeCommandSkill(src, destDir, name, dryRun) {
|
|
182
|
+
function writeCommandSkill(src, destDir, name, dryRun, codex = {}) {
|
|
168
183
|
if (dryRun) { log(` [dry-run] write command skill ${path.relative(PKG_ROOT, src)} -> ${destDir}`); return; }
|
|
169
184
|
fs.mkdirSync(destDir, { recursive: true });
|
|
170
|
-
fs.writeFileSync(path.join(destDir, 'SKILL.md'), commandSkillText(fs.readFileSync(src, 'utf8'), name, `$${name}
|
|
185
|
+
fs.writeFileSync(path.join(destDir, 'SKILL.md'), commandSkillText(fs.readFileSync(src, 'utf8'), name, `$${name}`, codex));
|
|
171
186
|
}
|
|
172
187
|
|
|
173
188
|
/* ---------- Claude Code target ---------- */
|
|
@@ -180,7 +195,7 @@ function setupClaude(dryRun) {
|
|
|
180
195
|
];
|
|
181
196
|
for (const [bin, args] of steps) {
|
|
182
197
|
if (dryRun) { log(` [dry-run] ${bin} ${args.join(' ')}`); continue; }
|
|
183
|
-
try { cp.execFileSync(bin, args, { stdio: 'inherit' }); }
|
|
198
|
+
try { cp.execFileSync(bin, args, { stdio: 'inherit', ...bareSpawnOpts() }); }
|
|
184
199
|
catch (e) { warn(` step failed (may already be applied): ${bin} ${args.join(' ')}`); }
|
|
185
200
|
}
|
|
186
201
|
log(' → skills/commands available as /banker:* (reload-plugins or restart to apply).');
|
|
@@ -195,30 +210,38 @@ function setupCodex(dryRun, scope) {
|
|
|
195
210
|
const base = codexBase(scope);
|
|
196
211
|
const skillsDir = path.join(base, 'skills');
|
|
197
212
|
const promptsDir = path.join(base, 'prompts');
|
|
213
|
+
const renames = renamedInstalls(skillsDir, m);
|
|
198
214
|
// Clean reinstall: remove any prior banker-* first so an update never leaves a stale duplicate.
|
|
199
215
|
const swept = sweepCodexArtifacts(base, dryRun);
|
|
200
216
|
if (swept) log(` swept ${swept} prior banker-* artifact(s) before reinstall.`);
|
|
201
217
|
let nSkill = 0, nCmd = 0;
|
|
202
218
|
for (const s of eligible(m)) {
|
|
203
219
|
if (s.type === 'skill') {
|
|
204
|
-
const dest = path.join(skillsDir, `banker-${s
|
|
220
|
+
const dest = path.join(skillsDir, `banker-${codexNameOf(s)}`);
|
|
205
221
|
copyDir(skillSource(s), dest, dryRun);
|
|
206
|
-
setCodexSkillName(path.join(dest, 'SKILL.md'), `banker-${s
|
|
222
|
+
setCodexSkillName(path.join(dest, 'SKILL.md'), `banker-${codexNameOf(s)}`, dryRun, s.codexDescription); // dir==name (Codex discovery)
|
|
207
223
|
nSkill++;
|
|
208
224
|
} else if (s.type === 'command') {
|
|
209
225
|
const src = path.join(PKG_ROOT, 'commands', `${s.name}.md`);
|
|
210
226
|
copyFile(src, path.join(promptsDir, `banker-${s.name}.md`), dryRun);
|
|
211
|
-
writeCommandSkill(src, path.join(skillsDir, `banker-${s.name}`), `banker-${s.name}`, dryRun);
|
|
227
|
+
writeCommandSkill(src, path.join(skillsDir, `banker-${s.name}`), `banker-${s.name}`, dryRun, { description: s.codexDescription, rename: codexRenames(m) });
|
|
212
228
|
nCmd++;
|
|
213
229
|
}
|
|
214
230
|
}
|
|
215
231
|
log(` → ${nSkill} skills -> ${path.join(base, 'skills', 'banker-*')}, ${nCmd} commands -> skills banker-* and prompts ${path.join(base, 'prompts', 'banker-*.md')}`);
|
|
232
|
+
reportRenames(renames);
|
|
216
233
|
log(' → Codex 0.144+ has no custom prompts, so each command is also a skill: invoke it as $banker-<name>.');
|
|
217
234
|
log(' → skills are invoked as `banker-<name>` (frontmatter name rewritten to match the dir).');
|
|
218
235
|
log(' → ~/.codex/AGENTS.md is NOT modified (omx regenerates it); skills auto-discovered from ~/.codex/skills/.');
|
|
219
236
|
return true;
|
|
220
237
|
}
|
|
221
238
|
|
|
239
|
+
// The skills an update installed under their new Codex name, and what a user who turned an old name off must do.
|
|
240
|
+
function reportRenames(renames) {
|
|
241
|
+
for (const [from, to] of renames) log(` 이름 바뀜: ${from} 에서 ${to} (부를 때는 $${to})`);
|
|
242
|
+
if (renames.length) log(' 옛 이름으로 끈 설정(config.toml 의 [[skills.config]])은 새 이름에 닿지 않으니 새 이름으로 다시 적으십시오.');
|
|
243
|
+
}
|
|
244
|
+
|
|
222
245
|
/* ---------- doctor ---------- */
|
|
223
246
|
// The newest Codex session record (rollout) under <base>/sessions/YYYY/MM/DD/, or null.
|
|
224
247
|
function newestRollout(base) {
|
|
@@ -264,11 +287,31 @@ function doctorCodexShape(base) {
|
|
|
264
287
|
const file = newestRollout(base);
|
|
265
288
|
if (!file) { log(' Codex record shape: no session record yet (run one Codex session, then doctor again)'); return; }
|
|
266
289
|
const r = codexShapeReport(file);
|
|
267
|
-
|
|
268
|
-
if (
|
|
269
|
-
if (!r || !r.version) { log(` ⚠ Codex record shape: ${path.basename(file)} does not open with session_meta - lineage, progress and usage counting cannot read it`); return; }
|
|
290
|
+
const early = shapeEarlyNote(r, path.basename(file));
|
|
291
|
+
if (early) { log(early); return; }
|
|
270
292
|
const mark = (ok) => (ok ? 'ok' : 'MISSING');
|
|
271
293
|
log(` Codex record shape (Codex ${r.version}, ${path.basename(file)}): turn start ${mark(r.turnStart)}, user text ${mark(r.userText)}, tool calls ${mark(r.toolCall)}`);
|
|
294
|
+
doctorShapeVerdict(r);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// What doctor says before the three checks: the first line is too long, no turn yet, or not a Codex record. Lines after
|
|
298
|
+
// session_meta of which banker reads none (no turn start, user text or tool call) are what a Codex update that changed
|
|
299
|
+
// the whole record shape leaves, so they are flagged, not taken for a session with no turn yet.
|
|
300
|
+
function shapeEarlyNote(r, name) {
|
|
301
|
+
const unread = ` ⚠ Codex record shape: ${name} does not open with session_meta - lineage, progress and usage counting cannot read it`;
|
|
302
|
+
if (!r) return unread;
|
|
303
|
+
if (r.tooLong) return ` Codex record shape: ${name} opens with a line over 8 MB, not checked`;
|
|
304
|
+
if (r.fresh) return ` Codex record shape: ${name} holds no turn yet (run one Codex turn, then doctor again)`;
|
|
305
|
+
if (r.version && !(r.turnStart || r.userText || r.toolCall)) {
|
|
306
|
+
return ` ⚠ Codex record shape (Codex ${r.version}, ${name}): it has lines after session_meta but no turn start, user text or tool call banker reads - `
|
|
307
|
+
+ 'the record shape may have changed (lineage stops, progress warns, usage counting misses); update banker. If this session has run no turn yet, run one and doctor again';
|
|
308
|
+
}
|
|
309
|
+
return r.version ? '' : unread;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// A turn opens with task_started, then the user's text. Text or tool calls with no turn start, or a turn start with no
|
|
313
|
+
// text, is a record shape banker does not know. Neither one is a session whose first turn has not begun.
|
|
314
|
+
function doctorShapeVerdict(r) {
|
|
272
315
|
if (!r.turnStart || !r.userText) log(' ⚠ banker may not read this Codex version\'s records (lineage stops, progress warns, usage counting misses); update banker');
|
|
273
316
|
else if (!r.toolCall) log(' (no tool calls: fine for a session that used no tools)');
|
|
274
317
|
}
|
|
@@ -294,6 +337,21 @@ async function warnCodexPlugin(base) {
|
|
|
294
337
|
warn(` Keep one: codex plugin remove ${ids[0].split(' ')[0]}, or banker uninstall --codex.`);
|
|
295
338
|
}
|
|
296
339
|
|
|
340
|
+
// The plugin's per-skill list was measured on Codex 0.160.1 and later; below that the banker skills may not show.
|
|
341
|
+
async function warnOldCodex(plugins) {
|
|
342
|
+
if (!plugins.length) return;
|
|
343
|
+
const r = await loadCodexRoutes();
|
|
344
|
+
const note = r.pluginVersionNote(r.codexCliVersion(cp.spawnSync));
|
|
345
|
+
if (note) log(` ⚠ ${note}`);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// A Codex home inside the folder doctor runs in (not its top .codex, which Codex's sandbox keeps read-only) is one a
|
|
349
|
+
// Codex session opened here can change from the sandbox: its config, the hook copies, the plugins.
|
|
350
|
+
async function warnCodexHomeHere(base) {
|
|
351
|
+
if (!(await loadCodexRoutes()).homeInSession(base, process.cwd())) return;
|
|
352
|
+
log(` ⚠ the Codex home ${base} is inside this folder (not its top .codex): a Codex session opened here can change its config and hooks from the sandbox; use a Codex home outside the folders you open Codex in`);
|
|
353
|
+
}
|
|
354
|
+
|
|
297
355
|
async function doctor() {
|
|
298
356
|
log(`banker v${version()} (pkg: ${PKG_ROOT})`);
|
|
299
357
|
log(`plugin.json version: ${(() => { try { return require(PLUGIN_JSON).version; } catch { return '?'; } })()}`);
|
|
@@ -306,6 +364,7 @@ async function doctor() {
|
|
|
306
364
|
try { installed = fs.readdirSync(sdir).filter(d => d.startsWith('banker-')); } catch {}
|
|
307
365
|
log(` codex CLI: ${have('codex') ? 'found' : 'NOT found'}`);
|
|
308
366
|
log(` installed banker skills in ${sdir}: ${installed.length}`);
|
|
367
|
+
await warnCodexHomeHere(base);
|
|
309
368
|
doctorCodexShape(base);
|
|
310
369
|
// Codex only discovers a skill when its dir name equals the SKILL.md `name:` — flag any mismatch.
|
|
311
370
|
const mismatched = installed
|
|
@@ -317,6 +376,8 @@ async function doctor() {
|
|
|
317
376
|
}
|
|
318
377
|
const plugins = await codexPluginInstalls(base);
|
|
319
378
|
log(` Codex plugin (codex plugin add): ${plugins.length ? plugins.join(', ') : 'not installed'}`);
|
|
379
|
+
await warnOldCodex(plugins);
|
|
380
|
+
doctorTeamwork(base);
|
|
320
381
|
// A project-scope npm install (banker setup --codex --scope project) in this folder doubles the skills here too.
|
|
321
382
|
const projectNpm = (await loadCodexRoutes()).projectNpmRoot(process.cwd());
|
|
322
383
|
if (plugins.length && (installed.length || projectNpm)) log(` ⚠ banker is installed both ways${projectNpm && !installed.length ? ` (npm in ${path.join(projectNpm, '.codex')})` : ''}: skills show twice ($banker-<name> and $banker:<name>). Keep one: banker uninstall --codex, or codex plugin remove ${plugins[0].split(' ')[0]}`);
|
|
@@ -328,13 +389,27 @@ async function doctor() {
|
|
|
328
389
|
log(' → install via /banker:setup (Claude) or the setup-* skills; skills also guide you if a dependency is missing.');
|
|
329
390
|
}
|
|
330
391
|
|
|
392
|
+
// The Codex-only teamwork skill keeps its engine, hooks and approval rule in the Codex home: say whether the programs it
|
|
393
|
+
// recorded still exist, and whether a rules/teamwork.rules it did not write sits where its rule goes.
|
|
394
|
+
function doctorTeamwork(base) {
|
|
395
|
+
let st = null;
|
|
396
|
+
try { st = JSON.parse(fs.readFileSync(path.join(base, 'teamwork', 'state.json'), 'utf8')); } catch { return; }
|
|
397
|
+
const missing = ['node', 'codex'].filter((k) => !(st.tools && st.tools[k] && fs.existsSync(st.tools[k])));
|
|
398
|
+
// The hooks' wrapper needs the engine and node only; send and reply start the recorded codex.
|
|
399
|
+
const fails = [...(missing.includes('node') ? ['its hooks stay silent'] : []), ...(missing.includes('codex') ? ['send and reply fail'] : [])];
|
|
400
|
+
log(` teamwork: ${st.enabled ? 'on' : 'off'} (engine ${st.version || '?'})${missing.length ? ` ⚠ recorded ${missing.join(', ')} missing: ${fails.join(' and ')} until $banker-teamwork on runs again` : ''}`);
|
|
401
|
+
let rules = '';
|
|
402
|
+
try { rules = fs.readFileSync(path.join(base, 'rules', 'teamwork.rules'), 'utf8'); } catch { return; }
|
|
403
|
+
if (!rules.startsWith('# teamwork ')) log(` ⚠ ${path.join(base, 'rules', 'teamwork.rules')} was not written by teamwork; teamwork leaves it as it is and asks for approval on every call`);
|
|
404
|
+
}
|
|
405
|
+
|
|
331
406
|
/* ---------- uninstall ---------- */
|
|
332
407
|
function uninstallClaude(dryRun) {
|
|
333
408
|
log('• Claude Code uninstall:');
|
|
334
409
|
if (!have('claude')) { warn(' claude CLI not found; skipping.'); return; }
|
|
335
410
|
for (const args of [['plugin', 'uninstall', PLUGIN_NAME], ['plugin', 'marketplace', 'remove', MARKETPLACE]]) {
|
|
336
411
|
if (dryRun) { log(` [dry-run] claude ${args.join(' ')}`); continue; }
|
|
337
|
-
try { cp.execFileSync('claude', args, { stdio: 'inherit' }); } catch { warn(` (not present) claude ${args.join(' ')}`); }
|
|
412
|
+
try { cp.execFileSync('claude', args, { stdio: 'inherit', ...bareSpawnOpts() }); } catch { warn(` (not present) claude ${args.join(' ')}`); }
|
|
338
413
|
}
|
|
339
414
|
}
|
|
340
415
|
function uninstallCodex(dryRun, scopes) {
|
|
@@ -358,6 +433,21 @@ function uninstallCodex(dryRun, scopes) {
|
|
|
358
433
|
}
|
|
359
434
|
}
|
|
360
435
|
|
|
436
|
+
// teamwork (codex-only) goes only when no other way of banker into this Codex home is left: the user-scope npm skills
|
|
437
|
+
// (kept by --scope project) and the Codex plugin. Its own uninstall removes its two hooks, its rule and its state.
|
|
438
|
+
// It runs only with the user scope in the sweep, so a dry run counts the npm skills as gone, as the real run finds them.
|
|
439
|
+
async function uninstallTeamwork(dryRun) {
|
|
440
|
+
const base = codexBase('user');
|
|
441
|
+
if (!fs.existsSync(path.join(base, 'teamwork'))) return;
|
|
442
|
+
const npmLeft = !dryRun && fs.existsSync(path.join(base, 'skills', 'banker-teamwork'));
|
|
443
|
+
const left = [...(npmLeft ? ['npm skills'] : []), ...(await codexPluginInstalls(base))];
|
|
444
|
+
if (left.length) { log(` teamwork kept: banker is still in this Codex home (${left.join(', ')})`); return; }
|
|
445
|
+
if (dryRun) { log(` [dry-run] teamwork uninstall in ${base}`); return; }
|
|
446
|
+
const r = cp.spawnSync(process.execPath, [path.join(PKG_ROOT, 'codex', 'skills', 'teamwork', 'scripts', 'teamwork.mjs'), 'uninstall'], { env: { ...process.env, CODEX_HOME: base }, encoding: 'utf8' });
|
|
447
|
+
if (r.status === 0) log(' removed teamwork (its hooks, approval rule and state)');
|
|
448
|
+
else warn(` teamwork not removed (exit ${r.status}): ${(r.stderr || '').trim()}`);
|
|
449
|
+
}
|
|
450
|
+
|
|
361
451
|
/* ---------- Codex hooks ---------- */
|
|
362
452
|
// bin/lib/codex-hooks.mjs is ESM; loaded lazily like telemetry-config. Hooks go into the same Codex home as the skills.
|
|
363
453
|
async function loadCodexHooks() {
|
|
@@ -374,6 +464,7 @@ async function setupCodexHooks(dryRun, scope) {
|
|
|
374
464
|
const r = ch.enableHooks(codexHookPaths(ch), ch.DEFAULT_HOOKS, PKG_ROOT);
|
|
375
465
|
if (r.code) { warn(` Codex hooks not changed: ${r.msg}`); return; }
|
|
376
466
|
log(` → Codex hooks ${ch.DEFAULT_HOOKS.join(', ')} in ${codexHookPaths(ch).hooks}${r.changed.length ? ` (changed: ${r.changed.join(', ')})` : ' (already in place)'}.`);
|
|
467
|
+
if (r.note) log(` → ${r.note}`);
|
|
377
468
|
if (r.changed.length) log(` → ${ch.TRUST_NOTE}`);
|
|
378
469
|
}
|
|
379
470
|
|
|
@@ -401,7 +492,12 @@ async function hooksCmd(sub, ids) {
|
|
|
401
492
|
}
|
|
402
493
|
const r = sub === 'enable' ? ch.enableHooks(p, want, PKG_ROOT) : ch.disableHooks(p, want);
|
|
403
494
|
if (r.code) { warn(`banker hooks: not changed: ${r.msg}`); process.exitCode = 1; return; }
|
|
495
|
+
reportHooks(sub, r, ch);
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
function reportHooks(sub, r, ch) {
|
|
404
499
|
log(`banker hooks ${sub}: ${r.changed.length ? r.changed.join(', ') : 'nothing to change'}`);
|
|
500
|
+
if (r.note) log(r.note);
|
|
405
501
|
if (sub === 'enable' && r.changed.length) log(ch.TRUST_NOTE);
|
|
406
502
|
if (r.shifted && r.shifted.length) log(`later ${r.shifted.join(', ')} hooks may need trusting again in /hooks.`);
|
|
407
503
|
}
|
|
@@ -593,7 +689,7 @@ async function main() {
|
|
|
593
689
|
if (a.claude) uninstallClaude(a.dryRun);
|
|
594
690
|
if (a.codex) {
|
|
595
691
|
uninstallCodex(a.dryRun, a.scopeExplicit ? [a.scope] : ['user', 'project']);
|
|
596
|
-
if (!a.scopeExplicit || a.scope === 'user') await uninstallCodexHooks(a.dryRun);
|
|
692
|
+
if (!a.scopeExplicit || a.scope === 'user') { await uninstallCodexHooks(a.dryRun); await uninstallTeamwork(a.dryRun); }
|
|
597
693
|
}
|
|
598
694
|
log('done.');
|
|
599
695
|
return;
|