@kaydash9999/banker-plugins 0.14.0 → 0.15.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.
Files changed (80) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CHANGELOG.md +47 -0
  4. package/README.md +23 -11
  5. package/codex/manifest.json +5 -5
  6. package/codex/transform-matrix.md +5 -5
  7. package/commands/front-qa.md +2 -2
  8. package/commands/setup.md +13 -4
  9. package/hooks/graceful-pause.mjs +222 -0
  10. package/hooks/hooks.json +2 -1
  11. package/hooks/register.mjs +12 -0
  12. package/package.json +4 -1
  13. package/skills/3d-intro-build/SKILL.md +1 -1
  14. package/skills/3d-intro-setup/SKILL.md +1 -1
  15. package/skills/all-in-one/SKILL.md +1 -1
  16. package/skills/append_wiki/SKILL.md +1 -1
  17. package/skills/arch-diagram/SKILL.md +1 -1
  18. package/skills/audit-mock/SKILL.md +1 -1
  19. package/skills/audit-security/SKILL.md +1 -1
  20. package/skills/audit-web-page/SKILL.md +1 -1
  21. package/skills/cleansing-memory/SKILL.md +1 -1
  22. package/skills/compact-copy/SKILL.md +1 -1
  23. package/skills/compact-wiki/SKILL.md +1 -1
  24. package/skills/curation/SKILL.md +1 -1
  25. package/skills/deep-init/SKILL.md +1 -1
  26. package/skills/deep-research/SKILL.md +1 -1
  27. package/skills/docs-setup/SKILL.md +1 -1
  28. package/skills/humanizer/SKILL.md +1 -1
  29. package/skills/interval-report/SKILL.md +1 -1
  30. package/skills/lineage/SKILL.md +146 -16
  31. package/skills/lineage/lineage.py +1091 -107
  32. package/skills/make-notion-guide/SKILL.md +1 -1
  33. package/skills/motion-graphic-make/SKILL.md +1 -1
  34. package/skills/motion-graphic-setup/SKILL.md +1 -1
  35. package/skills/nothing-design/SKILL.md +1 -1
  36. package/skills/obsidizer/SKILL.md +1 -1
  37. package/skills/omc-reference/SKILL.md +1 -1
  38. package/skills/payload-mon/SKILL.md +1 -1
  39. package/skills/pdf-vision-extract/SKILL.md +1 -1
  40. package/skills/play-qa/SKILL.md +1 -1
  41. package/skills/ralph-qa/SKILL.md +263 -112
  42. package/skills/ralph-qa/references/gemini-read-only.toml +9 -0
  43. package/skills/ralph-qa/references/gemini-seat.mjs +175 -0
  44. package/skills/ralph-qa/references/payload-scan.mjs +130 -0
  45. package/skills/ralph-qa/references/verifier-probe.mjs +872 -780
  46. package/skills/ready-compact/SKILL.md +1 -1
  47. package/skills/refresh-git-ignore/SKILL.md +1 -1
  48. package/skills/refresh-readme/SKILL.md +1 -1
  49. package/skills/rfp-author/SKILL.md +1 -1
  50. package/skills/setup-bypass-permissions/SKILL.md +123 -0
  51. package/skills/setup-bypass-permissions/agents/openai.yaml +4 -0
  52. package/skills/setup-bypass-permissions/scripts/bypass-permissions.mjs +381 -0
  53. package/skills/setup-bypass-permissions/scripts/fallback/bypass-permissions.ps1 +247 -0
  54. package/skills/setup-bypass-permissions/scripts/fallback/bypass-permissions.py +241 -0
  55. package/skills/{harness-factory → setup-harness-factory}/SKILL.md +3 -3
  56. package/skills/setup-insane-search/SKILL.md +1 -1
  57. package/skills/setup-java/SKILL.md +1 -1
  58. package/skills/setup-lsp/SKILL.md +1 -1
  59. package/skills/setup-mcp/SKILL.md +1 -1
  60. package/skills/setup-node/SKILL.md +1 -1
  61. package/skills/setup-omc/SKILL.md +1 -1
  62. package/skills/setup-omc-hud/SKILL.md +15 -1
  63. package/skills/setup-omc-hud/scripts/claude-update-last.mjs +247 -0
  64. package/skills/setup-playwright/SKILL.md +1 -1
  65. package/skills/setup-pwsh/SKILL.md +1 -1
  66. package/skills/setup-python/SKILL.md +1 -1
  67. package/skills/setup-sandbox/SKILL.md +1 -1
  68. package/skills/setup-stitch/SKILL.md +1 -1
  69. package/skills/setup-tmux/SKILL.md +1 -1
  70. package/skills/smart-compact/SKILL.md +1 -1
  71. package/skills/summary-wiki/SKILL.md +1 -1
  72. package/skills/tone-compact/SKILL.md +1 -1
  73. package/skills/ultra-init/SKILL.md +1 -1
  74. package/skills/ultra-interview/SKILL.md +1 -1
  75. package/skills/ultra-ui-qa/SKILL.md +1 -1
  76. package/skills/update-banker/SKILL.md +1 -1
  77. package/skills/vertical-pptx/SKILL.md +1 -1
  78. package/skills/vertical-pptx-setup/SKILL.md +1 -1
  79. package/skills/visual-ralph/SKILL.md +1 -1
  80. package/skills/graceful_pause/SKILL.md +0 -95
