@dmsdc-ai/aigentry-deliberation 0.0.20 → 0.0.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -0
- package/browser-control-port.js +0 -9
- package/index.js +60 -12
- package/install.js +89 -1
- package/observer.js +11 -3
- package/package.json +1 -1
- package/session-monitor-win.js +1 -1
- package/skills/deliberation/SKILL.md +5 -0
- package/skills/deliberation-gate/SKILL.md +212 -0
package/README.md
CHANGED
|
@@ -31,6 +31,8 @@ npx @dmsdc-ai/aigentry-deliberation install
|
|
|
31
31
|
2. npm 의존성 설치
|
|
32
32
|
3. `~/.claude/.mcp.json`에 MCP 서버 자동 등록
|
|
33
33
|
4. Claude Code 재시작하면 바로 사용 가능
|
|
34
|
+
5. Gemini CLI MCP 서버 자동 등록 (`~/.gemini/settings.json`)
|
|
35
|
+
6. deliberation-gate 스킬 자동 설치 (`~/.claude/skills/deliberation-gate/`)
|
|
34
36
|
|
|
35
37
|
### 기타 설치 방법
|
|
36
38
|
|
|
@@ -53,6 +55,8 @@ cd aigentry-deliberation && npm install && node install.js
|
|
|
53
55
|
npx @dmsdc-ai/aigentry-deliberation uninstall
|
|
54
56
|
```
|
|
55
57
|
|
|
58
|
+
MCP 서버 등록 해제 + 설치 파일 삭제 + 스킬 파일 정리까지 자동 처리됩니다.
|
|
59
|
+
|
|
56
60
|
## Forum Demo
|
|
57
61
|
|
|
58
62
|
Deliberation이 완료되면 결과를 시각화하는 Forum View를 생성합니다.
|
|
@@ -68,6 +72,16 @@ Deliberation이 완료되면 결과를 시각화하는 Forum View를 생성합
|
|
|
68
72
|
open demo/forum/index.html
|
|
69
73
|
```
|
|
70
74
|
|
|
75
|
+
## Diagnostics
|
|
76
|
+
|
|
77
|
+
MCP 연결 문제 자동 진단:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
npx @dmsdc-ai/aigentry-deliberation doctor
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Claude Code, Codex CLI, Gemini CLI의 MCP 설정을 자동 점검하고 문제를 진단합니다.
|
|
84
|
+
|
|
71
85
|
## MCP Tools
|
|
72
86
|
|
|
73
87
|
| Tool | Description |
|
|
@@ -107,6 +121,28 @@ open demo/forum/index.html
|
|
|
107
121
|
| `researcher` | Data, benchmarks, references |
|
|
108
122
|
| `free` | No role constraint (default) |
|
|
109
123
|
|
|
124
|
+
### deliberation-gate (Superpowers Integration)
|
|
125
|
+
|
|
126
|
+
Inserts multi-AI verification gates at key [superpowers](https://github.com/obra/superpowers) workflow decision points.
|
|
127
|
+
|
|
128
|
+
**Scenarios:**
|
|
129
|
+
- **brainstorming** → multi-AI design validation before writing plans
|
|
130
|
+
- **code-review** → multi-AI review via `deliberation_request_review`
|
|
131
|
+
- **debugging** → multi-AI hypothesis verification when stuck
|
|
132
|
+
|
|
133
|
+
**Trigger:** Semi-automatic — skill recommends deliberation, user approves.
|
|
134
|
+
|
|
135
|
+
**Fallback:** MCP 미설치 시 self-criticism 기반 자가 검증으로 대체 (Silver 등급). MCP 설치 시 멀티-AI 토론 (Gold 등급).
|
|
136
|
+
|
|
137
|
+
**Install:** `npx @dmsdc-ai/aigentry-deliberation install` 실행 시 자동 설치됩니다.
|
|
138
|
+
|
|
139
|
+
수동 설치:
|
|
140
|
+
```bash
|
|
141
|
+
cp skills/deliberation-gate/SKILL.md ~/.claude/skills/deliberation-gate/SKILL.md
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
**RFC:** [Prerequisites header for tool-dependent skills](https://github.com/obra/superpowers/issues/589)
|
|
145
|
+
|
|
110
146
|
## aigentry Ecosystem
|
|
111
147
|
|
|
112
148
|
aigentry-deliberation is one component of the unified aigentry platform. All packages work together to make AI decisions transparent and auditable.
|
package/browser-control-port.js
CHANGED
|
@@ -509,15 +509,6 @@ class DevToolsMcpAdapter extends BrowserControlPort {
|
|
|
509
509
|
}
|
|
510
510
|
}
|
|
511
511
|
|
|
512
|
-
const sendResult = { ok: true };
|
|
513
|
-
|
|
514
|
-
if (!sendResult.ok) {
|
|
515
|
-
return makeResult(false, null, {
|
|
516
|
-
code: "SEND_FAILED",
|
|
517
|
-
message: `Send button not found: ${binding.selectors.sendButton}`,
|
|
518
|
-
});
|
|
519
|
-
}
|
|
520
|
-
|
|
521
512
|
sent.add(turnId);
|
|
522
513
|
return makeResult(true, { turnId, sent: true });
|
|
523
514
|
} catch (err) {
|
package/index.js
CHANGED
|
@@ -948,7 +948,7 @@ async function ensureCdpAvailable() {
|
|
|
948
948
|
|
|
949
949
|
const launchArgs = [
|
|
950
950
|
"--remote-debugging-port=9222",
|
|
951
|
-
"--remote-allow-origins
|
|
951
|
+
"--remote-allow-origins=http://127.0.0.1:9222",
|
|
952
952
|
`--user-data-dir=${cdpDataDir}`,
|
|
953
953
|
`--profile-directory=${profileDir}`,
|
|
954
954
|
"--no-first-run",
|
|
@@ -965,7 +965,7 @@ async function ensureCdpAvailable() {
|
|
|
965
965
|
}
|
|
966
966
|
|
|
967
967
|
// Wait for Chrome to initialize CDP
|
|
968
|
-
|
|
968
|
+
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
969
969
|
|
|
970
970
|
// Retry CDP connection after launch
|
|
971
971
|
for (const endpoint of endpoints) {
|
|
@@ -2739,9 +2739,24 @@ server.tool(
|
|
|
2739
2739
|
|
|
2740
2740
|
const speaker = state.current_speaker;
|
|
2741
2741
|
const { transport, profile, reason } = resolveTransportForSpeaker(state, speaker);
|
|
2742
|
-
const guidance = formatTransportGuidance(transport, state, speaker);
|
|
2743
2742
|
const turnId = state.pending_turn_id || null;
|
|
2744
2743
|
|
|
2744
|
+
// ── Self-speaker detection ──
|
|
2745
|
+
// If the current speaker is the same CLI as the orchestrator (caller),
|
|
2746
|
+
// cli_auto_turn would recursively spawn the same process and timeout.
|
|
2747
|
+
// Instead, instruct the orchestrator to respond directly.
|
|
2748
|
+
const callerSpeaker = detectCallerSpeaker();
|
|
2749
|
+
const isSelfSpeaker = callerSpeaker && speaker === callerSpeaker && transport === "cli_respond";
|
|
2750
|
+
|
|
2751
|
+
let guidance;
|
|
2752
|
+
if (isSelfSpeaker) {
|
|
2753
|
+
guidance = `🟢 **본인 턴입니다.** 당신(${speaker})이 현재 speaker입니다.\n\n` +
|
|
2754
|
+
`직접 응답을 작성하여 \`deliberation_respond(session_id: "${state.id}", speaker: "${speaker}", content: "...")\`로 제출하세요.\n\n` +
|
|
2755
|
+
`⚠️ **cli_auto_turn 사용 금지**: 자기 자신을 재귀 호출하면 타임아웃이 발생합니다. 반드시 직접 deliberation_respond를 사용하세요.`;
|
|
2756
|
+
} else {
|
|
2757
|
+
guidance = formatTransportGuidance(transport, state, speaker);
|
|
2758
|
+
}
|
|
2759
|
+
|
|
2745
2760
|
let extra = "";
|
|
2746
2761
|
|
|
2747
2762
|
if (transport === "browser_auto") {
|
|
@@ -2963,6 +2978,17 @@ server.tool(
|
|
|
2963
2978
|
return { content: [{ type: "text", text: `speaker "${speaker}"는 CLI 타입이 아닙니다 (transport: ${transport}). 브라우저 speaker는 deliberation_browser_auto_turn을 사용하세요.` }] };
|
|
2964
2979
|
}
|
|
2965
2980
|
|
|
2981
|
+
// Block recursive self-spawn: if the speaker is the same CLI as the caller,
|
|
2982
|
+
// spawning it would create infinite recursion and timeout.
|
|
2983
|
+
const callerSpeaker = detectCallerSpeaker();
|
|
2984
|
+
if (callerSpeaker && speaker === callerSpeaker) {
|
|
2985
|
+
return { content: [{ type: "text", text:
|
|
2986
|
+
`⚠️ **재귀 호출 차단**: speaker "${speaker}"는 현재 오케스트레이터와 동일한 CLI입니다.\n\n` +
|
|
2987
|
+
`cli_auto_turn으로 자기 자신을 spawn하면 타임아웃이 발생합니다.\n` +
|
|
2988
|
+
`직접 응답을 작성하여 \`deliberation_respond(session_id: "${resolved}", speaker: "${speaker}", content: "...")\`로 제출하세요.`
|
|
2989
|
+
}] };
|
|
2990
|
+
}
|
|
2991
|
+
|
|
2966
2992
|
const hint = CLI_INVOCATION_HINTS[speaker];
|
|
2967
2993
|
if (!hint) {
|
|
2968
2994
|
return { content: [{ type: "text", text: `speaker "${speaker}"에 대한 CLI 호출 정보가 없습니다. CLI_INVOCATION_HINTS에 등록되지 않은 speaker입니다.` }] };
|
|
@@ -3098,7 +3124,8 @@ server.tool(
|
|
|
3098
3124
|
const { transport } = resolveTransportForSpeaker(state, speaker);
|
|
3099
3125
|
if (transport === "cli_respond" || transport === "browser_auto") {
|
|
3100
3126
|
// Check if caller is the same speaker (legitimate self-response) or an impersonator
|
|
3101
|
-
const
|
|
3127
|
+
const callerSpeaker = detectCallerSpeaker();
|
|
3128
|
+
const callerIsSpeaker = callerSpeaker && (speaker === callerSpeaker);
|
|
3102
3129
|
if (!callerIsSpeaker) {
|
|
3103
3130
|
return {
|
|
3104
3131
|
content: [{
|
|
@@ -3422,15 +3449,36 @@ server.tool(
|
|
|
3422
3449
|
// ── Request Review (auto-review) ───────────────────────────────
|
|
3423
3450
|
|
|
3424
3451
|
function invokeCliReviewer(command, prompt, timeoutMs) {
|
|
3425
|
-
const
|
|
3452
|
+
const hint = CLI_INVOCATION_HINTS[command];
|
|
3453
|
+
let args;
|
|
3454
|
+
let opts = { encoding: "utf-8", timeout: timeoutMs, stdio: ["pipe", "pipe", "pipe"], maxBuffer: 5 * 1024 * 1024, windowsHide: true };
|
|
3455
|
+
const env = { ...process.env };
|
|
3456
|
+
|
|
3457
|
+
switch (command) {
|
|
3458
|
+
case "claude":
|
|
3459
|
+
if (hint?.envPrefix?.includes("CLAUDECODE=")) delete env.CLAUDECODE;
|
|
3460
|
+
args = ["-p", "--output-format", "text", "--no-input"];
|
|
3461
|
+
opts.input = prompt;
|
|
3462
|
+
opts.stdio = ["pipe", "pipe", "pipe"];
|
|
3463
|
+
break;
|
|
3464
|
+
case "codex":
|
|
3465
|
+
args = ["exec", prompt];
|
|
3466
|
+
opts.stdio = ["ignore", "pipe", "pipe"];
|
|
3467
|
+
break;
|
|
3468
|
+
case "gemini":
|
|
3469
|
+
args = ["-p", prompt];
|
|
3470
|
+
opts.stdio = ["ignore", "pipe", "pipe"];
|
|
3471
|
+
break;
|
|
3472
|
+
default: {
|
|
3473
|
+
const flags = hint?.flags ? hint.flags.split(/\s+/).filter(Boolean) : ["-p"];
|
|
3474
|
+
args = [...flags, prompt];
|
|
3475
|
+
opts.stdio = ["ignore", "pipe", "pipe"];
|
|
3476
|
+
break;
|
|
3477
|
+
}
|
|
3478
|
+
}
|
|
3479
|
+
|
|
3426
3480
|
try {
|
|
3427
|
-
const result = execFileSync(command, args, {
|
|
3428
|
-
encoding: "utf-8",
|
|
3429
|
-
timeout: timeoutMs,
|
|
3430
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
3431
|
-
maxBuffer: 5 * 1024 * 1024,
|
|
3432
|
-
windowsHide: true,
|
|
3433
|
-
});
|
|
3481
|
+
const result = execFileSync(command, args, { ...opts, env });
|
|
3434
3482
|
return { ok: true, response: result.trim() };
|
|
3435
3483
|
} catch (error) {
|
|
3436
3484
|
if (error && error.killed) {
|
package/install.js
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
* 3. Registers MCP server in ~/.claude/.mcp.json (Claude Code)
|
|
14
14
|
* 4. Registers MCP server in ~/.gemini/settings.json (Gemini CLI)
|
|
15
15
|
* 5. Ready to use — next Claude Code or Gemini CLI session will auto-load
|
|
16
|
+
* 6. 스킬 파일 설치 (~/.claude/skills/deliberation-gate/SKILL.md)
|
|
16
17
|
*/
|
|
17
18
|
|
|
18
19
|
import { execSync } from "node:child_process";
|
|
@@ -28,6 +29,10 @@ const INSTALL_DIR = IS_WIN
|
|
|
28
29
|
: path.join(HOME, ".local", "lib", "mcp-deliberation");
|
|
29
30
|
const MCP_CONFIG = path.join(HOME, ".claude", ".mcp.json");
|
|
30
31
|
const GEMINI_CONFIG = path.join(HOME, ".gemini", "settings.json");
|
|
32
|
+
const SKILL_SRC = path.join(__dirname, "skills", "deliberation-gate", "SKILL.md");
|
|
33
|
+
const SKILL_DEST_DIR = path.join(HOME, ".claude", "skills", "deliberation-gate");
|
|
34
|
+
const SKILL_DEST = path.join(SKILL_DEST_DIR, "SKILL.md");
|
|
35
|
+
const MANIFEST_PATH = path.join(INSTALL_DIR, ".install-manifest.json");
|
|
31
36
|
|
|
32
37
|
/** Normalize path to forward slashes for JSON config (Windows backslash → forward slash) */
|
|
33
38
|
function toForwardSlash(p) {
|
|
@@ -175,12 +180,53 @@ function install() {
|
|
|
175
180
|
} catch { /* ignore on Windows */ }
|
|
176
181
|
}
|
|
177
182
|
|
|
178
|
-
// Step
|
|
183
|
+
// Step 6b: Preserve existing config
|
|
179
184
|
const configPath = path.join(INSTALL_DIR, "config.json");
|
|
180
185
|
if (!fs.existsSync(configPath)) {
|
|
181
186
|
fs.writeFileSync(configPath, JSON.stringify({}, null, 2));
|
|
182
187
|
}
|
|
183
188
|
|
|
189
|
+
// Step 7: Deploy deliberation-gate skill
|
|
190
|
+
log("🎓 deliberation-gate 스킬 파일 설치...");
|
|
191
|
+
if (!fs.existsSync(SKILL_SRC)) {
|
|
192
|
+
log(" ⚠️ 스킬 소스 파일 없음, 스킵: " + SKILL_SRC);
|
|
193
|
+
} else {
|
|
194
|
+
try {
|
|
195
|
+
fs.mkdirSync(SKILL_DEST_DIR, { recursive: true });
|
|
196
|
+
let shouldCopy = true;
|
|
197
|
+
if (fs.existsSync(SKILL_DEST) && !FORCE) {
|
|
198
|
+
const existing = fs.readFileSync(SKILL_DEST, "utf-8");
|
|
199
|
+
const incoming = fs.readFileSync(SKILL_SRC, "utf-8");
|
|
200
|
+
if (existing === incoming) {
|
|
201
|
+
log(" → 이미 최신 상태, 스킵");
|
|
202
|
+
shouldCopy = false;
|
|
203
|
+
} else {
|
|
204
|
+
fs.copyFileSync(SKILL_DEST, SKILL_DEST + ".backup");
|
|
205
|
+
log(" → 기존 파일 백업: SKILL.md.backup");
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
if (shouldCopy) {
|
|
209
|
+
fs.copyFileSync(SKILL_SRC, SKILL_DEST);
|
|
210
|
+
log(" → " + SKILL_DEST);
|
|
211
|
+
}
|
|
212
|
+
} catch (err) {
|
|
213
|
+
log(` ⚠️ 스킬 설치 실패: ${err.message}`);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Write install manifest
|
|
218
|
+
try {
|
|
219
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, "package.json"), "utf-8"));
|
|
220
|
+
const manifest = {
|
|
221
|
+
version: pkg.version,
|
|
222
|
+
installedAt: new Date().toISOString(),
|
|
223
|
+
skills: [SKILL_DEST],
|
|
224
|
+
};
|
|
225
|
+
fs.writeFileSync(MANIFEST_PATH, JSON.stringify(manifest, null, 2));
|
|
226
|
+
} catch (err) {
|
|
227
|
+
log(` ⚠️ manifest 작성 실패: ${err.message}`);
|
|
228
|
+
}
|
|
229
|
+
|
|
184
230
|
// Done
|
|
185
231
|
console.log("\n✅ 설치 완료!\n");
|
|
186
232
|
console.log(" 다음 단계:");
|
|
@@ -191,6 +237,7 @@ function install() {
|
|
|
191
237
|
|
|
192
238
|
// Entry point
|
|
193
239
|
const args = process.argv.slice(2);
|
|
240
|
+
const FORCE = args.includes("--force");
|
|
194
241
|
if (args.includes("--help") || args.includes("-h")) {
|
|
195
242
|
console.log(`
|
|
196
243
|
Deliberation MCP Server Installer
|
|
@@ -202,10 +249,18 @@ Usage:
|
|
|
202
249
|
Options:
|
|
203
250
|
--help, -h 이 도움말 표시
|
|
204
251
|
--uninstall 서버 제거
|
|
252
|
+
--force 기존 스킬 파일 비교 없이 강제 덮어쓰기
|
|
253
|
+
|
|
254
|
+
기능:
|
|
255
|
+
- 서버 파일을 설치 경로에 복사
|
|
256
|
+
- npm 의존성 설치
|
|
257
|
+
- Claude Code / Gemini CLI MCP 서버 등록
|
|
258
|
+
- 스킬 파일 설치 (~/.claude/skills/deliberation-gate/SKILL.md)
|
|
205
259
|
|
|
206
260
|
설치 경로: ${INSTALL_DIR}
|
|
207
261
|
MCP 설정: ${MCP_CONFIG}
|
|
208
262
|
Gemini: ${GEMINI_CONFIG}
|
|
263
|
+
스킬 경로: ${SKILL_DEST}
|
|
209
264
|
`);
|
|
210
265
|
} else if (args.includes("--uninstall") || args.includes("uninstall")) {
|
|
211
266
|
console.log("\n🗑️ Deliberation MCP Server 제거\n");
|
|
@@ -234,6 +289,39 @@ Gemini: ${GEMINI_CONFIG}
|
|
|
234
289
|
} catch { /* ignore */ }
|
|
235
290
|
}
|
|
236
291
|
|
|
292
|
+
// Remove skill files tracked by manifest (or fall back to default path)
|
|
293
|
+
let skillsToRemove = [SKILL_DEST];
|
|
294
|
+
const manifestFile = path.join(INSTALL_DIR, ".install-manifest.json");
|
|
295
|
+
if (fs.existsSync(manifestFile)) {
|
|
296
|
+
try {
|
|
297
|
+
const manifest = JSON.parse(fs.readFileSync(manifestFile, "utf-8"));
|
|
298
|
+
if (Array.isArray(manifest.skills) && manifest.skills.length > 0) {
|
|
299
|
+
skillsToRemove = manifest.skills;
|
|
300
|
+
}
|
|
301
|
+
} catch { /* use default */ }
|
|
302
|
+
}
|
|
303
|
+
for (const skillPath of skillsToRemove) {
|
|
304
|
+
if (fs.existsSync(skillPath)) {
|
|
305
|
+
try {
|
|
306
|
+
fs.rmSync(skillPath, { force: true });
|
|
307
|
+
log(`스킬 파일 삭제: ${skillPath}`);
|
|
308
|
+
const backupPath = skillPath + ".backup";
|
|
309
|
+
if (fs.existsSync(backupPath)) {
|
|
310
|
+
log(` 💡 백업 파일이 남아 있습니다: ${backupPath}`);
|
|
311
|
+
log(` 복원하려면: cp "${backupPath}" "${skillPath}"`);
|
|
312
|
+
}
|
|
313
|
+
// Remove directory if empty
|
|
314
|
+
const dir = path.dirname(skillPath);
|
|
315
|
+
if (fs.existsSync(dir) && fs.readdirSync(dir).length === 0) {
|
|
316
|
+
fs.rmdirSync(dir);
|
|
317
|
+
log(`빈 스킬 디렉토리 삭제: ${dir}`);
|
|
318
|
+
}
|
|
319
|
+
} catch (err) {
|
|
320
|
+
log(` ⚠️ 스킬 파일 삭제 실패: ${err.message}`);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
237
325
|
// Remove install directory
|
|
238
326
|
if (fs.existsSync(INSTALL_DIR)) {
|
|
239
327
|
fs.rmSync(INSTALL_DIR, { recursive: true, force: true });
|
package/observer.js
CHANGED
|
@@ -261,7 +261,9 @@ function createServer(port) {
|
|
|
261
261
|
const pathname = url.pathname;
|
|
262
262
|
|
|
263
263
|
// CORS
|
|
264
|
-
|
|
264
|
+
const origin = req.headers.origin || "";
|
|
265
|
+
const allowedOrigins = [`http://127.0.0.1:${port}`, `http://localhost:${port}`];
|
|
266
|
+
res.setHeader("Access-Control-Allow-Origin", allowedOrigins.includes(origin) ? origin : allowedOrigins[0]);
|
|
265
267
|
res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
|
266
268
|
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
|
|
267
269
|
|
|
@@ -377,7 +379,13 @@ function createServer(port) {
|
|
|
377
379
|
|
|
378
380
|
req.on("close", () => {
|
|
379
381
|
const clients = sseClients.get(sessionId) || [];
|
|
380
|
-
|
|
382
|
+
const remaining = clients.filter(c => c !== res);
|
|
383
|
+
if (remaining.length === 0) {
|
|
384
|
+
sseClients.delete(sessionId);
|
|
385
|
+
sessionSnapshots.delete(sessionId);
|
|
386
|
+
} else {
|
|
387
|
+
sseClients.set(sessionId, remaining);
|
|
388
|
+
}
|
|
381
389
|
});
|
|
382
390
|
return;
|
|
383
391
|
}
|
|
@@ -468,7 +476,7 @@ const server = createServer(port);
|
|
|
468
476
|
// Poll every 1 second
|
|
469
477
|
const pollInterval = setInterval(pollSessions, 1000);
|
|
470
478
|
|
|
471
|
-
server.listen(port, () => {
|
|
479
|
+
server.listen(port, "127.0.0.1", () => {
|
|
472
480
|
console.log(`Deliberation Observer running at http://localhost:${port}`);
|
|
473
481
|
console.log(` Dashboard: http://localhost:${port}/`);
|
|
474
482
|
console.log(` API: http://localhost:${port}/api/sessions`);
|
package/package.json
CHANGED
package/session-monitor-win.js
CHANGED
|
@@ -14,7 +14,7 @@ if (!sessionId) {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
const HOME = process.env.HOME || process.env.USERPROFILE || "";
|
|
17
|
-
const stateDir = path.join(HOME, ".local", "
|
|
17
|
+
const stateDir = path.join(HOME, ".local", "lib", "mcp-deliberation", "state", project);
|
|
18
18
|
const stateFile = path.join(stateDir, `${sessionId}.json`);
|
|
19
19
|
|
|
20
20
|
const BOLD = "\x1b[1m";
|
|
@@ -176,3 +176,8 @@ bash deliberation-monitor.sh --tmux
|
|
|
176
176
|
4. 실시간 sync 파일은 state 디렉토리에 저장되며 완료 시 자동 삭제됨 (프로젝트 루트 오염 없음)
|
|
177
177
|
5. `Transport closed` 발생 시 현재 CLI 세션 재시작 후 재시도 (stdio 연결은 세션 바인딩)
|
|
178
178
|
6. 멀티 세션 운영 중 `pkill -f mcp-deliberation` 사용 금지 (다른 세션 연결까지 끊길 수 있음)
|
|
179
|
+
|
|
180
|
+
## 관련 스킬
|
|
181
|
+
|
|
182
|
+
- **deliberation-gate**: superpowers 워크플로우 통합 스킬. brainstorming/code-review/debugging 의사결정 지점에 멀티-AI 검증 게이트를 삽입합니다. `~/.claude/skills/deliberation-gate/SKILL.md`에 설치.
|
|
183
|
+
- **deliberation-executor**: deliberation 합의안을 실제 코드 구현으로 전환하는 실행 전용 스킬.
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: deliberation-gate
|
|
3
|
+
description: |
|
|
4
|
+
Use after brainstorming produces design doc, after code-review produces feedback,
|
|
5
|
+
when debugging hits dead end with failed hypotheses, or when user says
|
|
6
|
+
"deliberate this", "토론해줘", "검증해줘", "멀티-AI 리뷰", "multi-AI verify"
|
|
7
|
+
version: 0.1.0
|
|
8
|
+
prerequisites:
|
|
9
|
+
mcp: ["aigentry-deliberation"]
|
|
10
|
+
fallback: self-criticism
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Deliberation Gate — Multi-AI Verification for Superpowers Workflows
|
|
14
|
+
|
|
15
|
+
Insert multi-AI deliberation gates at key decision points in superpowers workflow chains.
|
|
16
|
+
Uses aigentry-deliberation MCP tools to orchestrate structured debate between multiple AI systems.
|
|
17
|
+
|
|
18
|
+
**Semi-automatic**: Recommends deliberation at decision points. User approves before starting.
|
|
19
|
+
|
|
20
|
+
## Context Detection
|
|
21
|
+
|
|
22
|
+
Detect the current workflow context by checking these signals IN ORDER:
|
|
23
|
+
|
|
24
|
+
| Priority | Signal | Context |
|
|
25
|
+
|----------|--------|---------|
|
|
26
|
+
| 1 | User says "deliberate", "토론", "debate", "검증", "멀티-AI" | explicit |
|
|
27
|
+
| 2 | Design doc recently written in session (docs/plans/*-design.md) | brainstorming |
|
|
28
|
+
| 3 | git diff output, PR number, or code review feedback in conversation | code-review |
|
|
29
|
+
| 4 | Error traces + failed hypotheses / "root cause" in conversation | debugging |
|
|
30
|
+
| 5 | None of above | general |
|
|
31
|
+
|
|
32
|
+
### Scenario Preset Map
|
|
33
|
+
|
|
34
|
+
| Context | preset | rounds | roles | MCP path |
|
|
35
|
+
|---------|--------|--------|-------|----------|
|
|
36
|
+
| brainstorming | brainstorm | 2 | critic, implementer, researcher | deliberation_start → route_turn loop → synthesize |
|
|
37
|
+
| code-review | review | 1 | critic, implementer | deliberation_request_review (lightweight) |
|
|
38
|
+
| debugging | research | 2 | researcher, implementer, critic | deliberation_start → route_turn loop → synthesize |
|
|
39
|
+
| general | balanced | 3 | user-selected via AskUserQuestion | deliberation_start → route_turn loop → synthesize |
|
|
40
|
+
|
|
41
|
+
## Recommendation Protocol (Semi-Automatic)
|
|
42
|
+
|
|
43
|
+
When you detect a decision point, recommend deliberation to the user.
|
|
44
|
+
|
|
45
|
+
### Step 1: Detect and Announce
|
|
46
|
+
|
|
47
|
+
Announce the detected context:
|
|
48
|
+
|
|
49
|
+
> 🔔 **멀티-AI 검증 추천** — [context] 시나리오 감지
|
|
50
|
+
>
|
|
51
|
+
> 이 [설계안/코드 리뷰/디버깅 가설]을 다른 AI의 관점으로 검증하면 더 견고해질 수 있습니다.
|
|
52
|
+
|
|
53
|
+
### Step 2: Ask User
|
|
54
|
+
|
|
55
|
+
Use AskUserQuestion to get approval:
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
AskUserQuestion:
|
|
59
|
+
question: "이 [artifact]을 멀티-AI 토론으로 검증할까요?"
|
|
60
|
+
header: "멀티-AI 검증"
|
|
61
|
+
options:
|
|
62
|
+
- label: "시작 (Recommended)"
|
|
63
|
+
description: "[preset] preset, [N]라운드, [roles] 역할로 deliberation 시작"
|
|
64
|
+
- label: "설정 변경 후 시작"
|
|
65
|
+
description: "preset, rounds, roles를 직접 선택"
|
|
66
|
+
- label: "건너뛰기"
|
|
67
|
+
description: "deliberation 없이 원래 워크플로우 계속"
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Step 3: On Decline
|
|
71
|
+
|
|
72
|
+
If user chooses "건너뛰기":
|
|
73
|
+
- Do NOT persist or re-ask
|
|
74
|
+
- Continue the original workflow immediately
|
|
75
|
+
- No penalty, no warning
|
|
76
|
+
|
|
77
|
+
## Deliberation Execution
|
|
78
|
+
|
|
79
|
+
When user approves, execute this sequence:
|
|
80
|
+
|
|
81
|
+
### Standard Path (brainstorming, debugging, general)
|
|
82
|
+
|
|
83
|
+
1. **Speaker discovery**: `deliberation_speaker_candidates` → get available CLI + browser speakers
|
|
84
|
+
2. **Speaker selection**: `AskUserQuestion(multiSelect: true)` → user selects which speakers to include
|
|
85
|
+
3. **Start deliberation**: `deliberation_start`
|
|
86
|
+
- `topic`: the artifact being validated (design summary / error description + hypotheses / user's question)
|
|
87
|
+
- `speakers`: user-selected list
|
|
88
|
+
- `speaker_roles`: from scenario preset map above
|
|
89
|
+
- `rounds`: from scenario preset map above
|
|
90
|
+
- `ordering_strategy`: "auto"
|
|
91
|
+
- `role_preset`: from scenario preset map above
|
|
92
|
+
4. **Turn loop**: For each turn:
|
|
93
|
+
- Call `deliberation_route_turn` — it auto-detects the correct transport
|
|
94
|
+
- **Self-speaker** (you are the current speaker): Compose your response based on your role, submit via `deliberation_respond(speaker: "claude", content: "...")`
|
|
95
|
+
- **Other CLI speaker**: `deliberation_route_turn` will guide to `deliberation_cli_auto_turn` which spawns the actual CLI
|
|
96
|
+
- **Browser speaker**: `deliberation_route_turn` will auto-execute via CDP
|
|
97
|
+
5. **Synthesize**: After all rounds complete, call `deliberation_synthesize` with a summary of the consensus
|
|
98
|
+
6. **Apply synthesis**: Follow the Integration Rules below
|
|
99
|
+
|
|
100
|
+
### Lightweight Path (code-review only)
|
|
101
|
+
|
|
102
|
+
1. **Speaker discovery**: `deliberation_speaker_candidates` → get available speakers
|
|
103
|
+
2. **Reviewer selection**: `AskUserQuestion(multiSelect: true)` → user selects reviewers
|
|
104
|
+
3. **Request review**: `deliberation_request_review`
|
|
105
|
+
- `context`: the diff or code under review
|
|
106
|
+
- `question`: "이 코드 변경사항을 리뷰해주세요. 버그, 설계 문제, 보안 취약점을 중심으로."
|
|
107
|
+
- `reviewers`: user-selected list
|
|
108
|
+
- `mode`: "sync"
|
|
109
|
+
- `deadline_ms`: 120000
|
|
110
|
+
4. **Apply results**: Follow the Integration Rules below
|
|
111
|
+
|
|
112
|
+
## Synthesis Integration Rules
|
|
113
|
+
|
|
114
|
+
### brainstorming → design doc update
|
|
115
|
+
|
|
116
|
+
After deliberation on a design:
|
|
117
|
+
1. Read the synthesis from `deliberation_synthesize`
|
|
118
|
+
2. Append a `## 멀티-AI 합의` section to the design doc with:
|
|
119
|
+
- **합의 사항**: Key agreements from all participants
|
|
120
|
+
- **이견**: Dissenting points (if any)
|
|
121
|
+
- **권장 변경**: Concrete changes recommended by consensus
|
|
122
|
+
3. Apply the agreed changes to the design document
|
|
123
|
+
4. Continue to `writing-plans` skill with the updated design
|
|
124
|
+
|
|
125
|
+
### code-review → receiving-code-review
|
|
126
|
+
|
|
127
|
+
After multi-AI code review:
|
|
128
|
+
1. Parse review results into severity categories:
|
|
129
|
+
- **Critical**: Must fix before merge
|
|
130
|
+
- **Major**: Should fix
|
|
131
|
+
- **Minor**: Optional improvements
|
|
132
|
+
2. Present the categorized feedback to user
|
|
133
|
+
3. Continue to `receiving-code-review` skill workflow
|
|
134
|
+
|
|
135
|
+
### debugging → hypothesis reordering
|
|
136
|
+
|
|
137
|
+
After deliberation on debugging hypotheses:
|
|
138
|
+
1. Extract the consensus hypothesis ranking from synthesis
|
|
139
|
+
2. Update the debugging state:
|
|
140
|
+
- Move consensus-top hypothesis to position 1
|
|
141
|
+
- Mark disproven hypotheses as eliminated
|
|
142
|
+
- Add any new hypotheses suggested by other AIs
|
|
143
|
+
3. Resume `systematic-debugging` with the new priorities
|
|
144
|
+
|
|
145
|
+
### general → user-directed
|
|
146
|
+
|
|
147
|
+
For explicit or general deliberation:
|
|
148
|
+
1. Present the synthesis summary to user
|
|
149
|
+
2. Ask how to proceed with the consensus
|
|
150
|
+
3. Follow user's direction
|
|
151
|
+
|
|
152
|
+
## MCP 미설치 시 Fallback (Graceful Degradation)
|
|
153
|
+
|
|
154
|
+
deliberation MCP 도구(`deliberation_start`, `deliberation_speaker_candidates` 등)가 사용 불가능할 경우:
|
|
155
|
+
|
|
156
|
+
### 감지 방법
|
|
157
|
+
- MCP 도구 호출 시 "tool not found" 또는 연결 실패 에러 발생
|
|
158
|
+
- `deliberation_speaker_candidates` 호출이 실패하면 MCP 미설치로 판단
|
|
159
|
+
|
|
160
|
+
### Fallback 프로토콜
|
|
161
|
+
|
|
162
|
+
1. **안내**: AskUserQuestion으로 상황 설명
|
|
163
|
+
```
|
|
164
|
+
question: "멀티-AI 검증 MCP 서버가 감지되지 않았습니다. 단일 모델 자가 검증으로 대체할까요?"
|
|
165
|
+
options:
|
|
166
|
+
- label: "자가 검증 진행"
|
|
167
|
+
description: "3관점 self-criticism으로 검증 (Silver 등급)"
|
|
168
|
+
- label: "MCP 설치 안내"
|
|
169
|
+
description: "npx @dmsdc-ai/aigentry-deliberation install 실행 방법 안내"
|
|
170
|
+
- label: "건너뛰기"
|
|
171
|
+
description: "검증 없이 원래 워크플로우 계속"
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
2. **Self-Criticism 실행** (자가 검증 선택 시):
|
|
175
|
+
- 동일 artifact에 대해 3가지 관점으로 순차 분석:
|
|
176
|
+
- **비판적 분석가**: 약점, 리스크, 누락된 고려사항
|
|
177
|
+
- **현실적 실행가**: 구현 가능성, 비용, 복잡도
|
|
178
|
+
- **리서처**: 대안, 선례, 데이터 기반 근거
|
|
179
|
+
- 3관점 결과를 종합하여 합의 포맷으로 출력
|
|
180
|
+
|
|
181
|
+
3. **투명성 라벨링**:
|
|
182
|
+
- 모든 검증 결과에 출처 라벨 필수 표시:
|
|
183
|
+
- `🥇 Verification: Multi-AI Deliberation (Gold)` — 실제 멀티-AI 토론 결과
|
|
184
|
+
- `🥈 Verification: Self-Criticism (Silver)` — 단일 모델 자가 검증 결과
|
|
185
|
+
- 라벨은 합의 섹션 상단에 표시
|
|
186
|
+
|
|
187
|
+
### MCP 설치 안내 (선택 시)
|
|
188
|
+
```
|
|
189
|
+
npx @dmsdc-ai/aigentry-deliberation install
|
|
190
|
+
```
|
|
191
|
+
설치 후 Claude Code 세션을 재시작하면 멀티-AI 검증이 활성화됩니다.
|
|
192
|
+
|
|
193
|
+
## Anti-Patterns (NEVER)
|
|
194
|
+
|
|
195
|
+
1. **NEVER skip user approval** — Always use AskUserQuestion before starting deliberation. This is a HARD GATE.
|
|
196
|
+
2. **NEVER fabricate speaker responses** — Use `deliberation_route_turn` for other speakers. Never write responses on behalf of codex, gemini, or any other speaker. The MCP server blocks this.
|
|
197
|
+
3. **NEVER use cli_auto_turn for self-speaker** — If you (claude) are the current speaker, compose your response and submit via `deliberation_respond` directly. Using `cli_auto_turn` would recursively spawn yourself and timeout.
|
|
198
|
+
4. **NEVER re-ask after decline** — If user chooses "건너뛰기", respect it immediately. Do not ask again.
|
|
199
|
+
5. **NEVER block on deliberation failure** — If MCP tools fail (server not running, speaker unavailable), warn the user and continue the original workflow. Deliberation is enhancement, not requirement.
|
|
200
|
+
6. **NEVER modify existing superpowers skills** — This skill is purely additive. It works alongside existing skills without changing them.
|
|
201
|
+
7. **NEVER omit verification source label** — 모든 검증 결과에 Gold/Silver 라벨을 반드시 표시. Self-criticism 결과를 Multi-AI 결과와 구분 없이 제시하면 신뢰도를 왜곡한다.
|
|
202
|
+
|
|
203
|
+
## Workflow Position
|
|
204
|
+
|
|
205
|
+
```
|
|
206
|
+
brainstorming ──────→ [deliberation-gate] → writing-plans → executing-plans
|
|
207
|
+
code-review ────────→ [deliberation-gate] → receiving-code-review
|
|
208
|
+
systematic-debugging → [deliberation-gate] → resume with consensus
|
|
209
|
+
explicit request ───→ [deliberation-gate] → context-dependent
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
This skill is invoked BETWEEN existing superpowers skills, not within them. It consumes the output of one skill and feeds enhanced output to the next.
|