@antonbabenko/deliberation-mcp 0.1.0 → 3.0.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 (3) hide show
  1. package/dist/index.js +4009 -2518
  2. package/dist/setup.js +213 -0
  3. package/package.json +3 -3
package/dist/setup.js ADDED
@@ -0,0 +1,213 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __commonJS = (cb, mod) => function __require() {
5
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
6
+ };
7
+
8
+ // ../../core/paths.js
9
+ var require_paths = __commonJS({
10
+ "../../core/paths.js"(exports2, module2) {
11
+ "use strict";
12
+ var os = require("node:os");
13
+ var path2 = require("node:path");
14
+ function resolveInjection(opts) {
15
+ return {
16
+ home: opts && opts.home || os.homedir(),
17
+ env: opts && opts.env || process.env,
18
+ platform: opts && opts.platform || process.platform
19
+ };
20
+ }
21
+ function isUsableBase(value, platform) {
22
+ if (typeof value !== "string" || value.length === 0) return false;
23
+ const impl = platform === "win32" ? path2.win32 : path2.posix;
24
+ return impl.isAbsolute(value);
25
+ }
26
+ function canonicalConfigDir(home, env, platform) {
27
+ if (platform === "win32") {
28
+ const appData = env.APPDATA;
29
+ const base2 = isUsableBase(appData, platform) ? appData : path2.join(home, "AppData", "Roaming");
30
+ return path2.join(base2, "deliberation");
31
+ }
32
+ const xdg = env.XDG_CONFIG_HOME;
33
+ const base = isUsableBase(xdg, platform) ? xdg : path2.join(home, ".config");
34
+ return path2.join(base, "deliberation");
35
+ }
36
+ function resolveConfigPath2(opts) {
37
+ const { home, env, platform } = resolveInjection(opts);
38
+ const override = env.DELIBERATION_CONFIG;
39
+ if (typeof override === "string" && override.length > 0) {
40
+ return override;
41
+ }
42
+ return path2.join(canonicalConfigDir(home, env, platform), "config.json");
43
+ }
44
+ function canonicalCacheDir(home, env, platform) {
45
+ if (platform === "win32") {
46
+ const localAppData = env.LOCALAPPDATA;
47
+ const base2 = isUsableBase(localAppData, platform) ? localAppData : path2.join(home, "AppData", "Local");
48
+ return path2.join(base2, "deliberation");
49
+ }
50
+ const xdg = env.XDG_CACHE_HOME;
51
+ const base = isUsableBase(xdg, platform) ? xdg : path2.join(home, ".cache");
52
+ return path2.join(base, "deliberation");
53
+ }
54
+ function resolveGrokCachePath(opts) {
55
+ const { home, env, platform } = resolveInjection(opts);
56
+ const override = env.DELIBERATION_CACHE;
57
+ if (typeof override === "string" && override.length > 0) {
58
+ return override;
59
+ }
60
+ return path2.join(canonicalCacheDir(home, env, platform), "grok-files.json");
61
+ }
62
+ function resolveSessionsDir(opts) {
63
+ const { home, env, platform } = resolveInjection(opts);
64
+ const override = env.DELIBERATION_SESSIONS;
65
+ if (typeof override === "string" && override.length > 0) {
66
+ return override;
67
+ }
68
+ return path2.join(canonicalCacheDir(home, env, platform), "sessions");
69
+ }
70
+ module2.exports = {
71
+ resolveConfigPath: resolveConfigPath2,
72
+ resolveGrokCachePath,
73
+ resolveSessionsDir
74
+ };
75
+ }
76
+ });
77
+
78
+ // setup.js
79
+ var fs = require("node:fs");
80
+ var path = require("node:path");
81
+ var { resolveConfigPath } = require_paths();
82
+ var SCHEMA_URL = "https://raw.githubusercontent.com/antonbabenko/deliberation/master/config/config.schema.json";
83
+ var STARTER_CONFIG = {
84
+ $schema: SCHEMA_URL,
85
+ version: 1,
86
+ providers: {
87
+ codex: { enabled: true },
88
+ gemini: { enabled: true },
89
+ grok: { enabled: true, apiKeyEnv: "XAI_API_KEY" },
90
+ openrouter: {
91
+ enabled: false,
92
+ apiKeyEnv: "OPENROUTER_API_KEY",
93
+ apiBase: "https://openrouter.ai/api/v1",
94
+ allowRawModel: false,
95
+ defaultModel: "openai/gpt-4.1-mini",
96
+ defaults: { reasoningEffort: "high", temperature: 0.2, timeout: 12e4 }
97
+ }
98
+ },
99
+ models: {},
100
+ routing: { maxFanout: 3 },
101
+ consensus: { arbiter: "auto" }
102
+ };
103
+ function starterConfigText() {
104
+ return JSON.stringify(STARTER_CONFIG, null, 2) + "\n";
105
+ }
106
+ function openrouterExampleLines() {
107
+ return [
108
+ "Example model record (add under models, then set providers.openrouter.enabled: true):",
109
+ ' "claude-arb": { "provider": "openrouter", "model": "anthropic/claude-3.7-sonnet", "askAll": true, "consensus": true }',
110
+ 'Then reference it as the arbiter with consensus.arbiter = { "model": "claude-arb" }.'
111
+ ];
112
+ }
113
+ function providerGuidanceLines() {
114
+ return [
115
+ "Provider setup:",
116
+ " GPT (Codex) - install the Codex CLI and run `codex login` (no env key).",
117
+ " Gemini - install Antigravity and run `agy` once to sign in (no env key).",
118
+ " Grok (xAI) - set XAI_API_KEY in the server env.",
119
+ " OpenRouter - set OPENROUTER_API_KEY and declare models in the config.",
120
+ "",
121
+ "Recommended cross-host arbiter: a dedicated Claude model record (an out-of-panel",
122
+ "model), so consensus is adjudicated by a model that is not one of the voting",
123
+ 'providers. Set it with consensus.arbiter = { "model": "<your-record-id>" }.'
124
+ ];
125
+ }
126
+ function consensusBlockLines() {
127
+ return [
128
+ "Suggested consensus block (merge into your existing config):",
129
+ ' "consensus": { "arbiter": "auto" }'
130
+ ];
131
+ }
132
+ function runSetup(deps) {
133
+ const fsImpl = deps && deps.fsImpl || fs;
134
+ const env = deps && deps.env || process.env;
135
+ const out = deps && deps.out || ((line) => console.log(line));
136
+ const home = deps && deps.home;
137
+ const configPath = resolveConfigPath({ home, env });
138
+ const print = (lines) => {
139
+ for (const line of lines) out(line);
140
+ };
141
+ out("deliberation setup");
142
+ out("");
143
+ const fileExists = (p) => {
144
+ if (typeof fsImpl.existsSync === "function") {
145
+ try {
146
+ return fsImpl.existsSync(p);
147
+ } catch (_) {
148
+ return false;
149
+ }
150
+ }
151
+ try {
152
+ return fsImpl.statSync(p).isFile();
153
+ } catch (_) {
154
+ return false;
155
+ }
156
+ };
157
+ const leaveUnchanged = () => {
158
+ out(`Config already exists at ${configPath} - leaving it unchanged.`);
159
+ out("");
160
+ print(consensusBlockLines());
161
+ out("");
162
+ print(openrouterExampleLines());
163
+ out("");
164
+ print(providerGuidanceLines());
165
+ return 0;
166
+ };
167
+ let stat = null;
168
+ try {
169
+ stat = fsImpl.statSync(configPath);
170
+ } catch (_) {
171
+ stat = null;
172
+ }
173
+ if (stat) {
174
+ if (stat.isFile()) return leaveUnchanged();
175
+ out(`Config path ${configPath} is not a regular file - refusing to write.`);
176
+ return 1;
177
+ }
178
+ try {
179
+ fsImpl.mkdirSync(path.dirname(configPath), { recursive: true });
180
+ } catch (err) {
181
+ const message = err instanceof Error ? err.message : String(err);
182
+ out(`Could not create config directory ${path.dirname(configPath)}: ${message}`);
183
+ return 1;
184
+ }
185
+ try {
186
+ fsImpl.writeFileSync(configPath, starterConfigText(), { flag: "wx" });
187
+ } catch (err) {
188
+ const code = err && typeof err === "object" && "code" in err ? err.code : null;
189
+ if (code === "EEXIST") return leaveUnchanged();
190
+ const message = err instanceof Error ? err.message : String(err);
191
+ if (fileExists(configPath) && typeof fsImpl.unlinkSync === "function") {
192
+ try {
193
+ fsImpl.unlinkSync(configPath);
194
+ } catch (_) {
195
+ }
196
+ }
197
+ out(`Could not write config at ${configPath}: ${message}`);
198
+ return 1;
199
+ }
200
+ out(`Wrote starter config at ${configPath}.`);
201
+ out("");
202
+ print(openrouterExampleLines());
203
+ out("");
204
+ print(providerGuidanceLines());
205
+ out("");
206
+ out("Next: set the env keys for the providers you use, then point your MCP");
207
+ out("host at the deliberation server (npx -y @antonbabenko/deliberation-mcp).");
208
+ return 0;
209
+ }
210
+ module.exports = { runSetup, starterConfigText, STARTER_CONFIG };
211
+ if (require.main === module) {
212
+ process.exit(runSetup());
213
+ }
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "@antonbabenko/deliberation-mcp",
3
- "version": "0.1.0",
3
+ "version": "3.0.0",
4
4
  "description": "Deliberation for Claude Code and any MCP host - GPT, Gemini, Grok, and OpenRouter expert subagents.",
5
5
  "mcpName": "io.github.antonbabenko/deliberation",
6
- "bin": { "deliberation-mcp": "./dist/index.js" },
6
+ "bin": { "deliberation-mcp": "./dist/index.js", "deliberation-setup": "./dist/setup.js" },
7
7
  "main": "./dist/index.js",
8
8
  "files": ["dist/"],
9
9
  "engines": { "node": ">=18" },
10
10
  "scripts": {
11
- "prepack": "esbuild index.js --bundle --platform=node --target=node18 --format=cjs --outfile=dist/index.js"
11
+ "prepack": "esbuild index.js setup.js --bundle --platform=node --target=node18 --format=cjs --outdir=dist"
12
12
  },
13
13
  "devDependencies": { "esbuild": "^0.28.0" },
14
14
  "license": "MIT"