@pruddiman/dispatch 1.5.0-beta.d367268-beta.59288b9 → 1.5.0-beta.e74ea4e
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/dist/cli.js +140 -47
- package/dist/cli.js.map +1 -1
- package/dist/mcp/dispatch-worker.js +29 -11
- package/dist/mcp/dispatch-worker.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1760,13 +1760,18 @@ async function checkCopilotAuth() {
|
|
|
1760
1760
|
return { status: "authenticated" };
|
|
1761
1761
|
}
|
|
1762
1762
|
try {
|
|
1763
|
-
await exec3("
|
|
1763
|
+
await exec3("copilot", ["auth", "status"], { timeout: AUTH_PROBE_TIMEOUT_MS });
|
|
1764
1764
|
return { status: "authenticated" };
|
|
1765
1765
|
} catch {
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
}
|
|
1766
|
+
try {
|
|
1767
|
+
await exec3("gh", ["auth", "status"], { timeout: AUTH_PROBE_TIMEOUT_MS });
|
|
1768
|
+
return { status: "authenticated" };
|
|
1769
|
+
} catch {
|
|
1770
|
+
return {
|
|
1771
|
+
status: "not-configured",
|
|
1772
|
+
hint: "Run 'copilot login' or set GITHUB_TOKEN"
|
|
1773
|
+
};
|
|
1774
|
+
}
|
|
1770
1775
|
}
|
|
1771
1776
|
}
|
|
1772
1777
|
async function checkClaudeAuth() {
|
|
@@ -1779,7 +1784,7 @@ async function checkClaudeAuth() {
|
|
|
1779
1784
|
} catch {
|
|
1780
1785
|
return {
|
|
1781
1786
|
status: "not-configured",
|
|
1782
|
-
hint: "
|
|
1787
|
+
hint: "Run 'claude auth login' or set ANTHROPIC_API_KEY"
|
|
1783
1788
|
};
|
|
1784
1789
|
}
|
|
1785
1790
|
}
|
|
@@ -1787,19 +1792,32 @@ async function checkCodexAuth() {
|
|
|
1787
1792
|
if (process.env.OPENAI_API_KEY) {
|
|
1788
1793
|
return { status: "authenticated" };
|
|
1789
1794
|
}
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
}
|
|
1795
|
+
try {
|
|
1796
|
+
await exec3("codex", ["auth", "status"], { timeout: AUTH_PROBE_TIMEOUT_MS });
|
|
1797
|
+
return { status: "authenticated" };
|
|
1798
|
+
} catch {
|
|
1799
|
+
return {
|
|
1800
|
+
status: "not-configured",
|
|
1801
|
+
hint: "Run 'codex login --device-auth' or set OPENAI_API_KEY"
|
|
1802
|
+
};
|
|
1803
|
+
}
|
|
1794
1804
|
}
|
|
1795
1805
|
async function checkOpencodeAuth() {
|
|
1796
1806
|
try {
|
|
1797
1807
|
await exec3("opencode", ["--version"], { timeout: AUTH_PROBE_TIMEOUT_MS });
|
|
1808
|
+
} catch {
|
|
1809
|
+
return {
|
|
1810
|
+
status: "not-configured",
|
|
1811
|
+
hint: "Install OpenCode (https://opencode.ai)"
|
|
1812
|
+
};
|
|
1813
|
+
}
|
|
1814
|
+
try {
|
|
1815
|
+
await exec3("opencode", ["auth", "status"], { timeout: AUTH_PROBE_TIMEOUT_MS });
|
|
1798
1816
|
return { status: "authenticated" };
|
|
1799
1817
|
} catch {
|
|
1800
1818
|
return {
|
|
1801
1819
|
status: "not-configured",
|
|
1802
|
-
hint: "
|
|
1820
|
+
hint: "Run 'opencode auth login' or set provider API keys"
|
|
1803
1821
|
};
|
|
1804
1822
|
}
|
|
1805
1823
|
}
|
|
@@ -2080,28 +2098,28 @@ async function setupCopilotAuth() {
|
|
|
2080
2098
|
const method = await select({
|
|
2081
2099
|
message: "How would you like to authenticate?",
|
|
2082
2100
|
choices: [
|
|
2083
|
-
{ name: "
|
|
2084
|
-
{ name: "
|
|
2101
|
+
{ name: "Copilot CLI login", value: "cli-login", description: "Run 'copilot login' \u2014 device code flow" },
|
|
2102
|
+
{ name: "API key (environment variable)", value: "env-var", description: "Set GITHUB_TOKEN or GH_TOKEN manually" }
|
|
2085
2103
|
]
|
|
2086
2104
|
});
|
|
2087
|
-
if (method === "
|
|
2105
|
+
if (method === "cli-login") {
|
|
2088
2106
|
try {
|
|
2089
|
-
log.info("Running '
|
|
2107
|
+
log.info("Running 'copilot login'...");
|
|
2090
2108
|
const { spawn } = await import("child_process");
|
|
2091
2109
|
await new Promise((resolve5, reject) => {
|
|
2092
|
-
const child = spawn("
|
|
2110
|
+
const child = spawn("copilot", ["login"], {
|
|
2093
2111
|
stdio: "inherit",
|
|
2094
2112
|
timeout: AUTH_CMD_TIMEOUT_MS
|
|
2095
2113
|
});
|
|
2096
2114
|
child.on(
|
|
2097
2115
|
"close",
|
|
2098
|
-
(code) => code === 0 ? resolve5() : reject(new Error(`
|
|
2116
|
+
(code) => code === 0 ? resolve5() : reject(new Error(`copilot login exited with code ${code}`))
|
|
2099
2117
|
);
|
|
2100
2118
|
child.on("error", reject);
|
|
2101
2119
|
});
|
|
2102
2120
|
return await verifyAuth("copilot");
|
|
2103
2121
|
} catch (err) {
|
|
2104
|
-
log.warn(`
|
|
2122
|
+
log.warn(`Copilot CLI auth failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
2105
2123
|
return false;
|
|
2106
2124
|
}
|
|
2107
2125
|
}
|
|
@@ -2118,28 +2136,28 @@ async function setupClaudeAuth() {
|
|
|
2118
2136
|
const method = await select({
|
|
2119
2137
|
message: "How would you like to authenticate?",
|
|
2120
2138
|
choices: [
|
|
2121
|
-
{ name: "
|
|
2122
|
-
{ name: "
|
|
2139
|
+
{ name: "Claude CLI login", value: "cli-login", description: "Run 'claude auth login' \u2014 opens a browser" },
|
|
2140
|
+
{ name: "API key (environment variable)", value: "env-var", description: "Set ANTHROPIC_API_KEY manually" }
|
|
2123
2141
|
]
|
|
2124
2142
|
});
|
|
2125
2143
|
if (method === "cli-login") {
|
|
2126
2144
|
try {
|
|
2127
|
-
log.info("Running 'claude login'...");
|
|
2145
|
+
log.info("Running 'claude auth login'...");
|
|
2128
2146
|
const { spawn } = await import("child_process");
|
|
2129
2147
|
await new Promise((resolve5, reject) => {
|
|
2130
|
-
const child = spawn("claude", ["login"], {
|
|
2148
|
+
const child = spawn("claude", ["auth", "login"], {
|
|
2131
2149
|
stdio: "inherit",
|
|
2132
2150
|
timeout: AUTH_CMD_TIMEOUT_MS
|
|
2133
2151
|
});
|
|
2134
2152
|
child.on(
|
|
2135
2153
|
"close",
|
|
2136
|
-
(code) => code === 0 ? resolve5() : reject(new Error(`claude login exited with code ${code}`))
|
|
2154
|
+
(code) => code === 0 ? resolve5() : reject(new Error(`claude auth login exited with code ${code}`))
|
|
2137
2155
|
);
|
|
2138
2156
|
child.on("error", reject);
|
|
2139
2157
|
});
|
|
2140
2158
|
return await verifyAuth("claude");
|
|
2141
2159
|
} catch (err) {
|
|
2142
|
-
log.warn(`Claude
|
|
2160
|
+
log.warn(`Claude CLI auth failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
2143
2161
|
return false;
|
|
2144
2162
|
}
|
|
2145
2163
|
}
|
|
@@ -2152,6 +2170,34 @@ async function setupClaudeAuth() {
|
|
|
2152
2170
|
async function setupCodexAuth() {
|
|
2153
2171
|
log.info("OpenAI Codex Authentication");
|
|
2154
2172
|
console.log();
|
|
2173
|
+
const method = await select({
|
|
2174
|
+
message: "How would you like to authenticate?",
|
|
2175
|
+
choices: [
|
|
2176
|
+
{ name: "ChatGPT sign-in", value: "cli-login", description: "Run 'codex login --device-auth' \u2014 device code flow" },
|
|
2177
|
+
{ name: "API key (environment variable)", value: "env-var", description: "Set OPENAI_API_KEY manually" }
|
|
2178
|
+
]
|
|
2179
|
+
});
|
|
2180
|
+
if (method === "cli-login") {
|
|
2181
|
+
try {
|
|
2182
|
+
log.info("Running 'codex login --device-auth'...");
|
|
2183
|
+
const { spawn } = await import("child_process");
|
|
2184
|
+
await new Promise((resolve5, reject) => {
|
|
2185
|
+
const child = spawn("codex", ["login", "--device-auth"], {
|
|
2186
|
+
stdio: "inherit",
|
|
2187
|
+
timeout: AUTH_CMD_TIMEOUT_MS
|
|
2188
|
+
});
|
|
2189
|
+
child.on(
|
|
2190
|
+
"close",
|
|
2191
|
+
(code) => code === 0 ? resolve5() : reject(new Error(`codex login exited with code ${code}`))
|
|
2192
|
+
);
|
|
2193
|
+
child.on("error", reject);
|
|
2194
|
+
});
|
|
2195
|
+
return await verifyAuth("codex");
|
|
2196
|
+
} catch (err) {
|
|
2197
|
+
log.warn(`Codex CLI auth failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
2198
|
+
return false;
|
|
2199
|
+
}
|
|
2200
|
+
}
|
|
2155
2201
|
log.info("Set the following environment variable in your shell profile:");
|
|
2156
2202
|
log.info(" OPENAI_API_KEY=<your API key>");
|
|
2157
2203
|
console.log();
|
|
@@ -2161,10 +2207,40 @@ async function setupCodexAuth() {
|
|
|
2161
2207
|
async function setupOpencodeAuth() {
|
|
2162
2208
|
log.info("OpenCode Authentication");
|
|
2163
2209
|
console.log();
|
|
2164
|
-
|
|
2165
|
-
|
|
2210
|
+
const method = await select({
|
|
2211
|
+
message: "How would you like to authenticate?",
|
|
2212
|
+
choices: [
|
|
2213
|
+
{ name: "OpenCode CLI login", value: "cli-login", description: "Run 'opencode auth login' interactively" },
|
|
2214
|
+
{ name: "API key (environment variable)", value: "env-var", description: "Set provider API keys manually" }
|
|
2215
|
+
]
|
|
2216
|
+
});
|
|
2217
|
+
if (method === "cli-login") {
|
|
2218
|
+
try {
|
|
2219
|
+
log.info("Running 'opencode auth login'...");
|
|
2220
|
+
const { spawn } = await import("child_process");
|
|
2221
|
+
await new Promise((resolve5, reject) => {
|
|
2222
|
+
const child = spawn("opencode", ["auth", "login"], {
|
|
2223
|
+
stdio: "inherit",
|
|
2224
|
+
timeout: AUTH_CMD_TIMEOUT_MS
|
|
2225
|
+
});
|
|
2226
|
+
child.on(
|
|
2227
|
+
"close",
|
|
2228
|
+
(code) => code === 0 ? resolve5() : reject(new Error(`opencode auth login exited with code ${code}`))
|
|
2229
|
+
);
|
|
2230
|
+
child.on("error", reject);
|
|
2231
|
+
});
|
|
2232
|
+
return await verifyAuth("opencode");
|
|
2233
|
+
} catch (err) {
|
|
2234
|
+
log.warn(`OpenCode CLI auth failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
2235
|
+
return false;
|
|
2236
|
+
}
|
|
2237
|
+
}
|
|
2238
|
+
log.info("Set the relevant API key environment variable in your shell profile.");
|
|
2239
|
+
log.info("For example:");
|
|
2240
|
+
log.info(" ANTHROPIC_API_KEY=<your API key>");
|
|
2241
|
+
log.info(" OPENAI_API_KEY=<your API key>");
|
|
2166
2242
|
console.log();
|
|
2167
|
-
log.dim("After
|
|
2243
|
+
log.dim("After setting the variable, restart your terminal and re-run 'dispatch config'.");
|
|
2168
2244
|
return false;
|
|
2169
2245
|
}
|
|
2170
2246
|
async function verifyAuth(name) {
|
|
@@ -2237,25 +2313,41 @@ async function runInteractiveConfigWizard(configDir) {
|
|
|
2237
2313
|
console.log(`${indicator} ${ps.displayName.padEnd(18)} ${statusLabel} ${tierLabel}`);
|
|
2238
2314
|
}
|
|
2239
2315
|
console.log();
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2316
|
+
log.info("Select which providers you want to enable:");
|
|
2317
|
+
console.log();
|
|
2318
|
+
const selectedProviders = [];
|
|
2319
|
+
for (const ps of providerStatuses) {
|
|
2320
|
+
const isAuth = ps.authStatus.status === "authenticated";
|
|
2321
|
+
const suffix = !isAuth ? " (not yet authenticated)" : "";
|
|
2322
|
+
const enable = await confirm({
|
|
2323
|
+
message: `Enable ${ps.displayName}?${suffix}`,
|
|
2324
|
+
default: isAuth
|
|
2325
|
+
});
|
|
2326
|
+
if (enable) selectedProviders.push(ps.name);
|
|
2327
|
+
}
|
|
2328
|
+
if (selectedProviders.length === 0) {
|
|
2329
|
+
log.error("At least one provider must be enabled to use Dispatch.");
|
|
2330
|
+
log.dim("Re-run 'dispatch config' to enable providers.");
|
|
2331
|
+
return;
|
|
2332
|
+
}
|
|
2333
|
+
const needsAuth = selectedProviders.filter((name) => {
|
|
2334
|
+
const ps = providerStatuses.find((p) => p.name === name);
|
|
2335
|
+
return ps && ps.authStatus.status !== "authenticated";
|
|
2336
|
+
});
|
|
2337
|
+
if (needsAuth.length > 0) {
|
|
2338
|
+
console.log();
|
|
2339
|
+
for (const name of needsAuth) {
|
|
2340
|
+
console.log();
|
|
2341
|
+
await setupProviderAuth(name);
|
|
2342
|
+
console.log();
|
|
2254
2343
|
}
|
|
2255
2344
|
providerStatuses = await getProviderStatuses();
|
|
2256
2345
|
}
|
|
2257
|
-
const
|
|
2258
|
-
|
|
2346
|
+
const enabledProviders = selectedProviders.filter((name) => {
|
|
2347
|
+
const ps = providerStatuses.find((p) => p.name === name);
|
|
2348
|
+
return ps && ps.authStatus.status === "authenticated";
|
|
2349
|
+
});
|
|
2350
|
+
if (enabledProviders.length === 0) {
|
|
2259
2351
|
log.error("At least one provider must be authenticated to use Dispatch.");
|
|
2260
2352
|
log.dim("Re-run 'dispatch config' after setting up provider credentials.");
|
|
2261
2353
|
return;
|
|
@@ -2263,12 +2355,13 @@ async function runInteractiveConfigWizard(configDir) {
|
|
|
2263
2355
|
console.log();
|
|
2264
2356
|
log.info("Provider status:");
|
|
2265
2357
|
for (const ps of providerStatuses) {
|
|
2266
|
-
const
|
|
2358
|
+
const isEnabled = enabledProviders.includes(ps.name);
|
|
2359
|
+
const indicator = isEnabled ? "\u2713" : "\u2717";
|
|
2267
2360
|
console.log(` ${indicator} ${ps.displayName}`);
|
|
2268
2361
|
}
|
|
2269
2362
|
console.log();
|
|
2270
2363
|
log.info(
|
|
2271
|
-
`${
|
|
2364
|
+
`${enabledProviders.length} provider(s) enabled. Dispatch will automatically route tasks to the best available provider.`
|
|
2272
2365
|
);
|
|
2273
2366
|
console.log();
|
|
2274
2367
|
const detectedSource = await detectDatasource(process.cwd());
|
|
@@ -2346,7 +2439,7 @@ async function runInteractiveConfigWizard(configDir) {
|
|
|
2346
2439
|
const existingConfig = await loadConfig(configDir);
|
|
2347
2440
|
const newConfig = {
|
|
2348
2441
|
...existingConfig,
|
|
2349
|
-
enabledProviders
|
|
2442
|
+
enabledProviders,
|
|
2350
2443
|
source
|
|
2351
2444
|
};
|
|
2352
2445
|
if (org !== void 0) newConfig.org = org;
|
|
@@ -8773,7 +8866,7 @@ async function main() {
|
|
|
8773
8866
|
process.exit(0);
|
|
8774
8867
|
}
|
|
8775
8868
|
if (args.version) {
|
|
8776
|
-
console.log(`dispatch v${"1.5.0-beta.
|
|
8869
|
+
console.log(`dispatch v${"1.5.0-beta.e74ea4e"}`);
|
|
8777
8870
|
process.exit(0);
|
|
8778
8871
|
}
|
|
8779
8872
|
const orchestrator = await boot5({ cwd: args.cwd });
|