llm-party-cli 0.7.1 → 0.9.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.
- package/README.md +54 -22
- package/dist/index.js +685 -374
- package/package.json +1 -1
- package/prompts/artifacts.md +61 -4
- package/prompts/base.md +38 -3
package/dist/index.js
CHANGED
|
@@ -37551,8 +37551,11 @@ var render = async (node, rendererOrConfig = {}) => {
|
|
|
37551
37551
|
import { query } from "@anthropic-ai/claude-agent-sdk";
|
|
37552
37552
|
|
|
37553
37553
|
// src/adapters/base.ts
|
|
37554
|
-
function formatTranscript(messages) {
|
|
37555
|
-
return messages.map((m2) =>
|
|
37554
|
+
function formatTranscript(messages, agentName, humanName) {
|
|
37555
|
+
return messages.map((m2) => {
|
|
37556
|
+
const role = m2.from === agentName ? "you" : m2.from === humanName ? "user" : "agent";
|
|
37557
|
+
return `${m2.from} (${role}):: ${m2.text}`;
|
|
37558
|
+
}).join(`
|
|
37556
37559
|
|
|
37557
37560
|
`);
|
|
37558
37561
|
}
|
|
@@ -37561,13 +37564,15 @@ function formatTranscript(messages) {
|
|
|
37561
37564
|
class ClaudeBaseAdapter {
|
|
37562
37565
|
name;
|
|
37563
37566
|
model;
|
|
37567
|
+
humanName;
|
|
37564
37568
|
systemPrompt = "";
|
|
37565
37569
|
sessionId = "";
|
|
37566
37570
|
runtimeEnv = {};
|
|
37567
37571
|
claudeExecutable;
|
|
37568
|
-
constructor(name, model) {
|
|
37572
|
+
constructor(name, model, humanName) {
|
|
37569
37573
|
this.name = name;
|
|
37570
37574
|
this.model = model;
|
|
37575
|
+
this.humanName = humanName;
|
|
37571
37576
|
}
|
|
37572
37577
|
async init(config) {
|
|
37573
37578
|
this.systemPrompt = config.resolvedPrompt ?? "";
|
|
@@ -37575,10 +37580,23 @@ class ClaudeBaseAdapter {
|
|
|
37575
37580
|
this.claudeExecutable = config.executablePath ?? process.env.CLAUDE_CODE_EXECUTABLE;
|
|
37576
37581
|
}
|
|
37577
37582
|
async buildEnv(config) {
|
|
37578
|
-
|
|
37583
|
+
const configEnv = config.env ?? {};
|
|
37584
|
+
const mapped = {};
|
|
37585
|
+
if (configEnv.AUTH_URL) {
|
|
37586
|
+
mapped.ANTHROPIC_BASE_URL = configEnv.AUTH_URL;
|
|
37587
|
+
}
|
|
37588
|
+
if (configEnv.AUTH_TOKEN) {
|
|
37589
|
+
mapped.ANTHROPIC_AUTH_TOKEN = configEnv.AUTH_TOKEN;
|
|
37590
|
+
}
|
|
37591
|
+
if (configEnv.AUTH_URL || configEnv.AUTH_TOKEN) {
|
|
37592
|
+
mapped.ANTHROPIC_DEFAULT_HAIKU_MODEL = this.model;
|
|
37593
|
+
mapped.ANTHROPIC_DEFAULT_SONNET_MODEL = this.model;
|
|
37594
|
+
mapped.ANTHROPIC_DEFAULT_OPUS_MODEL = this.model;
|
|
37595
|
+
}
|
|
37596
|
+
return { ...process.env, ...mapped, ...configEnv };
|
|
37579
37597
|
}
|
|
37580
37598
|
async send(messages, signal) {
|
|
37581
|
-
return await this.querySDK(formatTranscript(messages), signal);
|
|
37599
|
+
return await this.querySDK(formatTranscript(messages, this.name, this.humanName), signal);
|
|
37582
37600
|
}
|
|
37583
37601
|
async destroy() {
|
|
37584
37602
|
return;
|
|
@@ -38061,11 +38079,13 @@ class CodexAdapter {
|
|
|
38061
38079
|
name;
|
|
38062
38080
|
provider = "codex";
|
|
38063
38081
|
model;
|
|
38082
|
+
humanName;
|
|
38064
38083
|
codex;
|
|
38065
38084
|
thread;
|
|
38066
|
-
constructor(name, model) {
|
|
38085
|
+
constructor(name, model, humanName) {
|
|
38067
38086
|
this.name = name;
|
|
38068
38087
|
this.model = model;
|
|
38088
|
+
this.humanName = humanName;
|
|
38069
38089
|
}
|
|
38070
38090
|
async init(config) {
|
|
38071
38091
|
const cliPath = config.executablePath ?? process.env.CODEX_CLI_EXECUTABLE;
|
|
@@ -38090,7 +38110,7 @@ class CodexAdapter {
|
|
|
38090
38110
|
if (signal?.aborted) {
|
|
38091
38111
|
return "[Aborted] Codex was cancelled";
|
|
38092
38112
|
}
|
|
38093
|
-
const turn = await this.thread.run(formatTranscript(messages));
|
|
38113
|
+
const turn = await this.thread.run(formatTranscript(messages, this.name, this.humanName));
|
|
38094
38114
|
if (turn.finalResponse && turn.finalResponse.length > 0) {
|
|
38095
38115
|
return turn.finalResponse;
|
|
38096
38116
|
}
|
|
@@ -39276,14 +39296,16 @@ class CopilotAdapter {
|
|
|
39276
39296
|
name;
|
|
39277
39297
|
provider = "copilot";
|
|
39278
39298
|
model;
|
|
39299
|
+
humanName;
|
|
39279
39300
|
client;
|
|
39280
39301
|
session;
|
|
39281
39302
|
systemPrompt = "";
|
|
39282
39303
|
cliPath;
|
|
39283
39304
|
timeout = 600000;
|
|
39284
|
-
constructor(name, model) {
|
|
39305
|
+
constructor(name, model, humanName) {
|
|
39285
39306
|
this.name = name;
|
|
39286
39307
|
this.model = model;
|
|
39308
|
+
this.humanName = humanName;
|
|
39287
39309
|
}
|
|
39288
39310
|
async init(config) {
|
|
39289
39311
|
this.systemPrompt = config.resolvedPrompt ?? "";
|
|
@@ -39300,7 +39322,7 @@ class CopilotAdapter {
|
|
|
39300
39322
|
if (signal?.aborted) {
|
|
39301
39323
|
return "[Aborted] Copilot was cancelled";
|
|
39302
39324
|
}
|
|
39303
|
-
const transcript = formatTranscript(messages);
|
|
39325
|
+
const transcript = formatTranscript(messages, this.name, this.humanName);
|
|
39304
39326
|
try {
|
|
39305
39327
|
return await this.sendToSession(transcript);
|
|
39306
39328
|
} catch (err) {
|
|
@@ -39354,62 +39376,9 @@ class CopilotAdapter {
|
|
|
39354
39376
|
}
|
|
39355
39377
|
}
|
|
39356
39378
|
|
|
39357
|
-
// src/adapters/
|
|
39358
|
-
|
|
39359
|
-
|
|
39360
|
-
provider = "glm";
|
|
39361
|
-
async buildEnv(config) {
|
|
39362
|
-
const aliasEnv = await loadGlmAliasEnv();
|
|
39363
|
-
return { ...process.env, ...aliasEnv, ...config.env ?? {} };
|
|
39364
|
-
}
|
|
39365
|
-
}
|
|
39366
|
-
function detectShell() {
|
|
39367
|
-
if (process.env.SHELL) {
|
|
39368
|
-
return process.env.SHELL;
|
|
39369
|
-
}
|
|
39370
|
-
return "/bin/sh";
|
|
39371
|
-
}
|
|
39372
|
-
async function loadGlmAliasEnv() {
|
|
39373
|
-
const shell = detectShell();
|
|
39374
|
-
const isInteractive = shell.endsWith("zsh") || shell.endsWith("bash");
|
|
39375
|
-
const args = isInteractive ? ["-ic", "alias glm"] : ["-c", "alias glm"];
|
|
39376
|
-
return new Promise((resolve4) => {
|
|
39377
|
-
const child = spawn3(shell, args, {
|
|
39378
|
-
cwd: process.cwd(),
|
|
39379
|
-
env: process.env,
|
|
39380
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
39381
|
-
});
|
|
39382
|
-
let stdout = "";
|
|
39383
|
-
const timeout = setTimeout(() => {
|
|
39384
|
-
child.kill("SIGTERM");
|
|
39385
|
-
resolve4({});
|
|
39386
|
-
}, 5000);
|
|
39387
|
-
child.stdout.on("data", (chunk) => {
|
|
39388
|
-
stdout += String(chunk);
|
|
39389
|
-
});
|
|
39390
|
-
child.on("close", (code) => {
|
|
39391
|
-
clearTimeout(timeout);
|
|
39392
|
-
if (code !== 0) {
|
|
39393
|
-
resolve4({});
|
|
39394
|
-
return;
|
|
39395
|
-
}
|
|
39396
|
-
const env2 = {};
|
|
39397
|
-
const tokens = stdout.match(/[A-Z_]+="[^"]*"/g) ?? [];
|
|
39398
|
-
for (const token of tokens) {
|
|
39399
|
-
const eqIdx = token.indexOf("=");
|
|
39400
|
-
if (eqIdx === -1)
|
|
39401
|
-
continue;
|
|
39402
|
-
const key = token.slice(0, eqIdx);
|
|
39403
|
-
const raw = token.slice(eqIdx + 1);
|
|
39404
|
-
env2[key] = raw.replace(/^"|"$/g, "");
|
|
39405
|
-
}
|
|
39406
|
-
resolve4(env2);
|
|
39407
|
-
});
|
|
39408
|
-
child.on("error", () => {
|
|
39409
|
-
clearTimeout(timeout);
|
|
39410
|
-
resolve4({});
|
|
39411
|
-
});
|
|
39412
|
-
});
|
|
39379
|
+
// src/adapters/custom.ts
|
|
39380
|
+
class CustomAdapter extends ClaudeBaseAdapter {
|
|
39381
|
+
provider = "custom";
|
|
39413
39382
|
}
|
|
39414
39383
|
|
|
39415
39384
|
// src/config/loader.ts
|
|
@@ -39448,27 +39417,11 @@ var PROVIDERS = [
|
|
|
39448
39417
|
defaultTag: "copilot",
|
|
39449
39418
|
detectCommand: "copilot",
|
|
39450
39419
|
detectType: "binary"
|
|
39451
|
-
},
|
|
39452
|
-
{
|
|
39453
|
-
id: "glm",
|
|
39454
|
-
displayName: "GLM",
|
|
39455
|
-
description: "glm alias configured on Claude Code CLI",
|
|
39456
|
-
unavailableHint: "glm shell alias not configured",
|
|
39457
|
-
defaultModel: "glm-5",
|
|
39458
|
-
defaultTag: "glm",
|
|
39459
|
-
detectCommand: "glm",
|
|
39460
|
-
detectType: "alias",
|
|
39461
|
-
env: {
|
|
39462
|
-
ANTHROPIC_BASE_URL: "https://api.z.ai/api/anthropic",
|
|
39463
|
-
ANTHROPIC_DEFAULT_HAIKU_MODEL: "glm-4.5-air",
|
|
39464
|
-
ANTHROPIC_DEFAULT_SONNET_MODEL: "glm-4.5",
|
|
39465
|
-
ANTHROPIC_DEFAULT_OPUS_MODEL: "glm-5"
|
|
39466
|
-
}
|
|
39467
39420
|
}
|
|
39468
39421
|
];
|
|
39469
39422
|
|
|
39470
39423
|
// src/config/loader.ts
|
|
39471
|
-
var VALID_PROVIDER_IDS = new Set(PROVIDERS.map((p) => p.id));
|
|
39424
|
+
var VALID_PROVIDER_IDS = new Set([...PROVIDERS.map((p) => p.id), "custom"]);
|
|
39472
39425
|
var LLM_PARTY_HOME = path8.join(homedir(), ".llm-party");
|
|
39473
39426
|
var MIND_MAP_INDEX = `# Living Memory Neural Network
|
|
39474
39427
|
|
|
@@ -39654,9 +39607,23 @@ async function configExists() {
|
|
|
39654
39607
|
return false;
|
|
39655
39608
|
}
|
|
39656
39609
|
}
|
|
39610
|
+
function migrateProviders(data) {
|
|
39611
|
+
if (!Array.isArray(data.agents))
|
|
39612
|
+
return;
|
|
39613
|
+
for (const agent of data.agents) {
|
|
39614
|
+
if (!agent || typeof agent !== "object")
|
|
39615
|
+
continue;
|
|
39616
|
+
if (typeof agent.provider === "string" && !VALID_PROVIDER_IDS.has(agent.provider)) {
|
|
39617
|
+
agent.provider = "custom";
|
|
39618
|
+
if (!agent.cli)
|
|
39619
|
+
agent.cli = "claude";
|
|
39620
|
+
}
|
|
39621
|
+
}
|
|
39622
|
+
}
|
|
39657
39623
|
async function loadConfig2(configPath) {
|
|
39658
39624
|
const raw = await readFile3(configPath, "utf8");
|
|
39659
39625
|
const parsed = JSON.parse(raw);
|
|
39626
|
+
migrateProviders(parsed);
|
|
39660
39627
|
validateConfig(parsed);
|
|
39661
39628
|
return normalizeConfig(parsed);
|
|
39662
39629
|
}
|
|
@@ -39892,7 +39859,7 @@ function createSessionId() {
|
|
|
39892
39859
|
}
|
|
39893
39860
|
|
|
39894
39861
|
// src/ui/App.tsx
|
|
39895
|
-
import { spawn as
|
|
39862
|
+
import { spawn as spawn4 } from "child_process";
|
|
39896
39863
|
|
|
39897
39864
|
// src/ui/useOrchestrator.ts
|
|
39898
39865
|
import { execFile } from "child_process";
|
|
@@ -40314,7 +40281,7 @@ function InputLine(props) {
|
|
|
40314
40281
|
useKeyboard((key) => {
|
|
40315
40282
|
if (props.disabled)
|
|
40316
40283
|
return;
|
|
40317
|
-
if (key.shift && (key.name === "enter" || key.name === "return")) {
|
|
40284
|
+
if ((key.shift || key.option || key.meta) && (key.name === "enter" || key.name === "return")) {
|
|
40318
40285
|
update(value.slice(0, cursor) + `
|
|
40319
40286
|
` + value.slice(cursor), cursor + 1);
|
|
40320
40287
|
return;
|
|
@@ -40529,15 +40496,15 @@ function InputLine(props) {
|
|
|
40529
40496
|
}
|
|
40530
40497
|
|
|
40531
40498
|
// src/ui/ConfigWizard.tsx
|
|
40532
|
-
import { userInfo as
|
|
40499
|
+
import { userInfo as userInfo2 } from "os";
|
|
40533
40500
|
|
|
40534
40501
|
// src/config/detector.ts
|
|
40535
|
-
import { spawn as
|
|
40502
|
+
import { spawn as spawn3 } from "child_process";
|
|
40536
40503
|
var DETECT_TIMEOUT = 5000;
|
|
40537
40504
|
function detectBinary(command) {
|
|
40538
40505
|
return new Promise((resolve4) => {
|
|
40539
40506
|
const timer = setTimeout(() => resolve4({ available: false }), DETECT_TIMEOUT);
|
|
40540
|
-
const proc =
|
|
40507
|
+
const proc = spawn3(command, ["--version"], {
|
|
40541
40508
|
stdio: ["ignore", "pipe", "ignore"],
|
|
40542
40509
|
shell: true,
|
|
40543
40510
|
timeout: DETECT_TIMEOUT,
|
|
@@ -40562,33 +40529,13 @@ function detectBinary(command) {
|
|
|
40562
40529
|
});
|
|
40563
40530
|
});
|
|
40564
40531
|
}
|
|
40565
|
-
function detectAlias(command) {
|
|
40566
|
-
return new Promise((resolve4) => {
|
|
40567
|
-
const shell = process.env.SHELL || "/bin/bash";
|
|
40568
|
-
const timer = setTimeout(() => resolve4({ available: false }), DETECT_TIMEOUT);
|
|
40569
|
-
const proc = spawn4(shell, ["-ic", `type ${command}`], {
|
|
40570
|
-
stdio: ["ignore", "pipe", "ignore"],
|
|
40571
|
-
timeout: DETECT_TIMEOUT,
|
|
40572
|
-
detached: true
|
|
40573
|
-
});
|
|
40574
|
-
proc.unref();
|
|
40575
|
-
proc.on("close", (code) => {
|
|
40576
|
-
clearTimeout(timer);
|
|
40577
|
-
resolve4({ available: code === 0 });
|
|
40578
|
-
});
|
|
40579
|
-
proc.on("error", () => {
|
|
40580
|
-
clearTimeout(timer);
|
|
40581
|
-
resolve4({ available: false });
|
|
40582
|
-
});
|
|
40583
|
-
});
|
|
40584
|
-
}
|
|
40585
40532
|
async function detectProviders() {
|
|
40586
40533
|
const results = await Promise.allSettled(PROVIDERS.map(async (provider) => {
|
|
40587
|
-
const result =
|
|
40534
|
+
const result = await detectBinary(provider.detectCommand);
|
|
40588
40535
|
return {
|
|
40589
40536
|
id: provider.id,
|
|
40590
40537
|
available: result.available,
|
|
40591
|
-
version:
|
|
40538
|
+
version: result.version
|
|
40592
40539
|
};
|
|
40593
40540
|
}));
|
|
40594
40541
|
return results.map((result, i) => {
|
|
@@ -40600,57 +40547,8 @@ async function detectProviders() {
|
|
|
40600
40547
|
|
|
40601
40548
|
// src/config/writer.ts
|
|
40602
40549
|
import { writeFile as writeFile6, mkdir as mkdir6 } from "fs/promises";
|
|
40603
|
-
import { userInfo as userInfo2 } from "os";
|
|
40604
40550
|
import path10 from "path";
|
|
40605
|
-
async function
|
|
40606
|
-
const overrideMap = new Map((overrides || []).map((o) => [o.id, o]));
|
|
40607
|
-
const existingByProvider = new Map;
|
|
40608
|
-
if (existingConfig?.agents) {
|
|
40609
|
-
for (const agent of existingConfig.agents) {
|
|
40610
|
-
existingByProvider.set(agent.provider, agent);
|
|
40611
|
-
}
|
|
40612
|
-
}
|
|
40613
|
-
const agents = selectedIds.map((id) => {
|
|
40614
|
-
const def = PROVIDERS.find((p) => p.id === id);
|
|
40615
|
-
if (!def)
|
|
40616
|
-
throw new Error(`Unknown provider: ${id}`);
|
|
40617
|
-
const override = overrideMap.get(id);
|
|
40618
|
-
const existing = existingByProvider.get(id);
|
|
40619
|
-
const agent = {
|
|
40620
|
-
name: override?.name || def.displayName,
|
|
40621
|
-
tag: override?.tag || def.defaultTag,
|
|
40622
|
-
provider: def.id,
|
|
40623
|
-
model: override?.model || def.defaultModel
|
|
40624
|
-
};
|
|
40625
|
-
if (existing?.env) {
|
|
40626
|
-
agent.env = { ...existing.env };
|
|
40627
|
-
} else if (def.env) {
|
|
40628
|
-
agent.env = { ...def.env };
|
|
40629
|
-
}
|
|
40630
|
-
if (existing?.prompts)
|
|
40631
|
-
agent.prompts = existing.prompts;
|
|
40632
|
-
if (existing?.preloadSkills)
|
|
40633
|
-
agent.preloadSkills = existing.preloadSkills;
|
|
40634
|
-
if (existing?.executablePath)
|
|
40635
|
-
agent.executablePath = existing.executablePath;
|
|
40636
|
-
if (existing?.timeout)
|
|
40637
|
-
agent.timeout = existing.timeout;
|
|
40638
|
-
return agent;
|
|
40639
|
-
});
|
|
40640
|
-
const config = {
|
|
40641
|
-
humanName: existingConfig?.humanName || userInfo2().username || "USER",
|
|
40642
|
-
humanTag: existingConfig?.humanTag,
|
|
40643
|
-
maxAutoHops: existingConfig?.maxAutoHops ?? 15,
|
|
40644
|
-
timeout: existingConfig?.timeout,
|
|
40645
|
-
reminderInterval: existingConfig?.reminderInterval,
|
|
40646
|
-
agents
|
|
40647
|
-
};
|
|
40648
|
-
if (!config.humanTag)
|
|
40649
|
-
delete config.humanTag;
|
|
40650
|
-
if (config.timeout === undefined)
|
|
40651
|
-
delete config.timeout;
|
|
40652
|
-
if (config.reminderInterval === undefined)
|
|
40653
|
-
delete config.reminderInterval;
|
|
40551
|
+
async function writeConfig(config) {
|
|
40654
40552
|
await mkdir6(LLM_PARTY_HOME, { recursive: true });
|
|
40655
40553
|
const configPath = path10.join(LLM_PARTY_HOME, "config.json");
|
|
40656
40554
|
await writeFile6(configPath, JSON.stringify(config, null, 2) + `
|
|
@@ -40663,16 +40561,114 @@ function MultiSelect(props) {
|
|
|
40663
40561
|
const [focused, setFocused] = createSignal(props.items.findIndex((item) => !item.disabled));
|
|
40664
40562
|
const [selected, setSelected] = createSignal(new Set(props.initialSelected || []));
|
|
40665
40563
|
const [error, setError] = createSignal("");
|
|
40564
|
+
const [addingCustom, setAddingCustom] = createSignal(false);
|
|
40565
|
+
const [customName, setCustomName] = createSignal("");
|
|
40566
|
+
const [customCursor, setCustomCursor] = createSignal(0);
|
|
40567
|
+
const tuiRenderer = useRenderer();
|
|
40568
|
+
createEffect(() => {
|
|
40569
|
+
const handlePaste = (event) => {
|
|
40570
|
+
if (!addingCustom())
|
|
40571
|
+
return;
|
|
40572
|
+
const text = new TextDecoder().decode(event.bytes);
|
|
40573
|
+
if (!text)
|
|
40574
|
+
return;
|
|
40575
|
+
const cleaned = text.replace(/\n/g, "");
|
|
40576
|
+
if (!cleaned)
|
|
40577
|
+
return;
|
|
40578
|
+
const c = customCursor();
|
|
40579
|
+
const val = customName();
|
|
40580
|
+
setCustomName(val.slice(0, c) + cleaned + val.slice(c));
|
|
40581
|
+
setCustomCursor(c + cleaned.length);
|
|
40582
|
+
};
|
|
40583
|
+
tuiRenderer.keyInput.on("paste", handlePaste);
|
|
40584
|
+
onCleanup(() => {
|
|
40585
|
+
tuiRenderer.keyInput.off("paste", handlePaste);
|
|
40586
|
+
});
|
|
40587
|
+
});
|
|
40588
|
+
const totalRows = () => props.items.length + (props.addCustom ? 1 : 0);
|
|
40589
|
+
const isAddCustomRow = (idx) => props.addCustom && idx === props.items.length;
|
|
40666
40590
|
const findNextEnabled = (from, direction) => {
|
|
40591
|
+
const total = totalRows();
|
|
40667
40592
|
let idx = from;
|
|
40668
|
-
for (let i = 0;i <
|
|
40669
|
-
idx = (idx + direction +
|
|
40593
|
+
for (let i = 0;i < total; i++) {
|
|
40594
|
+
idx = (idx + direction + total) % total;
|
|
40595
|
+
if (isAddCustomRow(idx))
|
|
40596
|
+
return idx;
|
|
40670
40597
|
if (!props.items[idx].disabled)
|
|
40671
40598
|
return idx;
|
|
40672
40599
|
}
|
|
40673
40600
|
return from;
|
|
40674
40601
|
};
|
|
40675
40602
|
useKeyboard((key) => {
|
|
40603
|
+
if (addingCustom()) {
|
|
40604
|
+
if (key.name === "escape") {
|
|
40605
|
+
setAddingCustom(false);
|
|
40606
|
+
setCustomName("");
|
|
40607
|
+
setCustomCursor(0);
|
|
40608
|
+
return;
|
|
40609
|
+
}
|
|
40610
|
+
if (key.name === "enter" || key.name === "return") {
|
|
40611
|
+
const name = customName().trim();
|
|
40612
|
+
if (name.length > 0) {
|
|
40613
|
+
props.addCustom.onAdd(name);
|
|
40614
|
+
setAddingCustom(false);
|
|
40615
|
+
setCustomName("");
|
|
40616
|
+
setCustomCursor(0);
|
|
40617
|
+
}
|
|
40618
|
+
return;
|
|
40619
|
+
}
|
|
40620
|
+
if (key.name === "backspace") {
|
|
40621
|
+
const c = customCursor();
|
|
40622
|
+
if (c > 0) {
|
|
40623
|
+
const val = customName();
|
|
40624
|
+
setCustomName(val.slice(0, c - 1) + val.slice(c));
|
|
40625
|
+
setCustomCursor(c - 1);
|
|
40626
|
+
}
|
|
40627
|
+
return;
|
|
40628
|
+
}
|
|
40629
|
+
if (key.name === "delete") {
|
|
40630
|
+
const c = customCursor();
|
|
40631
|
+
const val = customName();
|
|
40632
|
+
if (c < val.length) {
|
|
40633
|
+
setCustomName(val.slice(0, c) + val.slice(c + 1));
|
|
40634
|
+
}
|
|
40635
|
+
return;
|
|
40636
|
+
}
|
|
40637
|
+
if (key.name === "left") {
|
|
40638
|
+
setCustomCursor((c) => Math.max(0, c - 1));
|
|
40639
|
+
return;
|
|
40640
|
+
}
|
|
40641
|
+
if (key.name === "right") {
|
|
40642
|
+
setCustomCursor((c) => Math.min(customName().length, c + 1));
|
|
40643
|
+
return;
|
|
40644
|
+
}
|
|
40645
|
+
if (key.name === "home" || key.ctrl && key.name === "a") {
|
|
40646
|
+
setCustomCursor(0);
|
|
40647
|
+
return;
|
|
40648
|
+
}
|
|
40649
|
+
if (key.name === "end" || key.ctrl && key.name === "e") {
|
|
40650
|
+
setCustomCursor(customName().length);
|
|
40651
|
+
return;
|
|
40652
|
+
}
|
|
40653
|
+
if (key.ctrl && key.name === "u") {
|
|
40654
|
+
setCustomName("");
|
|
40655
|
+
setCustomCursor(0);
|
|
40656
|
+
return;
|
|
40657
|
+
}
|
|
40658
|
+
if (key.ctrl || key.name === "up" || key.name === "down" || key.name === "pageup" || key.name === "pagedown" || key.name === "tab") {
|
|
40659
|
+
return;
|
|
40660
|
+
}
|
|
40661
|
+
const ch = key.sequence;
|
|
40662
|
+
if (ch && ch.length > 0 && !ch.startsWith("\x1B")) {
|
|
40663
|
+
if (ch === "'" || ch === '"' || ch === "`")
|
|
40664
|
+
return;
|
|
40665
|
+
const c = customCursor();
|
|
40666
|
+
const val = customName();
|
|
40667
|
+
setCustomName(val.slice(0, c) + ch + val.slice(c));
|
|
40668
|
+
setCustomCursor(c + ch.length);
|
|
40669
|
+
}
|
|
40670
|
+
return;
|
|
40671
|
+
}
|
|
40676
40672
|
if (key.name === "up" || key.name === "k") {
|
|
40677
40673
|
setFocused((f) => findNextEnabled(f, -1));
|
|
40678
40674
|
setError("");
|
|
@@ -40684,13 +40680,20 @@ function MultiSelect(props) {
|
|
|
40684
40680
|
return;
|
|
40685
40681
|
}
|
|
40686
40682
|
if (key.name === "space" || key.sequence === " ") {
|
|
40687
|
-
|
|
40683
|
+
const f = focused();
|
|
40684
|
+
if (isAddCustomRow(f)) {
|
|
40685
|
+
setAddingCustom(true);
|
|
40686
|
+
setCustomName("");
|
|
40687
|
+
setCustomCursor(0);
|
|
40688
|
+
return;
|
|
40689
|
+
}
|
|
40690
|
+
if (f >= 0 && !props.items[f].disabled) {
|
|
40688
40691
|
setSelected((prev) => {
|
|
40689
40692
|
const next = new Set(prev);
|
|
40690
|
-
if (next.has(
|
|
40691
|
-
next.delete(
|
|
40693
|
+
if (next.has(f)) {
|
|
40694
|
+
next.delete(f);
|
|
40692
40695
|
} else {
|
|
40693
|
-
next.add(
|
|
40696
|
+
next.add(f);
|
|
40694
40697
|
}
|
|
40695
40698
|
return next;
|
|
40696
40699
|
});
|
|
@@ -40699,6 +40702,13 @@ function MultiSelect(props) {
|
|
|
40699
40702
|
return;
|
|
40700
40703
|
}
|
|
40701
40704
|
if (key.name === "enter" || key.name === "return") {
|
|
40705
|
+
const f = focused();
|
|
40706
|
+
if (isAddCustomRow(f)) {
|
|
40707
|
+
setAddingCustom(true);
|
|
40708
|
+
setCustomName("");
|
|
40709
|
+
setCustomCursor(0);
|
|
40710
|
+
return;
|
|
40711
|
+
}
|
|
40702
40712
|
if (selected().size === 0) {
|
|
40703
40713
|
setError("Select at least one agent");
|
|
40704
40714
|
return;
|
|
@@ -40720,7 +40730,7 @@ function MultiSelect(props) {
|
|
|
40720
40730
|
},
|
|
40721
40731
|
children: (item, i) => {
|
|
40722
40732
|
const isSelected = () => selected().has(i());
|
|
40723
|
-
const isFocused = () => i() === focused();
|
|
40733
|
+
const isFocused = () => i() === focused() && !addingCustom();
|
|
40724
40734
|
const isDisabled = () => !!item.disabled;
|
|
40725
40735
|
const bullet = () => isSelected() ? "\u25CF" : "\u25CB";
|
|
40726
40736
|
const bulletColor = () => isDisabled() ? COLORS.textFaint : isSelected() ? COLORS.success : COLORS.textSecondary;
|
|
@@ -40728,29 +40738,29 @@ function MultiSelect(props) {
|
|
|
40728
40738
|
const descColor = () => isDisabled() ? COLORS.textFaint : COLORS.textMuted;
|
|
40729
40739
|
const bgColor = () => isFocused() && !isDisabled() ? COLORS.bgFocus : undefined;
|
|
40730
40740
|
return (() => {
|
|
40731
|
-
var _el$
|
|
40732
|
-
insertNode(_el$
|
|
40733
|
-
insertNode(_el$
|
|
40734
|
-
insertNode(_el$
|
|
40735
|
-
setProp(_el$
|
|
40736
|
-
insertNode(_el$
|
|
40737
|
-
insertNode(_el$
|
|
40738
|
-
insert(_el$
|
|
40739
|
-
insert(_el$
|
|
40740
|
-
insertNode(_el$
|
|
40741
|
-
insert(_el$
|
|
40741
|
+
var _el$0 = createElement("text"), _el$1 = createElement("span"), _el$10 = createTextNode(` `), _el$11 = createTextNode(` `), _el$12 = createElement("span"), _el$13 = createElement("span"), _el$14 = createTextNode(` `);
|
|
40742
|
+
insertNode(_el$0, _el$1);
|
|
40743
|
+
insertNode(_el$0, _el$12);
|
|
40744
|
+
insertNode(_el$0, _el$13);
|
|
40745
|
+
setProp(_el$0, "selectable", false);
|
|
40746
|
+
insertNode(_el$1, _el$10);
|
|
40747
|
+
insertNode(_el$1, _el$11);
|
|
40748
|
+
insert(_el$1, bullet, _el$11);
|
|
40749
|
+
insert(_el$12, () => item.label);
|
|
40750
|
+
insertNode(_el$13, _el$14);
|
|
40751
|
+
insert(_el$13, () => item.description, null);
|
|
40742
40752
|
effect((_p$) => {
|
|
40743
|
-
var _v$ = bgColor(), _v$
|
|
40753
|
+
var _v$4 = bgColor(), _v$5 = {
|
|
40744
40754
|
fg: bulletColor()
|
|
40745
|
-
}, _v$
|
|
40755
|
+
}, _v$6 = {
|
|
40746
40756
|
fg: labelColor()
|
|
40747
|
-
}, _v$
|
|
40757
|
+
}, _v$7 = {
|
|
40748
40758
|
fg: descColor()
|
|
40749
40759
|
};
|
|
40750
|
-
_v$ !== _p$.e && (_p$.e = setProp(_el$
|
|
40751
|
-
_v$
|
|
40752
|
-
_v$
|
|
40753
|
-
_v$
|
|
40760
|
+
_v$4 !== _p$.e && (_p$.e = setProp(_el$0, "bg", _v$4, _p$.e));
|
|
40761
|
+
_v$5 !== _p$.t && (_p$.t = setProp(_el$1, "style", _v$5, _p$.t));
|
|
40762
|
+
_v$6 !== _p$.a && (_p$.a = setProp(_el$12, "style", _v$6, _p$.a));
|
|
40763
|
+
_v$7 !== _p$.o && (_p$.o = setProp(_el$13, "style", _v$7, _p$.o));
|
|
40754
40764
|
return _p$;
|
|
40755
40765
|
}, {
|
|
40756
40766
|
e: undefined,
|
|
@@ -40758,21 +40768,96 @@ function MultiSelect(props) {
|
|
|
40758
40768
|
a: undefined,
|
|
40759
40769
|
o: undefined
|
|
40760
40770
|
});
|
|
40761
|
-
return _el$
|
|
40771
|
+
return _el$0;
|
|
40762
40772
|
})();
|
|
40763
40773
|
}
|
|
40764
40774
|
}), null);
|
|
40775
|
+
insert(_el$, createComponent2(Show, {
|
|
40776
|
+
get when() {
|
|
40777
|
+
return props.addCustom;
|
|
40778
|
+
},
|
|
40779
|
+
get children() {
|
|
40780
|
+
return createComponent2(Show, {
|
|
40781
|
+
get when() {
|
|
40782
|
+
return addingCustom();
|
|
40783
|
+
},
|
|
40784
|
+
get fallback() {
|
|
40785
|
+
return (() => {
|
|
40786
|
+
var _el$15 = createElement("text"), _el$16 = createElement("span"), _el$18 = createElement("span");
|
|
40787
|
+
insertNode(_el$15, _el$16);
|
|
40788
|
+
insertNode(_el$15, _el$18);
|
|
40789
|
+
setProp(_el$15, "selectable", false);
|
|
40790
|
+
insertNode(_el$16, createTextNode(` + `));
|
|
40791
|
+
insertNode(_el$18, createTextNode(`Add Custom...`));
|
|
40792
|
+
effect((_p$) => {
|
|
40793
|
+
var _v$8 = focused() === props.items.length && !addingCustom() ? COLORS.bgFocus : undefined, _v$9 = {
|
|
40794
|
+
fg: COLORS.primary
|
|
40795
|
+
}, _v$0 = {
|
|
40796
|
+
fg: COLORS.textSecondary
|
|
40797
|
+
};
|
|
40798
|
+
_v$8 !== _p$.e && (_p$.e = setProp(_el$15, "bg", _v$8, _p$.e));
|
|
40799
|
+
_v$9 !== _p$.t && (_p$.t = setProp(_el$16, "style", _v$9, _p$.t));
|
|
40800
|
+
_v$0 !== _p$.a && (_p$.a = setProp(_el$18, "style", _v$0, _p$.a));
|
|
40801
|
+
return _p$;
|
|
40802
|
+
}, {
|
|
40803
|
+
e: undefined,
|
|
40804
|
+
t: undefined,
|
|
40805
|
+
a: undefined
|
|
40806
|
+
});
|
|
40807
|
+
return _el$15;
|
|
40808
|
+
})();
|
|
40809
|
+
},
|
|
40810
|
+
get children() {
|
|
40811
|
+
var _el$2 = createElement("text"), _el$3 = createElement("span"), _el$5 = createElement("span"), _el$7 = createElement("span");
|
|
40812
|
+
insertNode(_el$2, _el$3);
|
|
40813
|
+
insertNode(_el$2, _el$5);
|
|
40814
|
+
insertNode(_el$2, _el$7);
|
|
40815
|
+
setProp(_el$2, "selectable", false);
|
|
40816
|
+
insertNode(_el$3, createTextNode(` + `));
|
|
40817
|
+
insertNode(_el$5, createTextNode(`Name: `));
|
|
40818
|
+
insert(_el$2, () => customName().slice(0, customCursor()), _el$7);
|
|
40819
|
+
insert(_el$7, (() => {
|
|
40820
|
+
var _c$ = memo2(() => customCursor() < customName().length);
|
|
40821
|
+
return () => _c$() ? customName()[customCursor()] : " ";
|
|
40822
|
+
})());
|
|
40823
|
+
insert(_el$2, (() => {
|
|
40824
|
+
var _c$2 = memo2(() => customCursor() < customName().length);
|
|
40825
|
+
return () => _c$2() ? customName().slice(customCursor() + 1) : "";
|
|
40826
|
+
})(), null);
|
|
40827
|
+
effect((_p$) => {
|
|
40828
|
+
var _v$ = {
|
|
40829
|
+
fg: COLORS.primary
|
|
40830
|
+
}, _v$2 = {
|
|
40831
|
+
fg: COLORS.textSecondary
|
|
40832
|
+
}, _v$3 = {
|
|
40833
|
+
bg: COLORS.textPrimary,
|
|
40834
|
+
fg: "#000000"
|
|
40835
|
+
};
|
|
40836
|
+
_v$ !== _p$.e && (_p$.e = setProp(_el$3, "style", _v$, _p$.e));
|
|
40837
|
+
_v$2 !== _p$.t && (_p$.t = setProp(_el$5, "style", _v$2, _p$.t));
|
|
40838
|
+
_v$3 !== _p$.a && (_p$.a = setProp(_el$7, "style", _v$3, _p$.a));
|
|
40839
|
+
return _p$;
|
|
40840
|
+
}, {
|
|
40841
|
+
e: undefined,
|
|
40842
|
+
t: undefined,
|
|
40843
|
+
a: undefined
|
|
40844
|
+
});
|
|
40845
|
+
return _el$2;
|
|
40846
|
+
}
|
|
40847
|
+
});
|
|
40848
|
+
}
|
|
40849
|
+
}), null);
|
|
40765
40850
|
insert(_el$, createComponent2(Show, {
|
|
40766
40851
|
get when() {
|
|
40767
40852
|
return error();
|
|
40768
40853
|
},
|
|
40769
40854
|
get children() {
|
|
40770
|
-
var _el$
|
|
40771
|
-
insertNode(_el$
|
|
40772
|
-
setProp(_el$
|
|
40773
|
-
insert(_el$
|
|
40774
|
-
effect((_$p) => setProp(_el$
|
|
40775
|
-
return _el$
|
|
40855
|
+
var _el$8 = createElement("text"), _el$9 = createTextNode(` `);
|
|
40856
|
+
insertNode(_el$8, _el$9);
|
|
40857
|
+
setProp(_el$8, "marginTop", 1);
|
|
40858
|
+
insert(_el$8, error, null);
|
|
40859
|
+
effect((_$p) => setProp(_el$8, "fg", COLORS.error, _$p));
|
|
40860
|
+
return _el$8;
|
|
40776
40861
|
}
|
|
40777
40862
|
}), null);
|
|
40778
40863
|
return _el$;
|
|
@@ -40793,7 +40878,6 @@ var SWEEP_CHARS = ["\u2591", "\u2592", "\u2593", "\u2588", "\u2593", "\u2592", "
|
|
|
40793
40878
|
var BAR_WIDTH = 6;
|
|
40794
40879
|
function SweepBar(props) {
|
|
40795
40880
|
const glow = SWEEP_CHARS.length;
|
|
40796
|
-
const totalWidth = BAR_WIDTH * 2 + props.title.length + 2;
|
|
40797
40881
|
const [pos, setPos] = createSignal(0);
|
|
40798
40882
|
createEffect(() => {
|
|
40799
40883
|
const interval = setInterval(() => setPos((p) => (p + 1) % (BAR_WIDTH + glow)), 50);
|
|
@@ -40869,22 +40953,105 @@ function useDiscoColor() {
|
|
|
40869
40953
|
});
|
|
40870
40954
|
return () => PARTY_COLORS[idx()];
|
|
40871
40955
|
}
|
|
40956
|
+
function personaToEntry(agent) {
|
|
40957
|
+
const env2 = agent.env ?? {};
|
|
40958
|
+
return {
|
|
40959
|
+
name: agent.name,
|
|
40960
|
+
tag: agent.tag,
|
|
40961
|
+
model: agent.model,
|
|
40962
|
+
provider: agent.provider,
|
|
40963
|
+
active: agent.active !== false,
|
|
40964
|
+
authUrl: env2.AUTH_URL ?? "",
|
|
40965
|
+
authToken: env2.AUTH_TOKEN ?? "",
|
|
40966
|
+
cli: agent.cli ?? "claude",
|
|
40967
|
+
prompts: agent.prompts,
|
|
40968
|
+
preloadSkills: agent.preloadSkills,
|
|
40969
|
+
executablePath: agent.executablePath,
|
|
40970
|
+
timeout: agent.timeout,
|
|
40971
|
+
extraEnv: extractExtraEnv(env2)
|
|
40972
|
+
};
|
|
40973
|
+
}
|
|
40974
|
+
function extractExtraEnv(env2) {
|
|
40975
|
+
const extra = {};
|
|
40976
|
+
for (const [k2, v2] of Object.entries(env2)) {
|
|
40977
|
+
if (k2 !== "AUTH_URL" && k2 !== "AUTH_TOKEN") {
|
|
40978
|
+
extra[k2] = v2;
|
|
40979
|
+
}
|
|
40980
|
+
}
|
|
40981
|
+
return Object.keys(extra).length > 0 ? extra : undefined;
|
|
40982
|
+
}
|
|
40983
|
+
function entryToPersona(entry) {
|
|
40984
|
+
const config = {
|
|
40985
|
+
name: entry.name.trim(),
|
|
40986
|
+
tag: entry.tag.trim(),
|
|
40987
|
+
provider: entry.provider,
|
|
40988
|
+
model: entry.model.trim(),
|
|
40989
|
+
active: entry.active
|
|
40990
|
+
};
|
|
40991
|
+
if (entry.provider === "custom") {
|
|
40992
|
+
config.cli = entry.cli || "claude";
|
|
40993
|
+
const env2 = {};
|
|
40994
|
+
if (entry.authUrl)
|
|
40995
|
+
env2.AUTH_URL = entry.authUrl;
|
|
40996
|
+
if (entry.authToken)
|
|
40997
|
+
env2.AUTH_TOKEN = entry.authToken;
|
|
40998
|
+
if (entry.extraEnv)
|
|
40999
|
+
Object.assign(env2, entry.extraEnv);
|
|
41000
|
+
if (Object.keys(env2).length > 0)
|
|
41001
|
+
config.env = env2;
|
|
41002
|
+
}
|
|
41003
|
+
if (entry.prompts)
|
|
41004
|
+
config.prompts = entry.prompts;
|
|
41005
|
+
if (entry.preloadSkills)
|
|
41006
|
+
config.preloadSkills = entry.preloadSkills;
|
|
41007
|
+
if (entry.executablePath)
|
|
41008
|
+
config.executablePath = entry.executablePath;
|
|
41009
|
+
if (entry.timeout)
|
|
41010
|
+
config.timeout = entry.timeout;
|
|
41011
|
+
return config;
|
|
41012
|
+
}
|
|
40872
41013
|
function ConfigWizard(props) {
|
|
40873
41014
|
const [step, setStep] = createSignal("detect");
|
|
40874
41015
|
const [detection, setDetection] = createSignal([]);
|
|
40875
|
-
const [selectedIds, setSelectedIds] = createSignal([]);
|
|
40876
|
-
const [, setAgentConfigs] = createSignal([]);
|
|
40877
41016
|
const [activeTab, setActiveTab] = createSignal(0);
|
|
40878
41017
|
const [focusedField, setFocusedField] = createSignal(0);
|
|
40879
41018
|
const [error, setError] = createSignal("");
|
|
40880
41019
|
const [tick, setTick] = createSignal(0);
|
|
40881
|
-
|
|
40882
|
-
let
|
|
40883
|
-
|
|
40884
|
-
|
|
41020
|
+
const [customItems, setCustomItems] = createSignal([]);
|
|
41021
|
+
let agentEntries = [];
|
|
41022
|
+
let settingsData = {
|
|
41023
|
+
name: props.existingConfig?.humanName || userInfo2().username || "USER",
|
|
41024
|
+
tag: props.existingConfig?.humanTag || toTag(props.existingConfig?.humanName || userInfo2().username || "USER"),
|
|
41025
|
+
maxHops: String(props.existingConfig?.maxAutoHops ?? 15),
|
|
41026
|
+
timeout: String(props.existingConfig?.timeout ?? 600)
|
|
40885
41027
|
};
|
|
40886
41028
|
let cursorPos = 0;
|
|
40887
41029
|
const spinner = useSpinner();
|
|
41030
|
+
const tuiRenderer = useRenderer();
|
|
41031
|
+
createEffect(() => {
|
|
41032
|
+
const handlePaste = (event) => {
|
|
41033
|
+
if (step() !== "configure")
|
|
41034
|
+
return;
|
|
41035
|
+
const text = new TextDecoder().decode(event.bytes);
|
|
41036
|
+
if (!text)
|
|
41037
|
+
return;
|
|
41038
|
+
const cleaned = text.replace(/\n/g, "");
|
|
41039
|
+
if (!cleaned)
|
|
41040
|
+
return;
|
|
41041
|
+
const fieldValue = getCurrentFieldValue();
|
|
41042
|
+
const cursor = cursorPos;
|
|
41043
|
+
updateField(fieldValue.slice(0, cursor) + cleaned + fieldValue.slice(cursor), cursor + cleaned.length);
|
|
41044
|
+
};
|
|
41045
|
+
tuiRenderer.keyInput.on("paste", handlePaste);
|
|
41046
|
+
onCleanup(() => {
|
|
41047
|
+
tuiRenderer.keyInput.off("paste", handlePaste);
|
|
41048
|
+
});
|
|
41049
|
+
});
|
|
41050
|
+
createEffect(() => {
|
|
41051
|
+
const existing = props.existingConfig?.agents ?? [];
|
|
41052
|
+
const customs = existing.filter((a) => a.provider === "custom").map(personaToEntry);
|
|
41053
|
+
setCustomItems(customs);
|
|
41054
|
+
});
|
|
40888
41055
|
createEffect(() => {
|
|
40889
41056
|
detectProviders().then((results) => {
|
|
40890
41057
|
setDetection(results);
|
|
@@ -40894,103 +41061,255 @@ function ConfigWizard(props) {
|
|
|
40894
41061
|
setStep("providers");
|
|
40895
41062
|
});
|
|
40896
41063
|
});
|
|
40897
|
-
const
|
|
40898
|
-
|
|
40899
|
-
|
|
40900
|
-
|
|
40901
|
-
|
|
40902
|
-
|
|
40903
|
-
|
|
40904
|
-
|
|
40905
|
-
|
|
40906
|
-
|
|
40907
|
-
|
|
40908
|
-
|
|
40909
|
-
const ids = selectedIndices.map((i) => PROVIDERS[i].id);
|
|
40910
|
-
setSelectedIds(ids);
|
|
40911
|
-
const configs = ids.map((id) => {
|
|
40912
|
-
const def = PROVIDERS.find((p) => p.id === id);
|
|
40913
|
-
const existing = existingByProvider().get(id);
|
|
41064
|
+
const existingNative = () => {
|
|
41065
|
+
const map = new Map;
|
|
41066
|
+
for (const a of props.existingConfig?.agents ?? []) {
|
|
41067
|
+
if (a.provider !== "custom")
|
|
41068
|
+
map.set(a.provider, a);
|
|
41069
|
+
}
|
|
41070
|
+
return map;
|
|
41071
|
+
};
|
|
41072
|
+
const multiSelectItems = () => {
|
|
41073
|
+
const nativeItems = PROVIDERS.map((provider) => {
|
|
41074
|
+
const result = detection().find((d2) => d2.id === provider.id);
|
|
41075
|
+
const available = result?.available ?? false;
|
|
40914
41076
|
return {
|
|
40915
|
-
|
|
40916
|
-
|
|
40917
|
-
|
|
40918
|
-
model: existing?.model || def.defaultModel
|
|
41077
|
+
label: provider.displayName,
|
|
41078
|
+
description: available ? provider.description : provider.unavailableHint,
|
|
41079
|
+
disabled: !available
|
|
40919
41080
|
};
|
|
40920
41081
|
});
|
|
40921
|
-
|
|
40922
|
-
|
|
40923
|
-
|
|
41082
|
+
const customs = customItems();
|
|
41083
|
+
if (customs.length > 0) {
|
|
41084
|
+
nativeItems.push({
|
|
41085
|
+
label: "\u2500\u2500 Custom \u2500\u2500",
|
|
41086
|
+
description: "",
|
|
41087
|
+
disabled: true
|
|
41088
|
+
});
|
|
41089
|
+
}
|
|
41090
|
+
const customEntries = customs.map((c) => ({
|
|
41091
|
+
label: c.name,
|
|
41092
|
+
description: "custom provider"
|
|
40924
41093
|
}));
|
|
41094
|
+
return [...nativeItems, ...customEntries];
|
|
41095
|
+
};
|
|
41096
|
+
const initialSelected = () => {
|
|
41097
|
+
if (!props.existingConfig)
|
|
41098
|
+
return;
|
|
41099
|
+
const indices = [];
|
|
41100
|
+
const nativeMap = existingNative();
|
|
41101
|
+
PROVIDERS.forEach((p, i) => {
|
|
41102
|
+
const existing = nativeMap.get(p.id);
|
|
41103
|
+
if (existing && existing.active !== false)
|
|
41104
|
+
indices.push(i);
|
|
41105
|
+
});
|
|
41106
|
+
const customs = customItems();
|
|
41107
|
+
if (customs.length > 0) {
|
|
41108
|
+
const offset = PROVIDERS.length + 1;
|
|
41109
|
+
customs.forEach((c, i) => {
|
|
41110
|
+
if (c.active)
|
|
41111
|
+
indices.push(offset + i);
|
|
41112
|
+
});
|
|
41113
|
+
}
|
|
41114
|
+
return indices.length > 0 ? indices : undefined;
|
|
41115
|
+
};
|
|
41116
|
+
const handleAddCustom = (name) => {
|
|
41117
|
+
const entry = {
|
|
41118
|
+
name,
|
|
41119
|
+
tag: toTag(name),
|
|
41120
|
+
model: "",
|
|
41121
|
+
provider: "custom",
|
|
41122
|
+
active: true,
|
|
41123
|
+
authUrl: "",
|
|
41124
|
+
authToken: "",
|
|
41125
|
+
cli: "claude"
|
|
41126
|
+
};
|
|
41127
|
+
setCustomItems((prev) => [...prev, entry]);
|
|
41128
|
+
};
|
|
41129
|
+
const handleProviderConfirm = (selectedIndices) => {
|
|
41130
|
+
const nativeMap = existingNative();
|
|
41131
|
+
const customs = customItems();
|
|
41132
|
+
const hasCustoms = customs.length > 0;
|
|
41133
|
+
const customOffset = PROVIDERS.length + (hasCustoms ? 1 : 0);
|
|
41134
|
+
const entries = [];
|
|
41135
|
+
for (let i = 0;i < PROVIDERS.length; i++) {
|
|
41136
|
+
const def = PROVIDERS[i];
|
|
41137
|
+
const isSelected = selectedIndices.includes(i);
|
|
41138
|
+
const existing = nativeMap.get(def.id);
|
|
41139
|
+
if (isSelected || existing) {
|
|
41140
|
+
entries.push({
|
|
41141
|
+
name: existing?.name || def.displayName,
|
|
41142
|
+
tag: existing?.tag || def.defaultTag,
|
|
41143
|
+
model: existing?.model || def.defaultModel,
|
|
41144
|
+
provider: def.id,
|
|
41145
|
+
active: isSelected,
|
|
41146
|
+
authUrl: "",
|
|
41147
|
+
authToken: "",
|
|
41148
|
+
cli: "claude",
|
|
41149
|
+
prompts: existing?.prompts,
|
|
41150
|
+
preloadSkills: existing?.preloadSkills,
|
|
41151
|
+
executablePath: existing?.executablePath,
|
|
41152
|
+
timeout: existing?.timeout
|
|
41153
|
+
});
|
|
41154
|
+
}
|
|
41155
|
+
}
|
|
41156
|
+
for (let i = 0;i < customs.length; i++) {
|
|
41157
|
+
const isSelected = selectedIndices.includes(customOffset + i);
|
|
41158
|
+
entries.push({
|
|
41159
|
+
...customs[i],
|
|
41160
|
+
active: isSelected
|
|
41161
|
+
});
|
|
41162
|
+
}
|
|
41163
|
+
agentEntries = entries;
|
|
40925
41164
|
setActiveTab(0);
|
|
40926
41165
|
setFocusedField(0);
|
|
40927
|
-
cursorPos =
|
|
41166
|
+
cursorPos = settingsData.name.length;
|
|
40928
41167
|
setStep("configure");
|
|
40929
41168
|
};
|
|
40930
41169
|
const handleProviderCancel = () => {
|
|
40931
41170
|
if (props.onCancel)
|
|
40932
41171
|
props.onCancel();
|
|
40933
41172
|
};
|
|
40934
|
-
const
|
|
41173
|
+
const activeEntries = () => agentEntries.filter((e) => e.active);
|
|
41174
|
+
const isSettingsTab = () => activeTab() === 0;
|
|
40935
41175
|
const agentTabIndex = () => activeTab() - 1;
|
|
40936
|
-
const totalTabs = () => (
|
|
40937
|
-
const
|
|
41176
|
+
const totalTabs = () => activeEntries().length + 1;
|
|
41177
|
+
const isCustomAgent = () => {
|
|
41178
|
+
if (isSettingsTab())
|
|
41179
|
+
return false;
|
|
41180
|
+
const entry = activeEntries()[agentTabIndex()];
|
|
41181
|
+
return entry?.provider === "custom";
|
|
41182
|
+
};
|
|
41183
|
+
const maxFieldIndex = () => {
|
|
41184
|
+
if (isSettingsTab())
|
|
41185
|
+
return 3;
|
|
41186
|
+
return isCustomAgent() ? 4 : 2;
|
|
41187
|
+
};
|
|
41188
|
+
const getFieldValueForEntry = (entry, field) => {
|
|
41189
|
+
if (entry.provider === "custom") {
|
|
41190
|
+
return [entry.name, entry.tag, entry.model, entry.authUrl, entry.authToken][field];
|
|
41191
|
+
}
|
|
41192
|
+
return [entry.name, entry.tag, entry.model][field];
|
|
41193
|
+
};
|
|
41194
|
+
const getSettingsFieldValue = (field) => {
|
|
41195
|
+
return [settingsData.name, settingsData.tag, settingsData.maxHops, settingsData.timeout][field];
|
|
41196
|
+
};
|
|
41197
|
+
const getCurrentFieldValue = () => {
|
|
41198
|
+
if (isSettingsTab())
|
|
41199
|
+
return getSettingsFieldValue(focusedField());
|
|
41200
|
+
const entry = activeEntries()[agentTabIndex()];
|
|
41201
|
+
if (!entry)
|
|
41202
|
+
return "";
|
|
41203
|
+
return getFieldValueForEntry(entry, focusedField());
|
|
41204
|
+
};
|
|
41205
|
+
const updateField = (value, newCursor) => {
|
|
41206
|
+
if (isSettingsTab()) {
|
|
41207
|
+
if (focusedField() === 0)
|
|
41208
|
+
settingsData.name = value;
|
|
41209
|
+
else if (focusedField() === 1)
|
|
41210
|
+
settingsData.tag = value;
|
|
41211
|
+
else if (focusedField() === 2)
|
|
41212
|
+
settingsData.maxHops = value;
|
|
41213
|
+
else
|
|
41214
|
+
settingsData.timeout = value;
|
|
41215
|
+
} else {
|
|
41216
|
+
const entry = activeEntries()[agentTabIndex()];
|
|
41217
|
+
if (!entry)
|
|
41218
|
+
return;
|
|
41219
|
+
if (entry.provider === "custom") {
|
|
41220
|
+
if (focusedField() === 0)
|
|
41221
|
+
entry.name = value;
|
|
41222
|
+
else if (focusedField() === 1)
|
|
41223
|
+
entry.tag = value;
|
|
41224
|
+
else if (focusedField() === 2)
|
|
41225
|
+
entry.model = value;
|
|
41226
|
+
else if (focusedField() === 3)
|
|
41227
|
+
entry.authUrl = value;
|
|
41228
|
+
else
|
|
41229
|
+
entry.authToken = value;
|
|
41230
|
+
} else {
|
|
41231
|
+
if (focusedField() === 0)
|
|
41232
|
+
entry.name = value;
|
|
41233
|
+
else if (focusedField() === 1)
|
|
41234
|
+
entry.tag = value;
|
|
41235
|
+
else
|
|
41236
|
+
entry.model = value;
|
|
41237
|
+
}
|
|
41238
|
+
}
|
|
41239
|
+
cursorPos = newCursor;
|
|
41240
|
+
setError("");
|
|
41241
|
+
setTick((n) => n + 1);
|
|
41242
|
+
};
|
|
41243
|
+
const isTagField = () => focusedField() === 1;
|
|
41244
|
+
const isNumberField = () => isSettingsTab() && (focusedField() === 2 || focusedField() === 3);
|
|
40938
41245
|
const saveConfig = async () => {
|
|
40939
|
-
|
|
40940
|
-
|
|
40941
|
-
|
|
40942
|
-
|
|
41246
|
+
if (!settingsData.name.trim()) {
|
|
41247
|
+
setError("Name cannot be empty");
|
|
41248
|
+
return;
|
|
41249
|
+
}
|
|
41250
|
+
if (!settingsData.tag.trim()) {
|
|
41251
|
+
setError("Tag cannot be empty");
|
|
40943
41252
|
return;
|
|
40944
41253
|
}
|
|
40945
|
-
if (!
|
|
40946
|
-
setError("
|
|
41254
|
+
if (!TAG_PATTERN.test(settingsData.tag.trim())) {
|
|
41255
|
+
setError("Tag can only contain letters, numbers, hyphens, underscores");
|
|
40947
41256
|
return;
|
|
40948
41257
|
}
|
|
40949
|
-
|
|
40950
|
-
|
|
41258
|
+
const maxHops = parseInt(settingsData.maxHops, 10);
|
|
41259
|
+
if (isNaN(maxHops) || maxHops < 0) {
|
|
41260
|
+
setError("Max Hops must be 0 or a positive number");
|
|
40951
41261
|
return;
|
|
40952
41262
|
}
|
|
40953
|
-
|
|
40954
|
-
|
|
40955
|
-
|
|
41263
|
+
const timeout = parseInt(settingsData.timeout, 10);
|
|
41264
|
+
if (isNaN(timeout) || timeout < 0) {
|
|
41265
|
+
setError("Timeout must be 0 or a positive number");
|
|
41266
|
+
return;
|
|
41267
|
+
}
|
|
41268
|
+
const tags = new Set;
|
|
41269
|
+
tags.add(settingsData.tag.trim().toLowerCase());
|
|
41270
|
+
for (const entry of agentEntries) {
|
|
41271
|
+
if (!entry.name.trim()) {
|
|
41272
|
+
setError(`Name cannot be empty for an agent`);
|
|
40956
41273
|
return;
|
|
40957
41274
|
}
|
|
40958
|
-
if (!
|
|
40959
|
-
setError(`Tag cannot be empty for ${
|
|
41275
|
+
if (!entry.tag.trim()) {
|
|
41276
|
+
setError(`Tag cannot be empty for ${entry.name}`);
|
|
40960
41277
|
return;
|
|
40961
41278
|
}
|
|
40962
|
-
if (!TAG_PATTERN.test(
|
|
40963
|
-
setError(`Tag for ${
|
|
41279
|
+
if (!TAG_PATTERN.test(entry.tag.trim())) {
|
|
41280
|
+
setError(`Tag for ${entry.name} can only contain letters, numbers, hyphens, underscores`);
|
|
40964
41281
|
return;
|
|
40965
41282
|
}
|
|
40966
|
-
if (!
|
|
40967
|
-
setError(`Model cannot be empty for ${
|
|
41283
|
+
if (!entry.model.trim()) {
|
|
41284
|
+
setError(`Model cannot be empty for ${entry.name}`);
|
|
40968
41285
|
return;
|
|
40969
41286
|
}
|
|
40970
|
-
|
|
40971
|
-
|
|
40972
|
-
|
|
40973
|
-
|
|
40974
|
-
|
|
40975
|
-
|
|
41287
|
+
const tagLower = entry.tag.trim().toLowerCase();
|
|
41288
|
+
if (tags.has(tagLower)) {
|
|
41289
|
+
setError(`Duplicate tag: ${entry.tag}`);
|
|
41290
|
+
return;
|
|
41291
|
+
}
|
|
41292
|
+
tags.add(tagLower);
|
|
41293
|
+
if (entry.provider === "custom" && entry.active && !entry.authUrl.trim()) {
|
|
41294
|
+
setError(`URL is required for ${entry.name}`);
|
|
40976
41295
|
return;
|
|
40977
41296
|
}
|
|
40978
|
-
names.add(lower);
|
|
40979
41297
|
}
|
|
40980
|
-
const
|
|
40981
|
-
|
|
40982
|
-
|
|
40983
|
-
|
|
40984
|
-
|
|
40985
|
-
|
|
40986
|
-
|
|
40987
|
-
|
|
40988
|
-
humanName: human.name.trim(),
|
|
40989
|
-
humanTag: human.tag.trim(),
|
|
40990
|
-
agents: props.existingConfig?.agents || []
|
|
41298
|
+
const agents = agentEntries.map(entryToPersona);
|
|
41299
|
+
const config = {
|
|
41300
|
+
humanName: settingsData.name.trim(),
|
|
41301
|
+
humanTag: settingsData.tag.trim(),
|
|
41302
|
+
maxAutoHops: maxHops,
|
|
41303
|
+
timeout: timeout > 0 ? timeout : undefined,
|
|
41304
|
+
reminderInterval: props.existingConfig?.reminderInterval,
|
|
41305
|
+
agents
|
|
40991
41306
|
};
|
|
41307
|
+
if (config.timeout === undefined)
|
|
41308
|
+
delete config.timeout;
|
|
41309
|
+
if (config.reminderInterval === undefined)
|
|
41310
|
+
delete config.reminderInterval;
|
|
40992
41311
|
try {
|
|
40993
|
-
await
|
|
41312
|
+
await writeConfig(config);
|
|
40994
41313
|
setStep("done");
|
|
40995
41314
|
} catch (err) {
|
|
40996
41315
|
setError(`Failed to save: ${err.message}`);
|
|
@@ -41002,9 +41321,8 @@ function ConfigWizard(props) {
|
|
|
41002
41321
|
return;
|
|
41003
41322
|
}
|
|
41004
41323
|
if (step() !== "configure") {
|
|
41005
|
-
if (step() === "detect")
|
|
41324
|
+
if (step() === "detect")
|
|
41006
41325
|
return;
|
|
41007
|
-
}
|
|
41008
41326
|
if (step() === "done") {
|
|
41009
41327
|
if (key.name === "enter" || key.name === "return" || key.name === "space") {
|
|
41010
41328
|
props.onComplete();
|
|
@@ -41013,49 +41331,20 @@ function ConfigWizard(props) {
|
|
|
41013
41331
|
}
|
|
41014
41332
|
return;
|
|
41015
41333
|
}
|
|
41016
|
-
const
|
|
41017
|
-
const human = humanData;
|
|
41018
|
-
let fieldValue;
|
|
41019
|
-
if (isYouTab()) {
|
|
41020
|
-
fieldValue = focusedField() === 0 ? human.name : human.tag;
|
|
41021
|
-
} else {
|
|
41022
|
-
const current = configs[agentTabIndex()];
|
|
41023
|
-
if (!current)
|
|
41024
|
-
return;
|
|
41025
|
-
fieldValue = [current.name, current.tag, current.model][focusedField()];
|
|
41026
|
-
}
|
|
41334
|
+
const fieldValue = getCurrentFieldValue();
|
|
41027
41335
|
const cursor = cursorPos;
|
|
41028
|
-
const updateField = (value, newCursor) => {
|
|
41029
|
-
if (isYouTab()) {
|
|
41030
|
-
if (focusedField() === 0)
|
|
41031
|
-
human.name = value;
|
|
41032
|
-
else
|
|
41033
|
-
human.tag = value;
|
|
41034
|
-
} else {
|
|
41035
|
-
const current = configs[agentTabIndex()];
|
|
41036
|
-
if (focusedField() === 0)
|
|
41037
|
-
current.name = value;
|
|
41038
|
-
else if (focusedField() === 1)
|
|
41039
|
-
current.tag = value;
|
|
41040
|
-
else
|
|
41041
|
-
current.model = value;
|
|
41042
|
-
}
|
|
41043
|
-
cursorPos = newCursor;
|
|
41044
|
-
setError("");
|
|
41045
|
-
setTick((n) => n + 1);
|
|
41046
|
-
};
|
|
41047
41336
|
if (key.sequence === "[" || key.sequence === "]") {
|
|
41048
41337
|
const dir = key.sequence === "[" ? -1 : 1;
|
|
41049
41338
|
const next = (activeTab() + dir + totalTabs()) % totalTabs();
|
|
41050
41339
|
setActiveTab(next);
|
|
41051
|
-
const newMax = next === 0 ? 1 : 2;
|
|
41340
|
+
const newMax = next === 0 ? 3 : activeEntries()[next - 1]?.provider === "custom" ? 4 : 2;
|
|
41052
41341
|
const newField = Math.min(focusedField(), newMax);
|
|
41053
41342
|
setFocusedField(newField);
|
|
41054
41343
|
let newVal;
|
|
41055
41344
|
if (next === 0) {
|
|
41056
|
-
newVal = newField
|
|
41345
|
+
newVal = getSettingsFieldValue(newField);
|
|
41057
41346
|
} else {
|
|
41058
|
-
newVal =
|
|
41347
|
+
newVal = getFieldValueForEntry(activeEntries()[next - 1], newField);
|
|
41059
41348
|
}
|
|
41060
41349
|
cursorPos = newVal.length;
|
|
41061
41350
|
setTick((n) => n + 1);
|
|
@@ -41065,12 +41354,7 @@ function ConfigWizard(props) {
|
|
|
41065
41354
|
const fieldCount = maxFieldIndex() + 1;
|
|
41066
41355
|
const nextField = key.shift ? (focusedField() - 1 + fieldCount) % fieldCount : (focusedField() + 1) % fieldCount;
|
|
41067
41356
|
setFocusedField(nextField);
|
|
41068
|
-
|
|
41069
|
-
if (isYouTab()) {
|
|
41070
|
-
newVal = nextField === 0 ? human.name : human.tag;
|
|
41071
|
-
} else {
|
|
41072
|
-
newVal = getFieldValue(configs[agentTabIndex()], nextField);
|
|
41073
|
-
}
|
|
41357
|
+
const newVal = isSettingsTab() ? getSettingsFieldValue(nextField) : getFieldValueForEntry(activeEntries()[agentTabIndex()], nextField);
|
|
41074
41358
|
cursorPos = newVal.length;
|
|
41075
41359
|
setTick((n) => n + 1);
|
|
41076
41360
|
return;
|
|
@@ -41125,7 +41409,7 @@ function ConfigWizard(props) {
|
|
|
41125
41409
|
return;
|
|
41126
41410
|
}
|
|
41127
41411
|
if (key.name === "space" || key.sequence === " ") {
|
|
41128
|
-
if (
|
|
41412
|
+
if (!isTagField() && !isNumberField()) {
|
|
41129
41413
|
updateField(fieldValue.slice(0, cursor) + " " + fieldValue.slice(cursor), cursor + 1);
|
|
41130
41414
|
}
|
|
41131
41415
|
return;
|
|
@@ -41134,7 +41418,9 @@ function ConfigWizard(props) {
|
|
|
41134
41418
|
if (ch && ch.length > 0 && !ch.startsWith("\x1B")) {
|
|
41135
41419
|
if (ch === "'" || ch === '"' || ch === "`")
|
|
41136
41420
|
return;
|
|
41137
|
-
if (
|
|
41421
|
+
if (isTagField() && !TAG_PATTERN.test(ch))
|
|
41422
|
+
return;
|
|
41423
|
+
if (isNumberField() && !/^[0-9]$/.test(ch))
|
|
41138
41424
|
return;
|
|
41139
41425
|
updateField(fieldValue.slice(0, cursor) + ch + fieldValue.slice(cursor), cursor + ch.length);
|
|
41140
41426
|
}
|
|
@@ -41152,7 +41438,7 @@ function ConfigWizard(props) {
|
|
|
41152
41438
|
})();
|
|
41153
41439
|
}
|
|
41154
41440
|
const discoColor = useDiscoColor();
|
|
41155
|
-
function renderField(label, value, isFocused) {
|
|
41441
|
+
function renderField(label, value, isFocused, hint) {
|
|
41156
41442
|
tick();
|
|
41157
41443
|
const cursor = cursorPos;
|
|
41158
41444
|
const labelColor = isFocused ? COLORS.primary : COLORS.textDim;
|
|
@@ -41175,7 +41461,7 @@ function ConfigWizard(props) {
|
|
|
41175
41461
|
setProp(_el$12, "style", {
|
|
41176
41462
|
fg: valueColor
|
|
41177
41463
|
});
|
|
41178
|
-
insert(_el$12, value);
|
|
41464
|
+
insert(_el$12, value || (hint ? hint : ""));
|
|
41179
41465
|
effect((_$p) => setProp(_el$0, "style", {
|
|
41180
41466
|
fg: COLORS.borderStrong
|
|
41181
41467
|
}, _$p));
|
|
@@ -41210,6 +41496,13 @@ function ConfigWizard(props) {
|
|
|
41210
41496
|
return _el$13;
|
|
41211
41497
|
})();
|
|
41212
41498
|
}
|
|
41499
|
+
function renderTokenField(label, value, isFocused) {
|
|
41500
|
+
if (!isFocused && value.length > 0) {
|
|
41501
|
+
const masked = value.length > 4 ? "*".repeat(value.length - 4) + value.slice(-4) : "*".repeat(value.length);
|
|
41502
|
+
return renderField(label, masked, false);
|
|
41503
|
+
}
|
|
41504
|
+
return renderField(label, value, isFocused);
|
|
41505
|
+
}
|
|
41213
41506
|
const DetectStep = () => (() => {
|
|
41214
41507
|
var _el$19 = createElement("box"), _el$20 = createElement("box"), _el$21 = createElement("box"), _el$22 = createElement("text"), _el$23 = createTextNode(` Scanning for installed CLIs...`);
|
|
41215
41508
|
insertNode(_el$19, _el$20);
|
|
@@ -41325,6 +41618,9 @@ function ConfigWizard(props) {
|
|
|
41325
41618
|
},
|
|
41326
41619
|
get initialSelected() {
|
|
41327
41620
|
return initialSelected();
|
|
41621
|
+
},
|
|
41622
|
+
addCustom: {
|
|
41623
|
+
onAdd: handleAddCustom
|
|
41328
41624
|
}
|
|
41329
41625
|
}));
|
|
41330
41626
|
effect((_p$) => {
|
|
@@ -41362,12 +41658,8 @@ function ConfigWizard(props) {
|
|
|
41362
41658
|
})();
|
|
41363
41659
|
const ConfigureStep = () => {
|
|
41364
41660
|
tick();
|
|
41365
|
-
const
|
|
41366
|
-
const
|
|
41367
|
-
const tabLabels = ["You", ...selectedIds().map((id) => {
|
|
41368
|
-
const def = PROVIDERS.find((p) => p.id === id);
|
|
41369
|
-
return def?.displayName || id;
|
|
41370
|
-
})];
|
|
41661
|
+
const active = activeEntries();
|
|
41662
|
+
const tabLabels = ["Settings", ...active.map((e) => e.name)];
|
|
41371
41663
|
return (() => {
|
|
41372
41664
|
var _el$48 = createElement("box"), _el$49 = createElement("box"), _el$50 = createElement("box"), _el$51 = createElement("box"), _el$52 = createElement("box"), _el$53 = createElement("text"), _el$55 = createElement("box"), _el$56 = createElement("box"), _el$60 = createElement("box"), _el$61 = createElement("text"), _el$62 = createElement("span"), _el$64 = createElement("span"), _el$66 = createElement("span"), _el$68 = createElement("span"), _el$70 = createElement("span"), _el$72 = createElement("span"), _el$74 = createElement("span"), _el$76 = createElement("span"), _el$78 = createElement("span"), _el$80 = createElement("span"), _el$82 = createElement("span"), _el$84 = createElement("span"), _el$86 = createElement("span");
|
|
41373
41665
|
insertNode(_el$48, _el$49);
|
|
@@ -41439,7 +41731,7 @@ function ConfigWizard(props) {
|
|
|
41439
41731
|
setProp(_el$56, "flexDirection", "column");
|
|
41440
41732
|
insert(_el$56, createComponent2(Show, {
|
|
41441
41733
|
get when() {
|
|
41442
|
-
return
|
|
41734
|
+
return isSettingsTab();
|
|
41443
41735
|
},
|
|
41444
41736
|
get fallback() {
|
|
41445
41737
|
return [(() => {
|
|
@@ -41448,19 +41740,39 @@ function ConfigWizard(props) {
|
|
|
41448
41740
|
setProp(_el$94, "marginBottom", 1);
|
|
41449
41741
|
insertNode(_el$95, _el$96);
|
|
41450
41742
|
insert(_el$95, () => tabLabels[activeTab()], _el$96);
|
|
41743
|
+
insert(_el$94, createComponent2(Show, {
|
|
41744
|
+
get when() {
|
|
41745
|
+
return activeEntries()[agentTabIndex()]?.provider === "custom";
|
|
41746
|
+
},
|
|
41747
|
+
get children() {
|
|
41748
|
+
var _el$97 = createElement("span");
|
|
41749
|
+
insertNode(_el$97, createTextNode(` (custom)`));
|
|
41750
|
+
effect((_$p) => setProp(_el$97, "style", {
|
|
41751
|
+
fg: COLORS.textFaint
|
|
41752
|
+
}, _$p));
|
|
41753
|
+
return _el$97;
|
|
41754
|
+
}
|
|
41755
|
+
}), null);
|
|
41451
41756
|
effect((_$p) => setProp(_el$94, "fg", COLORS.success, _$p));
|
|
41452
41757
|
return _el$94;
|
|
41453
|
-
})(), memo2(() => renderField("Name ",
|
|
41758
|
+
})(), memo2(() => renderField("Name ", active[agentTabIndex()].name, focusedField() === 0)), memo2(() => renderField("Tag ", active[agentTabIndex()].tag, focusedField() === 1)), memo2(() => renderField("Model", active[agentTabIndex()].model, focusedField() === 2)), createComponent2(Show, {
|
|
41759
|
+
get when() {
|
|
41760
|
+
return active[agentTabIndex()]?.provider === "custom";
|
|
41761
|
+
},
|
|
41762
|
+
get children() {
|
|
41763
|
+
return [memo2(() => renderField("URL ", active[agentTabIndex()].authUrl, focusedField() === 3)), memo2(() => renderTokenField("Token", active[agentTabIndex()].authToken, focusedField() === 4))];
|
|
41764
|
+
}
|
|
41765
|
+
})];
|
|
41454
41766
|
},
|
|
41455
41767
|
get children() {
|
|
41456
41768
|
return [(() => {
|
|
41457
41769
|
var _el$57 = createElement("text"), _el$58 = createElement("strong");
|
|
41458
41770
|
insertNode(_el$57, _el$58);
|
|
41459
41771
|
setProp(_el$57, "marginBottom", 1);
|
|
41460
|
-
insertNode(_el$58, createTextNode(`
|
|
41772
|
+
insertNode(_el$58, createTextNode(`General Settings`));
|
|
41461
41773
|
effect((_$p) => setProp(_el$57, "fg", COLORS.agent, _$p));
|
|
41462
41774
|
return _el$57;
|
|
41463
|
-
})(), memo2(() => renderField("Name",
|
|
41775
|
+
})(), memo2(() => renderField("Name ", settingsData.name, focusedField() === 0)), memo2(() => renderField("Tag ", settingsData.tag, focusedField() === 1)), memo2(() => renderField("Max Hops", settingsData.maxHops, focusedField() === 2, "0 = unlimited")), memo2(() => renderField("Timeout ", settingsData.timeout, focusedField() === 3, "0 = unlimited"))];
|
|
41464
41776
|
}
|
|
41465
41777
|
}));
|
|
41466
41778
|
insertNode(_el$60, _el$61);
|
|
@@ -41520,7 +41832,7 @@ function ConfigWizard(props) {
|
|
|
41520
41832
|
}
|
|
41521
41833
|
}), null);
|
|
41522
41834
|
effect((_p$) => {
|
|
41523
|
-
var _v$13 = discoColor(), _v$14 = COLORS.bgPanel, _v$15 = COLORS.borderStrong, _v$16 =
|
|
41835
|
+
var _v$13 = discoColor(), _v$14 = COLORS.bgPanel, _v$15 = COLORS.borderStrong, _v$16 = isSettingsTab() ? COLORS.agent : COLORS.success, _v$17 = COLORS.bgContent, _v$18 = {
|
|
41524
41836
|
fg: COLORS.textFaint
|
|
41525
41837
|
}, _v$19 = {
|
|
41526
41838
|
fg: COLORS.success
|
|
@@ -41590,57 +41902,57 @@ function ConfigWizard(props) {
|
|
|
41590
41902
|
})();
|
|
41591
41903
|
};
|
|
41592
41904
|
const DoneStep = () => (() => {
|
|
41593
|
-
var _el$
|
|
41594
|
-
insertNode(_el$97, _el$98);
|
|
41595
|
-
setProp(_el$97, "flexDirection", "column");
|
|
41596
|
-
setProp(_el$97, "width", "100%");
|
|
41597
|
-
setProp(_el$97, "height", "100%");
|
|
41598
|
-
setProp(_el$97, "justifyContent", "center");
|
|
41599
|
-
setProp(_el$97, "alignItems", "center");
|
|
41600
|
-
insertNode(_el$98, _el$99);
|
|
41601
|
-
setProp(_el$98, "border", true);
|
|
41602
|
-
setProp(_el$98, "borderStyle", "double");
|
|
41603
|
-
setProp(_el$98, "paddingX", 4);
|
|
41604
|
-
setProp(_el$98, "paddingY", 2);
|
|
41905
|
+
var _el$99 = createElement("box"), _el$100 = createElement("box"), _el$101 = createElement("box"), _el$102 = createElement("text"), _el$104 = createElement("text"), _el$106 = createElement("text"), _el$108 = createElement("text"), _el$110 = createElement("text"), _el$112 = createElement("text"), _el$113 = createTextNode(`Press `), _el$114 = createElement("span"), _el$115 = createElement("strong"), _el$117 = createTextNode(` to continue`);
|
|
41605
41906
|
insertNode(_el$99, _el$100);
|
|
41606
|
-
insertNode(_el$99, _el$102);
|
|
41607
|
-
insertNode(_el$99, _el$104);
|
|
41608
|
-
insertNode(_el$99, _el$106);
|
|
41609
|
-
insertNode(_el$99, _el$108);
|
|
41610
|
-
insertNode(_el$99, _el$110);
|
|
41611
41907
|
setProp(_el$99, "flexDirection", "column");
|
|
41908
|
+
setProp(_el$99, "width", "100%");
|
|
41909
|
+
setProp(_el$99, "height", "100%");
|
|
41910
|
+
setProp(_el$99, "justifyContent", "center");
|
|
41612
41911
|
setProp(_el$99, "alignItems", "center");
|
|
41613
|
-
|
|
41912
|
+
insertNode(_el$100, _el$101);
|
|
41913
|
+
setProp(_el$100, "border", true);
|
|
41914
|
+
setProp(_el$100, "borderStyle", "double");
|
|
41915
|
+
setProp(_el$100, "paddingX", 4);
|
|
41916
|
+
setProp(_el$100, "paddingY", 2);
|
|
41917
|
+
insertNode(_el$101, _el$102);
|
|
41918
|
+
insertNode(_el$101, _el$104);
|
|
41919
|
+
insertNode(_el$101, _el$106);
|
|
41920
|
+
insertNode(_el$101, _el$108);
|
|
41921
|
+
insertNode(_el$101, _el$110);
|
|
41922
|
+
insertNode(_el$101, _el$112);
|
|
41923
|
+
setProp(_el$101, "flexDirection", "column");
|
|
41924
|
+
setProp(_el$101, "alignItems", "center");
|
|
41925
|
+
insert(_el$101, createComponent2(SweepBar, {
|
|
41614
41926
|
title: "Config Saved"
|
|
41615
|
-
}), _el$
|
|
41616
|
-
insertNode(_el$
|
|
41617
|
-
setProp(_el$100, "marginTop", 1);
|
|
41618
|
-
insertNode(_el$102, createTextNode(`Written to ~/.llm-party/config.json`));
|
|
41927
|
+
}), _el$102);
|
|
41928
|
+
insertNode(_el$102, createTextNode(`\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500`));
|
|
41619
41929
|
setProp(_el$102, "marginTop", 1);
|
|
41620
|
-
insertNode(_el$104, createTextNode(`
|
|
41930
|
+
insertNode(_el$104, createTextNode(`Written to ~/.llm-party/config.json`));
|
|
41621
41931
|
setProp(_el$104, "marginTop", 1);
|
|
41622
|
-
insertNode(_el$106, createTextNode(`
|
|
41623
|
-
|
|
41624
|
-
|
|
41625
|
-
insertNode(_el$110,
|
|
41626
|
-
insertNode(_el$110, _el$112);
|
|
41627
|
-
insertNode(_el$110, _el$115);
|
|
41932
|
+
insertNode(_el$106, createTextNode(`Edit this file anytime to add prompts,`));
|
|
41933
|
+
setProp(_el$106, "marginTop", 1);
|
|
41934
|
+
insertNode(_el$108, createTextNode(`env vars, or tweak settings.`));
|
|
41935
|
+
insertNode(_el$110, createTextNode(`\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500`));
|
|
41628
41936
|
setProp(_el$110, "marginTop", 1);
|
|
41629
41937
|
insertNode(_el$112, _el$113);
|
|
41630
|
-
insertNode(_el$
|
|
41938
|
+
insertNode(_el$112, _el$114);
|
|
41939
|
+
insertNode(_el$112, _el$117);
|
|
41940
|
+
setProp(_el$112, "marginTop", 1);
|
|
41941
|
+
insertNode(_el$114, _el$115);
|
|
41942
|
+
insertNode(_el$115, createTextNode(`Enter`));
|
|
41631
41943
|
effect((_p$) => {
|
|
41632
41944
|
var _v$33 = discoColor(), _v$34 = COLORS.bgPanel, _v$35 = COLORS.textSubtle, _v$36 = COLORS.textMuted, _v$37 = COLORS.textSubtle, _v$38 = COLORS.textSubtle, _v$39 = COLORS.textSubtle, _v$40 = COLORS.primary, _v$41 = {
|
|
41633
41945
|
fg: COLORS.success
|
|
41634
41946
|
};
|
|
41635
|
-
_v$33 !== _p$.e && (_p$.e = setProp(_el$
|
|
41636
|
-
_v$34 !== _p$.t && (_p$.t = setProp(_el$
|
|
41637
|
-
_v$35 !== _p$.a && (_p$.a = setProp(_el$
|
|
41638
|
-
_v$36 !== _p$.o && (_p$.o = setProp(_el$
|
|
41639
|
-
_v$37 !== _p$.i && (_p$.i = setProp(_el$
|
|
41640
|
-
_v$38 !== _p$.n && (_p$.n = setProp(_el$
|
|
41641
|
-
_v$39 !== _p$.s && (_p$.s = setProp(_el$
|
|
41642
|
-
_v$40 !== _p$.h && (_p$.h = setProp(_el$
|
|
41643
|
-
_v$41 !== _p$.r && (_p$.r = setProp(_el$
|
|
41947
|
+
_v$33 !== _p$.e && (_p$.e = setProp(_el$100, "borderColor", _v$33, _p$.e));
|
|
41948
|
+
_v$34 !== _p$.t && (_p$.t = setProp(_el$100, "backgroundColor", _v$34, _p$.t));
|
|
41949
|
+
_v$35 !== _p$.a && (_p$.a = setProp(_el$102, "fg", _v$35, _p$.a));
|
|
41950
|
+
_v$36 !== _p$.o && (_p$.o = setProp(_el$104, "fg", _v$36, _p$.o));
|
|
41951
|
+
_v$37 !== _p$.i && (_p$.i = setProp(_el$106, "fg", _v$37, _p$.i));
|
|
41952
|
+
_v$38 !== _p$.n && (_p$.n = setProp(_el$108, "fg", _v$38, _p$.n));
|
|
41953
|
+
_v$39 !== _p$.s && (_p$.s = setProp(_el$110, "fg", _v$39, _p$.s));
|
|
41954
|
+
_v$40 !== _p$.h && (_p$.h = setProp(_el$112, "fg", _v$40, _p$.h));
|
|
41955
|
+
_v$41 !== _p$.r && (_p$.r = setProp(_el$114, "style", _v$41, _p$.r));
|
|
41644
41956
|
return _p$;
|
|
41645
41957
|
}, {
|
|
41646
41958
|
e: undefined,
|
|
@@ -41653,7 +41965,7 @@ function ConfigWizard(props) {
|
|
|
41653
41965
|
h: undefined,
|
|
41654
41966
|
r: undefined
|
|
41655
41967
|
});
|
|
41656
|
-
return _el$
|
|
41968
|
+
return _el$99;
|
|
41657
41969
|
})();
|
|
41658
41970
|
return [createComponent2(Show, {
|
|
41659
41971
|
get when() {
|
|
@@ -41685,13 +41997,6 @@ function ConfigWizard(props) {
|
|
|
41685
41997
|
}
|
|
41686
41998
|
})];
|
|
41687
41999
|
}
|
|
41688
|
-
function getFieldValue(config, field) {
|
|
41689
|
-
if (field === 0)
|
|
41690
|
-
return config.name;
|
|
41691
|
-
if (field === 1)
|
|
41692
|
-
return config.tag;
|
|
41693
|
-
return config.model;
|
|
41694
|
-
}
|
|
41695
42000
|
|
|
41696
42001
|
// src/ui/AgentsPanel.tsx
|
|
41697
42002
|
function AgentsPanel(props) {
|
|
@@ -41996,7 +42301,7 @@ function InfoPanel(props) {
|
|
|
41996
42301
|
|
|
41997
42302
|
// src/ui/App.tsx
|
|
41998
42303
|
function copyToClipboard(text) {
|
|
41999
|
-
const proc =
|
|
42304
|
+
const proc = spawn4("pbcopy", [], {
|
|
42000
42305
|
stdio: ["pipe", "ignore", "ignore"]
|
|
42001
42306
|
});
|
|
42002
42307
|
proc.stdin?.write(text);
|
|
@@ -42028,6 +42333,7 @@ function App(props) {
|
|
|
42028
42333
|
const agents = props.orchestrator.listAgents();
|
|
42029
42334
|
let scrollRef = null;
|
|
42030
42335
|
const [screen, setScreen] = createSignal("chat");
|
|
42336
|
+
const [freshConfig, setFreshConfig] = createSignal(props.config);
|
|
42031
42337
|
const [showAgents, setShowAgents] = createSignal(false);
|
|
42032
42338
|
const [showInfo, setShowInfo] = createSignal(false);
|
|
42033
42339
|
process.on("SIGINT", () => renderer.destroy());
|
|
@@ -42101,6 +42407,10 @@ Transcript: ${props.orchestrator.getTranscriptPath()}`);
|
|
|
42101
42407
|
return;
|
|
42102
42408
|
}
|
|
42103
42409
|
if (line === "/config") {
|
|
42410
|
+
try {
|
|
42411
|
+
const reloaded = await loadConfig2(props.configPath);
|
|
42412
|
+
setFreshConfig(reloaded);
|
|
42413
|
+
} catch {}
|
|
42104
42414
|
setScreen("config");
|
|
42105
42415
|
return;
|
|
42106
42416
|
}
|
|
@@ -42141,7 +42451,7 @@ ${lines.join(`
|
|
|
42141
42451
|
return createComponent2(ConfigWizard, {
|
|
42142
42452
|
isFirstRun: false,
|
|
42143
42453
|
get existingConfig() {
|
|
42144
|
-
return
|
|
42454
|
+
return freshConfig();
|
|
42145
42455
|
},
|
|
42146
42456
|
onComplete: () => {
|
|
42147
42457
|
addSystemMessage("Config saved. Restart llm-party to apply changes.");
|
|
@@ -42258,7 +42568,8 @@ async function bootApp(appRoot, rendererConfig) {
|
|
|
42258
42568
|
` + obsidianPrompt;
|
|
42259
42569
|
const availableSkills = await discoverSkills();
|
|
42260
42570
|
const agentVerifiedSkills = new Map;
|
|
42261
|
-
|
|
42571
|
+
const activeAgents = config.agents.filter((a) => a.active !== false);
|
|
42572
|
+
for (const agent of activeAgents) {
|
|
42262
42573
|
if (agent.preloadSkills && agent.preloadSkills.length > 0) {
|
|
42263
42574
|
const verified = [];
|
|
42264
42575
|
const report = [];
|
|
@@ -42279,7 +42590,7 @@ async function bootApp(appRoot, rendererConfig) {
|
|
|
42279
42590
|
const resolveFromConfig = (value) => {
|
|
42280
42591
|
return path11.isAbsolute(value) ? value : path11.resolve(configDir, value);
|
|
42281
42592
|
};
|
|
42282
|
-
const adapters = await Promise.all(
|
|
42593
|
+
const adapters = await Promise.all(activeAgents.map(async (agent, _index, allAgents) => {
|
|
42283
42594
|
const promptParts = [mergedBase];
|
|
42284
42595
|
if (agent.prompts && agent.prompts.length > 0) {
|
|
42285
42596
|
const extraPaths = agent.prompts.map((p) => resolveFromConfig(p));
|
|
@@ -42318,7 +42629,7 @@ ${mySkills.map((s) => `- ${s}`).join(`
|
|
|
42318
42629
|
agentCount: String(allAgents.length),
|
|
42319
42630
|
preloadedSkills
|
|
42320
42631
|
});
|
|
42321
|
-
const adapter = agent.provider === "claude" ? new ClaudeAdapter(agent.name, agent.model) : agent.provider === "codex" ? new CodexAdapter(agent.name, agent.model) : agent.provider === "copilot" ? new CopilotAdapter(agent.name, agent.model) : agent.provider === "
|
|
42632
|
+
const adapter = agent.provider === "claude" ? new ClaudeAdapter(agent.name, agent.model, humanName) : agent.provider === "codex" ? new CodexAdapter(agent.name, agent.model, humanName) : agent.provider === "copilot" ? new CopilotAdapter(agent.name, agent.model, humanName) : agent.provider === "custom" ? new CustomAdapter(agent.name, agent.model, humanName) : null;
|
|
42322
42633
|
if (!adapter) {
|
|
42323
42634
|
throw new Error(`Unsupported provider: ${agent.provider}`);
|
|
42324
42635
|
}
|
|
@@ -42326,12 +42637,12 @@ ${mySkills.map((s) => `- ${s}`).join(`
|
|
|
42326
42637
|
return adapter;
|
|
42327
42638
|
}));
|
|
42328
42639
|
const defaultTimeout = typeof config.timeout === "number" && config.timeout > 0 ? config.timeout * 1000 : 600000;
|
|
42329
|
-
const agentTimeouts = Object.fromEntries(
|
|
42330
|
-
const orchestrator = new Orchestrator(adapters, humanName, Object.fromEntries(
|
|
42331
|
-
await render(() => App({ orchestrator, maxAutoHops, config }), rendererConfig);
|
|
42640
|
+
const agentTimeouts = Object.fromEntries(activeAgents.filter((agent) => typeof agent.timeout === "number" && agent.timeout > 0).map((agent) => [agent.name, agent.timeout * 1000]));
|
|
42641
|
+
const orchestrator = new Orchestrator(adapters, humanName, Object.fromEntries(activeAgents.map((agent) => [agent.name, agent.tag?.trim() || toTag(agent.name)])), humanTag, defaultTimeout, agentTimeouts, { reminderInterval: config.reminderInterval });
|
|
42642
|
+
await render(() => App({ orchestrator, maxAutoHops, config, configPath }), rendererConfig);
|
|
42332
42643
|
}
|
|
42333
42644
|
function resolveMaxAutoHops(value) {
|
|
42334
|
-
if (value === "
|
|
42645
|
+
if (typeof value === "number" && value === 0) {
|
|
42335
42646
|
return Number.POSITIVE_INFINITY;
|
|
42336
42647
|
}
|
|
42337
42648
|
if (typeof value === "number" && Number.isFinite(value) && value >= 1) {
|