@@ -0,0 +1,247 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * claude-update-last: puts OMC's Claude Code update notice at the end of the statusline.
4
+ *
5
+ * node claude-update-last.mjs on add the block to the OMC custom HUD wrapper
6
+ * node claude-update-last.mjs off take it out again
7
+ * node claude-update-last.mjs status say whether it is on
8
+ *
9
+ * When a newer Claude Code is out, OMC's HUD prints "[Claude#<running>] -> <latest>
10
+ * claude update" on its main line. The omc_hud wrapper lays that line out again in
11
+ * a fixed order: the older wrapper drops segments it does not know, so the notice
12
+ * never shows, and the current one shows them dimmed before the path, mid-line.
13
+ * The block runs right before the wrapper joins its segments, takes the notice out
14
+ * of wherever it landed and adds it, dimmed, after every other segment. OMC's own
15
+ * hint on the line below ("[!] claude <latest> - paste: ! claude update") is left
16
+ * as the wrapper shows it.
17
+ *
18
+ * The wrapper is <config>/hud/omc-hud-custom.mjs, where <config> is
19
+ * $CLAUDE_CONFIG_DIR or ~/.claude; $CLAUDE_UPDATE_LAST_HUD_FILE overrides the path.
20
+ * Blocks other tools add with their own markers (payload-mon's, say) are left alone.
21
+ *
22
+ * `on` converges on the current block and is a no-op when it is in place. Both
23
+ * commands refuse markers that do not pair up, keep the text from before each
24
+ * change in <wrapper>.claude-update-last.bak, and write nothing that fails
25
+ * `node --check`. Exit status 1 means nothing was changed; 2 means an unexpected
26
+ * error stopped the command partway, so check `status`.
27
+ */
28
+ import { spawnSync } from "node:child_process";
29
+ import { accessSync, constants, mkdtempSync, readFileSync, realpathSync, renameSync, rmSync, writeFileSync } from "node:fs";
30
+ import { homedir, tmpdir } from "node:os";
31
+ import { join } from "node:path";
32
+ import { fileURLToPath } from "node:url";
33
+
34
+ const OPEN = "// >>> claude-update-last >>>";
35
+ const CLOSE = "// <<< claude-update-last <<<";
36
+ // A block's body never crosses another opening marker, so a stray one above a
37
+ // block is left over (and refused) instead of taking the code between with it.
38
+ const BLOCKS =
39
+ /^[ \t]*\/\/ >>> claude-update-last >>>(?:(?!\/\/ >>> claude-update-last >>>)[\s\S])*?\/\/ <<< claude-update-last <<<[ \t]*(?:\r?\n|(?![\s\S]))/gm;
40
+ // The block goes right before the line that joins the segments into the statusline.
41
+ const JOIN_LINE = /^ {2}let result = colored\.join\(SEP\);\r?$/gm;
42
+ // What the block reads at that line, all in the wrapper's own scope there.
43
+ const NAMES = [/\bconst segs\b/, /\bconst colored\b/, /\bconst stripAnsi\b/, /\bconst A = /];
44
+
45
+ const CONFIG_DIR = process.env.CLAUDE_CONFIG_DIR || join(homedir(), ".claude");
46
+
47
+ const DEFAULTS = {
48
+ hudFile: process.env.CLAUDE_UPDATE_LAST_HUD_FILE || join(CONFIG_DIR, "hud", "omc-hud-custom.mjs"),
49
+ };
50
+
51
+ // OMC 5.6.1 renders the notice as `[Claude${tag}] -> ${latest} claude update`, the
52
+ // tag being "#<running version>" or empty. The block's names are block-scoped, so
53
+ // none can clash with the wrapper's own.
54
+ const BLOCK = [
55
+ OPEN,
56
+ "// claude-update-last (setup-omc-hud): OMC's Claude Code update notice",
57
+ '// ("[Claude#X] -> Y claude update") goes after every other segment.',
58
+ "// `claude-update-last off` removes this block; on any error the order stays as it was.",
59
+ "try {",
60
+ String.raw` const notice = /^\[Claude(?:#[^\]]*)?\]\s*->\s*\S+\s+claude\s+update\b/;`,
61
+ " const plain = (s) => stripAnsi(String(s)).trim();",
62
+ " const found = segs.find((s) => notice.test(plain(s)));",
63
+ " if (found) {",
64
+ ' const moved = A("2", plain(found));',
65
+ " for (let i = colored.length - 1; i >= 0; i--) if (notice.test(plain(colored[i]))) colored.splice(i, 1);",
66
+ " colored.push(moved);",
67
+ " }",
68
+ "} catch {",
69
+ " /* keep the order the wrapper chose */",
70
+ "}",
71
+ CLOSE,
72
+ ];
73
+
74
+ // The block as `on` writes it, in the line endings of the line it goes before.
75
+ const blockText = (eol) => BLOCK.map((line) => " " + line).join(eol) + eol;
76
+
77
+ const count = (text, needle) => text.split(needle).length - 1;
78
+ // Markers that do not pair up, in number or in order: removing the blocks leaves one behind.
79
+ const unpaired = (src) => {
80
+ const rest = src.replace(BLOCKS, "");
81
+ return rest.includes(OPEN) || rest.includes(CLOSE);
82
+ };
83
+ const PAIR = "claude-update-last 표시(>>> / <<<)의 짝이 맞지 않습니다(개수나 순서)";
84
+
85
+ // Every line that joins the segments, as [offset, line ending].
86
+ const joinLines = (src) => [...src.matchAll(JOIN_LINE)].map((m) => [m.index, m[0].endsWith("\r") ? "\r\n" : "\n"]);
87
+
88
+ // The wrapper's text, null when there is no such file. Any other read failure
89
+ // (permissions, say) is not "missing" and propagates.
90
+ const readText = (file) => {
91
+ try {
92
+ return readFileSync(file, "utf8");
93
+ } catch (e) {
94
+ if (e.code === "ENOENT" || e.code === "ENOTDIR") return null;
95
+ throw e;
96
+ }
97
+ };
98
+
99
+ const refusal = (why, hudFile) => ({ ok: false, message: `${why}. 래퍼를 그대로 두었습니다: ${hudFile}` });
100
+
101
+ // The block exactly as `on` writes it, once, right before the one joining line.
102
+ function inPlace(src) {
103
+ if (count(src, OPEN) !== 1 || count(src, CLOSE) !== 1) return false;
104
+ const lines = joinLines(src);
105
+ if (lines.length !== 1) return false;
106
+ const [at, eol] = lines[0];
107
+ const block = blockText(eol);
108
+ return src.slice(at - block.length, at) === block;
109
+ }
110
+
111
+ // Why the block cannot go into this wrapper, or "" when it can. Markers that do
112
+ // not pair up would let the block pattern swallow the code between them.
113
+ function misfit(src) {
114
+ if (unpaired(src)) return PAIR;
115
+ const base = src.replace(BLOCKS, "");
116
+ if (!base.includes("omc-hud.mjs")) return "OMC 커스텀 HUD 래퍼가 아닙니다";
117
+ const places = joinLines(base).length;
118
+ if (places === 0) return "삽입 위치를 찾지 못했습니다(세그먼트를 합치는 colored.join(SEP) 줄이 없음)";
119
+ if (places > 1) return "삽입 위치가 두 곳 이상입니다(colored.join(SEP) 줄이 여러 개)";
120
+ if (!NAMES.every((name) => name.test(base))) return "블록이 쓰는 이름(segs, colored, stripAnsi, A)을 래퍼에서 찾지 못했습니다";
121
+ return "";
122
+ }
123
+
124
+ function insertBlock(base) {
125
+ const [[at, eol]] = joinLines(base);
126
+ return base.slice(0, at) + blockText(eol) + base.slice(at);
127
+ }
128
+
129
+ // Replaces file through a fresh temp file ("wx") and a rename: a link planted at
130
+ // either name is replaced rather than written through, and a write that fails
131
+ // leaves the old file as it was.
132
+ function writeFresh(file, data) {
133
+ const tmp = `${file}.${process.pid}.tmp`;
134
+ rmSync(tmp, { force: true });
135
+ try {
136
+ writeFileSync(tmp, data, { flag: "wx" });
137
+ renameSync(tmp, file);
138
+ } catch (e) {
139
+ rmSync(tmp, { force: true });
140
+ throw e;
141
+ }
142
+ }
143
+
144
+ // The first lines of node's complaint about `text` as an ES module, "" if it parses.
145
+ function syntaxError(text) {
146
+ const dir = mkdtempSync(join(tmpdir(), "claude-update-last-"));
147
+ try {
148
+ const file = join(dir, "check.mjs");
149
+ writeFileSync(file, text);
150
+ const r = spawnSync(process.execPath, ["--check", file], { encoding: "utf8" });
151
+ return r.status === 0 ? "" : String(r.stderr || r.error).trim().split("\n").slice(0, 3).join(" | ");
152
+ } finally {
153
+ rmSync(dir, { recursive: true, force: true });
154
+ }
155
+ }
156
+
157
+ // Writes `after` over the wrapper if it parses, keeping `before` in the .bak.
158
+ function commit(hudFile, before, after, done) {
159
+ const err = syntaxError(after);
160
+ if (err) return { ok: false, message: `node --check 실패로 래퍼를 그대로 두었습니다: ${err}` };
161
+ try {
162
+ accessSync(hudFile, constants.W_OK);
163
+ } catch (e) {
164
+ return refusal(`래퍼에 쓸 권한이 없습니다(${e.code || e.message})`, hudFile);
165
+ }
166
+ writeFresh(`${hudFile}.claude-update-last.bak`, before);
167
+ writeFileSync(hudFile, after);
168
+ return { ok: true, message: done };
169
+ }
170
+
171
+ export function turnOn(opts = {}) {
172
+ const o = { ...DEFAULTS, ...opts };
173
+ const src = readText(o.hudFile);
174
+ if (src === null) return { ok: false, message: `HUD 래퍼가 없습니다: ${o.hudFile}` };
175
+ if (inPlace(src)) return { ok: true, message: "이미 켜져 있습니다 (변경 없음)." };
176
+ const why = misfit(src);
177
+ if (why) return refusal(why, o.hudFile);
178
+ const done = "켰습니다. 다음 statusline 갱신부터 Claude Code 갱신 안내가 줄 맨 끝에 표시됩니다.";
179
+ return commit(o.hudFile, src, insertBlock(src.replace(BLOCKS, "")), done);
180
+ }
181
+
182
+ export function turnOff(opts = {}) {
183
+ const o = { ...DEFAULTS, ...opts };
184
+ const src = readText(o.hudFile);
185
+ if (src === null) return { ok: true, message: `HUD 래퍼가 없어 끌 것이 없습니다: ${o.hudFile}` };
186
+ if (unpaired(src)) return refusal(PAIR, o.hudFile);
187
+ const out = src.replace(BLOCKS, "");
188
+ if (out === src) return { ok: true, message: "이미 꺼져 있습니다 (래퍼 변경 없음)." };
189
+ return commit(o.hudFile, src, out, "껐습니다. 다음 statusline 갱신부터 원래 순서로 표시됩니다.");
190
+ }
191
+
192
+ function stateOf(src) {
193
+ if (src === null) return "HUD 래퍼 없음";
194
+ if (count(src, OPEN) + count(src, CLOSE) === 0) return "꺼짐";
195
+ // on and off both refuse this, so pointing at on would be a dead end.
196
+ if (unpaired(src)) return "표시(>>> / <<<)의 짝이 맞지 않습니다 (on, off 모두 거부: HUD 재설치 또는 남은 표시 줄 정리)";
197
+ return inPlace(src) ? "켜짐" : "켜짐이 불완전하거나 오래됨 (on 으로 복구)";
198
+ }
199
+
200
+ // What status says about the wrapper. A wrapper it cannot read is reported, not
201
+ // thrown: status is where an exit 2 sends the user to look.
202
+ function describe(o) {
203
+ try {
204
+ return stateOf(readText(o.hudFile));
205
+ } catch (e) {
206
+ return `HUD 래퍼를 읽을 수 없음 (${e.code || e.message})`;
207
+ }
208
+ }
209
+
210
+ export function status(opts = {}) {
211
+ const o = { ...DEFAULTS, ...opts };
212
+ return { ok: true, message: `claude-update-last: ${describe(o)} (${o.hudFile})` };
213
+ }
214
+
215
+ const COMMANDS = new Map([
216
+ ["on", turnOn],
217
+ ["off", turnOff],
218
+ ["status", status],
219
+ ]);
220
+
221
+ function main(arg) {
222
+ const run = COMMANDS.get(arg);
223
+ if (!run) {
224
+ process.stdout.write("사용법: claude-update-last on | off | status\n");
225
+ return 1;
226
+ }
227
+ try {
228
+ const { ok, message } = run();
229
+ process.stdout.write(message + "\n");
230
+ return ok ? 0 : 1;
231
+ } catch (e) {
232
+ process.stdout.write(`예기치 못한 오류로 중단했습니다: ${e.message}\nstatus 로 상태를 확인하세요.\n`);
233
+ return 2;
234
+ }
235
+ }
236
+
237
+ // Run as a command, also when reached through a symlinked path: Node resolves
238
+ // symlinks for import.meta.url but not for process.argv[1].
239
+ const invokedDirectly = () => {
240
+ try {
241
+ return realpathSync(process.argv[1]) === fileURLToPath(import.meta.url);
242
+ } catch {
243
+ return false;
244
+ }
245
+ };
246
+
247
+ if (invokedDirectly()) process.exitCode = main((process.argv[2] || "status").toLowerCase());
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: setup-playwright
3
- description: "(banker) Playwright + headless 브라우저를 OS·권한·conda 감지 후 설치(RHEL8/Rocky8·non-root·no-conda·xvfb 폴백). 'setup-playwright'/'playwright 설치' 또는 /banker:setup 시 사용."
3
+ description: "Playwright 와 헤드리스 브라우저를 OS, 권한, conda 유무에 맞춰 설치. RHEL8, Rocky8, root 권한이 없는 환경도 지원하고 필요하면 xvfb 를 씀. 'setup-playwright'/'playwright 설치' 또는 `/banker:setup` 시 사용."
4
4
  ---
5
5
 
6
6
  # setup-playwright — Playwright + headless 브라우저 설치 (OS·권한 적응형)
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: setup-pwsh
3
- description: "(banker) Windows PowerShell 7 + Git + $PROFILE(UTF-8 무BOM) 환경을 winget 으로 설치·검증(비-Windows 는 감지 후 no-op). 'setup-pwsh'/'PowerShell 설치'/'pwsh 환경 설정' 또는 /banker:setup 시 사용."
3
+ description: "Windows 에 PowerShell 7 과 Git 을 winget 으로 설치하고, `$PROFILE` 을 BOM 없는 UTF-8 로 설정한 뒤 검증. Windows 가 아니면 감지만 하고 아무것도 바꾸지 않음. 'setup-pwsh'/'PowerShell 설치'/'pwsh 환경 설정' 또는 `/banker:setup` 시 사용."
4
4
  ---
5
5
 
6
6
  # setup-pwsh: Windows PowerShell 7 환경 설치
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: setup-python
3
- description: "(banker) Python 3.11+ 런타임 + pipx·uv 설치(OS별 PEP668·RHEL8 3.6 회피). 라이브러리(pptx·pymupdf)는 docs-setup 담당, 본 스킬은 런타임만. 'setup-python'/'Python 설치'/'pipx·uv 설치' 또는 /banker:setup 시 사용."
3
+ description: "Python 3.11 이상과 pipx, uv 를 설치. OS별 PEP 668 제약과 RHEL8 의 기본 3.6 을 피해 감. 라이브러리(python-pptx, pymupdf)는 `docs-setup` 이 맡고 이 스킬은 런타임만 설치. 'setup-python'/'Python 설치'/'pipx 설치'/'uv 설치' 또는 `/banker:setup` 시 사용."
4
4
  ---
5
5
 
6
6
  # setup-python: Python 3.11+ 런타임 + pipx·uv 설치
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: setup-sandbox
3
- description: "(banker) 에이전트 샌드박스 공통 기반(Linux bubblewrap+socat+sysctl userns, macOS Seatbelt, Windows AppContainer)을 OS 감지 후 설치(+rust/cargo·git safe.directory 폴드인). 'setup-sandbox'/'샌드박스 설치'/'bubblewrap 설치' 또는 /banker:setup 시 사용."
3
+ description: "OS 를 감지해 에이전트 샌드박스의 공통 기반을 설치. Linux 는 bubblewrap, socat, userns 설정, macOS 는 Seatbelt, Windows 는 AppContainer. rust 와 cargo 도 설치하고 git 의 `safe.directory` 를 설정. 'setup-sandbox'/'샌드박스 설치'/'bubblewrap 설치' 또는 `/banker:setup` 시 사용."
4
4
  ---
5
5
 
6
6
  # setup-sandbox: 에이전트 샌드박스 설치
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: setup-stitch
3
- description: "(banker) Stitch(Google 디자인 생성) MCP 프록시를 claude mcp add(Codex는 codex mcp add)로 등록(시크릿 미커밋). 'setup-stitch'/'stitch 설치'/'stitch mcp' 또는 /banker:setup 시 사용."
3
+ description: "Google 의 디자인 생성 서비스인 Stitch 의 MCP 프록시를 `claude mcp add`(Codex 는 `codex mcp add`)로 등록. 시크릿은 커밋하지 않음. 'setup-stitch'/'stitch 설치'/'stitch mcp' 또는 `/banker:setup` 시 사용."
4
4
  ---
5
5
 
6
6
  # setup-stitch — Stitch MCP 프록시 등록
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: setup-tmux
3
- description: "(banker) OMC team·worktree 세션과 Codex OMX $team·HUD 가 요구하는 tmux(Windows는 psmux)를 OS 감지 후 설치·소스빌드(Rocky8 3.6a). 'setup-tmux'/'tmux 설치'/'psmux 설치' 또는 /banker:setup 시 사용."
3
+ description: "OMC 의 `team` 과 worktree 세션, OMX 의 `$team` 과 HUD 에 필요한 tmux 를 OS 에 맞춰 설치(Windows 는 psmux). Rocky8 은 3.6a 를 소스에서 빌드. 'setup-tmux'/'tmux 설치'/'psmux 설치' 또는 `/banker:setup` 시 사용."
4
4
  ---
5
5
 
6
6
  # setup-tmux: tmux(Windows는 psmux) 설치
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: smart-compact
3
- description: "(banker) 컨텍스트 임계(기본 50%) 초과 시 append-wiki→ready-compact 자동 실행(마지막 메시지가 resume 프롬프트뿐) + /copy·/compact·paste 유저 핸드오프 게이트. 'smart-compact' 활성화 / '--cancel' 해제."
3
+ description: "컨텍스트 사용률이 임계(기본 50%)를 넘으면 `append_wiki` 와 `ready-compact` 를 자동 실행해 마지막 메시지에 resume 프롬프트만 남김. `/copy`, `/compact`, 붙여 넣기는 사용자가 직접 함. 'smart-compact' 로 켜고 `--cancel` 로 끔."
4
4
  ---
5
5
 
6
6
  # smart-compact — 컨텍스트 위생 자동 게이트
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: summary-wiki
3
- description: "(banker) 지금까지 쌓인 위키 페이지 전량을 docs/ 아래 단일 파일로 개조식 요약. 사용자가 아는 지식과 위키에 쌓인 내용의 차이를 식별하는 sync 검토용. 읽기 전용이며 stale 한 wiki_list 대신 파일을 직접 열거한다. 'summary-wiki'/'위키 요약'/'위키 지식 동기화'/'위키 digest' 시 사용."
3
+ description: "지금까지 쌓인 위키 페이지 전부를 `docs/` 아래 단일 파일로 개조식 요약. 사용자가 아는 지식과 위키 내용의 차이를 찾는 동기화 검토용. 읽기 전용이며, 낡은 목록을 줄 수 있는 `wiki_list` 대신 파일을 직접 열거함. 'summary-wiki'/'위키 요약'/'위키 지식 동기화'/'위키 digest' 시 사용."
4
4
  ---
5
5
 
6
6
  # summary-wiki: 위키 전량을 docs/ 단일 파일로 개조식 요약 (sync 검토용)
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: tone-compact
3
- description: "(banker) 답변과 새 문서를 ASD-STE100 기반 한글 개조식(표, 목록, 원어 발음 표기, 장식 기호 금지)으로 간결하게 쓰는 문체 규칙을 켜고 끔. 인자가 없으면 on, off 할 때까지 모든 세션에 유지. 'tone-compact'/'간결체 켜'/'개조식으로 답해'/'문체 규칙 켜/꺼' 시 사용."
3
+ description: "답변과 새 문서를 ASD-STE100 에 기반한 한글 개조식으로 간결하게 쓰는 문체 규칙을 켜고 끔. 표와 목록, 원어 발음 표기를 쓰고 장식 기호는 금지. 인자가 없으면 `on`. `off` 할 때까지 모든 세션에 유지. 'tone-compact'/'간결체 켜'/'개조식으로 답해'/'문체 규칙 켜/꺼' 시 사용."
4
4
  argument-hint: "on | off | status"
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: ultra-init
3
- description: "(banker) 아이디어·러프 브리프·그린필드를 계획→구현→QA 통과까지 핸즈오프 1회 자율 실행(ralplan→ralph→QA 게이트: Claude Code는 verify 순환, Codex는 ultraqa). 'ultra-init'/'알아서 만들어'/'핸즈오프 빌드'/'idea to passing' 시 사용."
3
+ description: "아이디어나 대략적인 요구, 새 프로젝트를 한 번의 지시로 받아 계획, 구현, QA 통과까지 자율 실행. `ralplan`, `ralph`, 독립 QA 게이트(Claude Code 는 `verify` 순환, Codex 는 `ultraqa`)를 차례로 씀. 'ultra-init'/'알아서 만들어'/'핸즈오프 빌드'/'idea to passing' 시 사용."
4
4
  argument-hint: "[--short|--deliberate] [--gated] [--qa tests,build,lint,typecheck] [--critic=architect|critic|codex] <브리프 / 만들 것>"
5
5
  level: 4
6
6
  ---
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: ultra-interview
3
- description: "(banker) 리서치를 선행해 사람에게 묻는 질문을 최소화하면서, 이산 체크리스트로 센 모호성이 3% 이하가 될 때까지 인터뷰를 반복. 공개 정보·맥락이 답하는 항목은 질문이 아니라 가정으로 제시. 'ultra-interview'/'울트라 인터뷰'/'리서치 선행 인터뷰'/'요구사항 확정' 시 사용."
3
+ description: "리서치를 선행해 사람에게 묻는 질문을 최소화하면서, 이산 체크리스트로 센 모호성이 3% 이하가 될 때까지 인터뷰를 반복. 공개 정보나 맥락이 답하는 항목은 질문이 아니라 가정으로 제시. 'ultra-interview'/'울트라 인터뷰'/'리서치 선행 인터뷰'/'요구사항 확정' 시 사용."
4
4
  ---
5
5
 
6
6
  # ultra-interview: 리서치 선행 인터뷰 (모호성 3% 이하까지)
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: ultra-ui-qa
3
- description: "(banker) 웹 UI를 playwright로 렌더해 디자인 SoT(PDF/스펙)와 1:1 대조 + 내부개념 텍스트 누출 점검(HTTP 200만으로 PASS 금지). 'ultra ui qa'/'UI 대조'/'디자인 PDF와 대조'/'어색한 내용 점검' 시 사용."
3
+ description: "웹 UI 를 Playwright 로 렌더해 디자인 원본(PDF 나 스펙)과 1:1 로 대조하고, 내부 개념 텍스트가 화면에 새는지 점검. HTTP 200 만으로는 통과시키지 않음. 'ultra ui qa'/'UI 대조'/'디자인 PDF와 대조'/'어색한 내용 점검' 시 사용."
4
4
  ---
5
5
 
6
6
  # ultra-ui-qa — 라이브 UI ↔ SoT 엄격 대조 + 내부개념 누출 점검
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: update-banker
3
- description: "(banker) 설치된 banker 를 최신 배포본으로 갱신. Claude 플러그인·npm 전역 CLI·Codex 3채널이 독립 드리프트하므로 npm 우선 게이트 후 채널별 갱신·3-프로브 검증. 'update-banker'/'banker 업데이트'/'banker 최신화'/'banker 드리프트' 시 사용."
3
+ description: "설치된 banker 를 최신 배포본으로 갱신. 세 채널(Claude Code 플러그인, npm 전역 CLI, Codex)은 따로 드리프트함. npm 전역 CLI 를 먼저 올려 최신 버전과 같을 때만 나머지 채널을 갱신하고, 채널마다 검증. 'update-banker'/'banker 업데이트'/'banker 최신화'/'banker 드리프트' 시 사용."
4
4
  ---
5
5
 
6
6
  # update-banker: 설치된 banker 3채널 갱신 (Claude 플러그인·npm 전역 CLI·Codex)
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: vertical-pptx
3
- description: "(banker) A4 세로(210x297mm) 규격 PPTX 생성·점검·수리와 16:9 덱의 A4 세로 변환. 'A4 세로 pptx'/'세로형 슬라이드'/'인쇄용 pptx'/'vertical-pptx' 시 사용."
3
+ description: "A4 세로(210x297mm) 규격의 PPTX 를 생성, 검증, 수리. 16:9 덱을 A4 세로로 변환하기도 함. 'A4 세로 pptx'/'세로형 슬라이드'/'인쇄용 pptx'/'vertical-pptx' 시 사용."
4
4
  ---
5
5
 
6
6
  # vertical-pptx - A4 세로(210x297mm) 규격 PPTX
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: vertical-pptx-setup
3
- description: "(banker) vertical-pptx 의존성(pptxgenjs·python-pptx)과 시각 검증용 LibreOffice 를 OS·권한 감지 후 설치(root 없으면 홈 프리픽스 추출). 'vertical-pptx-setup'/'LibreOffice 설치'/'pptx 렌더 검증 준비' 또는 /banker:setup 시 사용."
3
+ description: "`vertical-pptx` 의 의존성(pptxgenjs, python-pptx)과 시각 검증용 LibreOffice 를 OS 와 권한에 맞춰 설치. root 권한이 없으면 홈 프리픽스에 풀어 설치. 'vertical-pptx-setup'/'LibreOffice 설치'/'pptx 렌더 검증 준비' 또는 `/banker:setup` 시 사용."
4
4
  ---
5
5
 
6
6
  # vertical-pptx-setup — vertical-pptx 실행·검증 환경 설치
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: visual-ralph
3
- description: "(banker) 프론트엔드 UI를 레퍼런스(생성/정적/라이브 URL) 기준으로 측정 빌드: ralph 구현→Visual Verdict(≥90)+픽셀 diff 반복→재사용 디자인 시스템. 'visual-ralph'/'비주얼 랄프'/'UI 클론'/'레퍼런스대로 구현' 시 사용."
3
+ description: "프론트엔드 UI 를 레퍼런스(생성 이미지, 정적 이미지, 라이브 URL)에 맞춰 측정하며 구현. `ralph` 가 구현하고 Visual Verdict 점수가 90 이상이 될 때까지 픽셀 비교와 수정을 반복한 뒤, 재사용 디자인 시스템으로 정리. 'visual-ralph'/'비주얼 랄프'/'UI 클론'/'레퍼런스대로 구현' 시 사용."
4
4
  ---
5
5
 
6
6
  # visual-ralph — 측정 기반 비주얼 빌드 루프
@@ -1,95 +0,0 @@
1
- ---
2
- name: graceful_pause
3
- description: "(banker) 진행 중인 작업을 지금 단계까지만 마무리하고 멈춘 뒤, 상태를 보고하고 사용자 중간 지시를 받을 준비를 함. cancel 과 달리 모드 상태와 계획을 지우지 않음. 작업 중 대기 입력으로 넣어 두면 읽히는 시점에 동작. 'graceful_pause'/'잠깐 멈춰'/'지금 단계만 끝내고 멈춰'/'중간 지시' 시 사용."
4
- argument-hint: "[멈춘 뒤 다룰 지시나 메모]"
5
- ---
6
-
7
- # graceful_pause: 지금 단계만 끝내고 멈춤
8
-
9
- 인자: `$ARGUMENTS`
10
- - 선택. 멈춘 뒤 다룰 지시나 메모
11
- - Codex: 사용자 메시지에서 읽음
12
-
13
- ## 동작 시점
14
-
15
- - 작업 도중 사용자가 대기 입력으로 넣어 두면, 큐에서 넘어와 이 스킬을 읽는 시점에 동작
16
- - 즉시 끊는 장치 없음. 읽기 전에 끝난 동작은 되돌리지 않음
17
- - 바로 끊어야 하면 Esc. 이 스킬의 몫이 아님
18
- - 함께 들어온 다른 대기 입력: 이 스킬 먼저 처리. 나머지는 정지 보고의 "받은 지시"에 넣음
19
- - 이미 작업이 끝난 뒤에 읽혔으면 1단계와 2단계는 건너뛰고 정지 보고부터 시작
20
-
21
- ## cancel 과 차이
22
-
23
- | 항목 | graceful_pause | cancel |
24
- |---|---|---|
25
- | 진행 중인 단계 | 끝까지 마무리 | 그 자리에서 중단 |
26
- | 켜져 있는 모드 | 그대로 둠 | 실행을 끝냄 |
27
- | 모드가 남기는 기록 | 손대지 않음 | 모드마다 다름. ralph 상태는 지우고, autopilot 진행 상황과 ultragoal 원장은 남김 |
28
- | 이후 | 지시를 받아 같은 흐름 재개 | 모드를 다시 시작해 남은 기록부터 이어 감 |
29
-
30
- ## 절차
31
-
32
- 1. 지금 단계 확인
33
- - 지금 단계: 이미 시작한 도구 동작 하나와, 그 동작이 남긴 불일치를 닫는 최소 작업
34
- - 예: 함수 이름을 바꾸던 중이면 그 이름을 쓰는 곳까지 바꿈
35
- - 포함하지 않음: 스토리나 할 일 목록의 다음 항목
36
- 2. 지금 단계 마무리
37
-
38
- | 진행 중인 동작 | 처리 |
39
- |---|---|
40
- | 파일 수정 | 그 파일을 일관된 상태까지 수정. 반쯤 고친 파일을 남기지 않음 |
41
- | 실행 중인 명령이나 테스트 | 결과 받기 |
42
- | 백그라운드 작업 | 멈추지 않음. 이름과 출력 위치만 기록 |
43
- | 이미 띄운 하위 에이전트 | 결과를 기다리거나 백그라운드로 둠. 새로 띄우지 않음 |
44
-
45
- 3. 하지 않는 것
46
- - 다음 단계 시작 (예: 다음 파일, 다음 스토리)
47
- - 되돌리기 어려운 동작
48
- - 커밋과 push
49
- - 배포와 게시
50
- - 삭제와 외부 전송
51
- - 모드 상태와 계획 파일 삭제. `cancel` 실행
52
- 4. 정지 보고. 대화에만 짧게
53
-
54
- | 항목 | 내용 |
55
- |---|---|
56
- | 끝낸 단계 | 방금 마무리한 것 |
57
- | 현재 상태 | 검증 결과와 커밋하지 않은 변경 |
58
- | 진행 중인 것 | 실행 중인 백그라운드 작업과 켜져 있는 모드 |
59
- | 다음 예정 단계 | 1개에서 3개 |
60
- | 열린 결정 | 사용자 판단이 필요한 것 |
61
- | 받은 지시 | 인자 메모와 함께 들어온 대기 입력. 그 지시가 계획에 주는 영향 |
62
-
63
- 5. 지시 대기
64
-
65
- | 런타임 | 방법 |
66
- |---|---|
67
- | Claude Code | `AskUserQuestion` 으로 질문. 선택지는 계획대로 계속, 지시 반영 후 계속(자유 입력), 상태를 둔 채 중단. 질문이 열려 있는 동안은 응답이 끝나지 않으므로 ralph 같은 지속 모드도 끼어들지 않음 |
68
- | Codex | 구조화 질문 도구(`request_user_input` 등)가 있으면 사용. tmux 안이면 `omx question` 도 가능. 둘 다 없을 때는 아래 표 |
69
-
70
- - Codex 에서 질문 도구가 없을 때
71
-
72
- | 지속 모드 (ralph, ultraqa, team 등) | 처리 |
73
- |---|---|
74
- | 꺼짐 | 짧은 질문 하나로 응답 종료 |
75
- | 켜짐 | 응답을 끝내도 그 모드의 Stop 훅이 작업을 다시 이어 가게 하므로 멈출 수 없음. 이 사실을 정지 보고에 적고, 계속할지 `cancel` 할지 묻기 |
76
-
77
- 6. 재개
78
-
79
- | 사용자 답 | 처리 |
80
- |---|---|
81
- | 계속 | 다음 예정 단계부터 진행 |
82
- | 새 지시 | 영향받는 단계를 다시 계획. 범위가 바뀌면 바뀐 계획을 먼저 보여 주고 승인 뒤 진행 |
83
- | 중단 | 상태를 둔 채 멈춤. 세션을 끝낼 예정이면 `ready-compact --hand-off` 로 새 세션용 노트와 프롬프트 준비를 안내 |
84
- | 취소 | 사용자가 명시할 때만 `cancel` 실행 |
85
-
86
- - 중단 중인 지속 모드
87
- - Claude Code: 응답이 끝날 때마다 OMC Stop 훅이 한 번씩 계속하라는 메시지를 넣음. 사용자가 재개를 말할 때까지 작업을 진행하지 않고 정지 중이라는 한 줄만 답함
88
- - 예외: 직전 출력이 `ready-compact` 의 resume 프롬프트였다면 그 한 줄 대신 같은 프롬프트를 그대로 다시 출력. 마지막 메시지가 프롬프트여야 `/copy` 가 맞는 것을 복사함
89
- - 이 메시지까지 멈추려면 `cancel` 이 필요함을 알림. 그 모드가 남기는 기록은 위 표의 cancel 열
90
-
91
- ## 함정
92
-
93
- - 정지 보고를 핑계로 다음 단계를 미리 하지 않음
94
- - 정지 중 받은 계속 신호(훅 메시지)는 사용자 승인이 아님. 사용자가 재개를 말할 때까지 모든 응답에 해당
95
- - 정지 중 도착한 백그라운드 작업 결과: 보고에 추가만 함. 후속 작업은 시작하지 않음