@dmsdc-ai/aigentry-deliberation 0.0.21 → 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 +22 -2
- package/browser-control-port.js +0 -9
- package/index.js +33 -11
- package/observer.js +11 -3
- package/package.json +1 -1
- package/session-monitor-win.js +1 -1
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 |
|
|
@@ -109,7 +123,7 @@ open demo/forum/index.html
|
|
|
109
123
|
|
|
110
124
|
### deliberation-gate (Superpowers Integration)
|
|
111
125
|
|
|
112
|
-
Inserts multi-AI verification gates at key [superpowers](https://github.com/
|
|
126
|
+
Inserts multi-AI verification gates at key [superpowers](https://github.com/obra/superpowers) workflow decision points.
|
|
113
127
|
|
|
114
128
|
**Scenarios:**
|
|
115
129
|
- **brainstorming** → multi-AI design validation before writing plans
|
|
@@ -118,11 +132,17 @@ Inserts multi-AI verification gates at key [superpowers](https://github.com/anth
|
|
|
118
132
|
|
|
119
133
|
**Trigger:** Semi-automatic — skill recommends deliberation, user approves.
|
|
120
134
|
|
|
121
|
-
**
|
|
135
|
+
**Fallback:** MCP 미설치 시 self-criticism 기반 자가 검증으로 대체 (Silver 등급). MCP 설치 시 멀티-AI 토론 (Gold 등급).
|
|
136
|
+
|
|
137
|
+
**Install:** `npx @dmsdc-ai/aigentry-deliberation install` 실행 시 자동 설치됩니다.
|
|
138
|
+
|
|
139
|
+
수동 설치:
|
|
122
140
|
```bash
|
|
123
141
|
cp skills/deliberation-gate/SKILL.md ~/.claude/skills/deliberation-gate/SKILL.md
|
|
124
142
|
```
|
|
125
143
|
|
|
144
|
+
**RFC:** [Prerequisites header for tool-dependent skills](https://github.com/obra/superpowers/issues/589)
|
|
145
|
+
|
|
126
146
|
## aigentry Ecosystem
|
|
127
147
|
|
|
128
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) {
|
|
@@ -3124,7 +3124,8 @@ server.tool(
|
|
|
3124
3124
|
const { transport } = resolveTransportForSpeaker(state, speaker);
|
|
3125
3125
|
if (transport === "cli_respond" || transport === "browser_auto") {
|
|
3126
3126
|
// Check if caller is the same speaker (legitimate self-response) or an impersonator
|
|
3127
|
-
const
|
|
3127
|
+
const callerSpeaker = detectCallerSpeaker();
|
|
3128
|
+
const callerIsSpeaker = callerSpeaker && (speaker === callerSpeaker);
|
|
3128
3129
|
if (!callerIsSpeaker) {
|
|
3129
3130
|
return {
|
|
3130
3131
|
content: [{
|
|
@@ -3448,15 +3449,36 @@ server.tool(
|
|
|
3448
3449
|
// ── Request Review (auto-review) ───────────────────────────────
|
|
3449
3450
|
|
|
3450
3451
|
function invokeCliReviewer(command, prompt, timeoutMs) {
|
|
3451
|
-
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
|
+
|
|
3452
3480
|
try {
|
|
3453
|
-
const result = execFileSync(command, args, {
|
|
3454
|
-
encoding: "utf-8",
|
|
3455
|
-
timeout: timeoutMs,
|
|
3456
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
3457
|
-
maxBuffer: 5 * 1024 * 1024,
|
|
3458
|
-
windowsHide: true,
|
|
3459
|
-
});
|
|
3481
|
+
const result = execFileSync(command, args, { ...opts, env });
|
|
3460
3482
|
return { ok: true, response: result.trim() };
|
|
3461
3483
|
} catch (error) {
|
|
3462
3484
|
if (error && error.killed) {
|
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";
|