tagteam 0.2.0 → 0.3.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 +43 -1
- package/dist/index.js +138 -31
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -53,6 +53,32 @@ You can also set the default pair in your config:
|
|
|
53
53
|
agents = ["claude", "gemini"]
|
|
54
54
|
```
|
|
55
55
|
|
|
56
|
+
### Addressing agents inline
|
|
57
|
+
|
|
58
|
+
Prefix your prompt with an agent name to send it to just that agent:
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
gemini what do you think about this approach?
|
|
62
|
+
claude summarize the discussion so far
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Name two agents to override the active pair for that prompt (separators: `and`, `/`, `&`, `,`):
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
gemini and codex review this function
|
|
69
|
+
gemini/claude compare your approaches
|
|
70
|
+
gemini & codex review this function
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Add `discuss` to start a multi-round discussion — either word order works:
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
discuss codex and gemini what's the best caching strategy
|
|
77
|
+
codex and gemini discuss what's the best caching strategy
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
This works for any agent, not just your active pair. Addressed agents receive the full conversation history for context.
|
|
81
|
+
|
|
56
82
|
### Discussion mode
|
|
57
83
|
|
|
58
84
|
Have your agents discuss a topic in rounds until they reach consensus:
|
|
@@ -70,6 +96,12 @@ tagteam continue
|
|
|
70
96
|
# List recent sessions
|
|
71
97
|
tagteam history
|
|
72
98
|
|
|
99
|
+
# Delete a specific session
|
|
100
|
+
tagteam history rm <id>
|
|
101
|
+
|
|
102
|
+
# Delete all sessions
|
|
103
|
+
tagteam history clear
|
|
104
|
+
|
|
73
105
|
# Resume a specific session by ID
|
|
74
106
|
tagteam resume <id>
|
|
75
107
|
|
|
@@ -82,7 +114,7 @@ tagteam show <id> --markdown
|
|
|
82
114
|
|
|
83
115
|
### Configuration
|
|
84
116
|
|
|
85
|
-
Configuration is stored in `~/.tagteam/config.toml` (or `%APPDATA%\tagteam\config.toml` on Windows).
|
|
117
|
+
Configuration is stored in `~/.tagteam/config.toml` (or `%APPDATA%\tagteam\config.toml` on Windows). Session data is stored in `~/.tagteam/tagteam.db`.
|
|
86
118
|
|
|
87
119
|
```bash
|
|
88
120
|
# Interactive config editor
|
|
@@ -99,6 +131,16 @@ tagteam config set gemini.model gemini-2.5-pro
|
|
|
99
131
|
tagteam config set discussion.max_rounds 10
|
|
100
132
|
```
|
|
101
133
|
|
|
134
|
+
Default values:
|
|
135
|
+
|
|
136
|
+
| Key | Default |
|
|
137
|
+
|-----|---------|
|
|
138
|
+
| `agents` | `claude, codex` |
|
|
139
|
+
| `claude.model` | `sonnet` |
|
|
140
|
+
| `codex.model` | `gpt-5.3-codex` |
|
|
141
|
+
| `gemini.model` | `gemini-2.5-pro` |
|
|
142
|
+
| `discussion.max_rounds` | `10` |
|
|
143
|
+
|
|
102
144
|
### CLI options
|
|
103
145
|
|
|
104
146
|
```bash
|
package/dist/index.js
CHANGED
|
@@ -655,6 +655,16 @@ function touchSession(id) {
|
|
|
655
655
|
id
|
|
656
656
|
);
|
|
657
657
|
}
|
|
658
|
+
function deleteSession(id) {
|
|
659
|
+
const db2 = getDb();
|
|
660
|
+
db2.prepare(`DELETE FROM messages WHERE session_id = ?`).run(id);
|
|
661
|
+
db2.prepare(`DELETE FROM sessions WHERE id = ?`).run(id);
|
|
662
|
+
}
|
|
663
|
+
function deleteAllSessions() {
|
|
664
|
+
const db2 = getDb();
|
|
665
|
+
db2.prepare(`DELETE FROM messages`).run();
|
|
666
|
+
db2.prepare(`DELETE FROM sessions`).run();
|
|
667
|
+
}
|
|
658
668
|
|
|
659
669
|
// src/db/messages.ts
|
|
660
670
|
function insertMessage(params) {
|
|
@@ -722,6 +732,13 @@ ${conversationHistory}
|
|
|
722
732
|
|
|
723
733
|
Respond to the latest round. If you agree with ${other}'s position on all key points, end with [CONSENSUS]. Otherwise, continue the discussion.`;
|
|
724
734
|
}
|
|
735
|
+
function directPrompt(conversationHistory) {
|
|
736
|
+
return `You are being addressed directly in a multi-agent session. Here is the conversation so far:
|
|
737
|
+
|
|
738
|
+
${conversationHistory}
|
|
739
|
+
|
|
740
|
+
Respond to the user's latest message. Be concise.`;
|
|
741
|
+
}
|
|
725
742
|
var CONSENSUS_MARKER = "[CONSENSUS]";
|
|
726
743
|
function formatConversationHistory(messages) {
|
|
727
744
|
return messages.map((m) => {
|
|
@@ -887,12 +904,35 @@ function startConfigEditor() {
|
|
|
887
904
|
// src/ui.tsx
|
|
888
905
|
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
889
906
|
marked.use(markedTerminal());
|
|
890
|
-
|
|
907
|
+
var PAIR_SEPARATORS = /^(\w+)\s*(?:and|&|\/|,)\s*(\w+)[\s,]\s*/i;
|
|
908
|
+
function tryParsePair(text) {
|
|
909
|
+
const match = text.toLowerCase().match(PAIR_SEPARATORS);
|
|
910
|
+
if (!match) return null;
|
|
911
|
+
const [fullMatch, first, second] = match;
|
|
912
|
+
if (isValidAgentName(first) && isValidAgentName(second) && first !== second) {
|
|
913
|
+
return { pair: [first, second], rest: text.slice(fullMatch.length).trim() };
|
|
914
|
+
}
|
|
915
|
+
return null;
|
|
916
|
+
}
|
|
917
|
+
function parseInput(input) {
|
|
891
918
|
const lower = input.toLowerCase();
|
|
892
919
|
if (lower.startsWith("discuss ")) {
|
|
893
|
-
|
|
920
|
+
const rest = input.slice(8).trim();
|
|
921
|
+
const adHoc2 = tryParsePair(rest);
|
|
922
|
+
if (adHoc2) {
|
|
923
|
+
return { target: adHoc2.pair, prompt: adHoc2.rest, discuss: true };
|
|
924
|
+
}
|
|
925
|
+
return { target: "both", prompt: rest, discuss: true };
|
|
894
926
|
}
|
|
895
|
-
|
|
927
|
+
const adHoc = tryParsePair(input);
|
|
928
|
+
if (adHoc) {
|
|
929
|
+
const adHocLower = adHoc.rest.toLowerCase();
|
|
930
|
+
if (adHocLower.startsWith("discuss ")) {
|
|
931
|
+
return { target: adHoc.pair, prompt: adHoc.rest.slice(8).trim(), discuss: true };
|
|
932
|
+
}
|
|
933
|
+
return { target: adHoc.pair, prompt: adHoc.rest, discuss: false };
|
|
934
|
+
}
|
|
935
|
+
for (const agent of getAllAgentNames()) {
|
|
896
936
|
if (lower.startsWith(`${agent} `) || lower.startsWith(`${agent}, `)) {
|
|
897
937
|
return { target: agent, prompt: input.slice(input.indexOf(" ") + 1).trim(), discuss: false };
|
|
898
938
|
}
|
|
@@ -935,6 +975,23 @@ function Header({ sessionId }) {
|
|
|
935
975
|
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: " " + "\u2500".repeat(35) })
|
|
936
976
|
] });
|
|
937
977
|
}
|
|
978
|
+
function QuickHelp() {
|
|
979
|
+
const col = 38;
|
|
980
|
+
const examples = [
|
|
981
|
+
["ask anything", "sends to both agents"],
|
|
982
|
+
["gemini explain this", "sends to one agent"],
|
|
983
|
+
["discuss best approach", "multi-round debate"],
|
|
984
|
+
["gemini and codex discuss review app", "pick agents + debate"]
|
|
985
|
+
];
|
|
986
|
+
return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", marginLeft: 2, marginBottom: 1, children: [
|
|
987
|
+
examples.map(([cmd, desc]) => /* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
|
|
988
|
+
cmd.padEnd(col),
|
|
989
|
+
"\u2192 ",
|
|
990
|
+
desc
|
|
991
|
+
] }, cmd)),
|
|
992
|
+
/* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "/help for more" })
|
|
993
|
+
] });
|
|
994
|
+
}
|
|
938
995
|
function UserMessage({ content }) {
|
|
939
996
|
return /* @__PURE__ */ jsxs2(Box2, { marginLeft: 1, marginBottom: 1, children: [
|
|
940
997
|
/* @__PURE__ */ jsxs2(Text2, { bold: true, color: "white", children: [
|
|
@@ -1020,11 +1077,13 @@ function App({
|
|
|
1020
1077
|
}
|
|
1021
1078
|
return 0;
|
|
1022
1079
|
});
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1080
|
+
const sessionCreatedRef = useRef(!!existingSessionId);
|
|
1081
|
+
const ensureSession = (id) => {
|
|
1082
|
+
if (!sessionCreatedRef.current) {
|
|
1083
|
+
createSession(id, process.cwd());
|
|
1084
|
+
sessionCreatedRef.current = true;
|
|
1026
1085
|
}
|
|
1027
|
-
}
|
|
1086
|
+
};
|
|
1028
1087
|
useEffect(() => {
|
|
1029
1088
|
if (initialPrompt && state === "running") {
|
|
1030
1089
|
if (initialDiscuss) {
|
|
@@ -1058,7 +1117,7 @@ function App({
|
|
|
1058
1117
|
}
|
|
1059
1118
|
});
|
|
1060
1119
|
const runAgents = async (currentMessages, round, target, promptOverride, isDebate = false) => {
|
|
1061
|
-
const activeAgents = target === "both" ? [...pair] : [target];
|
|
1120
|
+
const activeAgents = Array.isArray(target) ? target : target === "both" ? [...pair] : [target];
|
|
1062
1121
|
setThinkingAgents(activeAgents);
|
|
1063
1122
|
const history = formatConversationHistory(
|
|
1064
1123
|
currentMessages.map((m) => ({
|
|
@@ -1069,20 +1128,25 @@ function App({
|
|
|
1069
1128
|
);
|
|
1070
1129
|
const cwd = process.cwd();
|
|
1071
1130
|
const isFirstRound = round === 0 && !existingSessionId;
|
|
1131
|
+
const userPrompt = currentMessages[currentMessages.length - 1]?.content || "";
|
|
1132
|
+
const isSingleAgent = !Array.isArray(target) && target !== "both";
|
|
1133
|
+
const promptPair = Array.isArray(target) ? target : pair;
|
|
1072
1134
|
const agentPrompt = (_agent) => {
|
|
1073
1135
|
if (promptOverride) return promptOverride;
|
|
1074
|
-
if (
|
|
1075
|
-
|
|
1076
|
-
}
|
|
1136
|
+
if (isSingleAgent) return userPrompt;
|
|
1137
|
+
if (isFirstRound) return userPrompt;
|
|
1077
1138
|
return "Provide your response for this round.";
|
|
1078
1139
|
};
|
|
1079
1140
|
const agentSystemPrompt = (agent) => {
|
|
1141
|
+
if (isSingleAgent) {
|
|
1142
|
+
return history ? directPrompt(history) : void 0;
|
|
1143
|
+
}
|
|
1080
1144
|
if (isDebate) {
|
|
1081
|
-
if (isFirstRound) return debatePrompt(agent,
|
|
1082
|
-
return debateRoundPrompt(agent, history,
|
|
1145
|
+
if (isFirstRound) return debatePrompt(agent, promptPair);
|
|
1146
|
+
return debateRoundPrompt(agent, history, promptPair);
|
|
1083
1147
|
}
|
|
1084
|
-
if (isFirstRound
|
|
1085
|
-
return discussionPrompt(agent, history,
|
|
1148
|
+
if (isFirstRound) return collaborationPrompt(agent, promptPair);
|
|
1149
|
+
return discussionPrompt(agent, history, promptPair);
|
|
1086
1150
|
};
|
|
1087
1151
|
const ac = new AbortController();
|
|
1088
1152
|
abortRef.current = ac;
|
|
@@ -1149,12 +1213,17 @@ function App({
|
|
|
1149
1213
|
return newMessages;
|
|
1150
1214
|
};
|
|
1151
1215
|
const runRound = async (rawInput) => {
|
|
1152
|
-
const { target, prompt, discuss } = parseInput(rawInput
|
|
1216
|
+
const { target, prompt, discuss } = parseInput(rawInput);
|
|
1153
1217
|
if (discuss) {
|
|
1154
|
-
return runDiscussion(prompt);
|
|
1218
|
+
return runDiscussion(prompt, Array.isArray(target) ? target : void 0);
|
|
1155
1219
|
}
|
|
1156
1220
|
const currentRound = roundNum;
|
|
1157
1221
|
runningRoundRef.current = currentRound;
|
|
1222
|
+
ensureSession(sessionId);
|
|
1223
|
+
if (currentRound === 0) {
|
|
1224
|
+
const title = prompt.length > 60 ? prompt.slice(0, 57) + "..." : prompt;
|
|
1225
|
+
updateSessionTitle(sessionId, title);
|
|
1226
|
+
}
|
|
1158
1227
|
const userMsg = {
|
|
1159
1228
|
role: "user",
|
|
1160
1229
|
content: rawInput,
|
|
@@ -1173,17 +1242,19 @@ function App({
|
|
|
1173
1242
|
setMessages((prev) => [...prev, ...newMessages]);
|
|
1174
1243
|
setRoundNum(currentRound + 1);
|
|
1175
1244
|
runningRoundRef.current = null;
|
|
1176
|
-
if (currentRound === 0 && !existingSessionId) {
|
|
1177
|
-
const title = prompt.length > 60 ? prompt.slice(0, 57) + "..." : prompt;
|
|
1178
|
-
updateSessionTitle(sessionId, title);
|
|
1179
|
-
}
|
|
1180
1245
|
touchSession(sessionId);
|
|
1181
1246
|
setState("input");
|
|
1182
1247
|
};
|
|
1183
|
-
const runDiscussion = async (prompt) => {
|
|
1248
|
+
const runDiscussion = async (prompt, adHocPair) => {
|
|
1249
|
+
const discussionTarget = adHocPair ?? "both";
|
|
1184
1250
|
setConsensusReached(false);
|
|
1185
1251
|
let currentRound = roundNum;
|
|
1186
1252
|
runningRoundRef.current = currentRound;
|
|
1253
|
+
ensureSession(sessionId);
|
|
1254
|
+
if (currentRound === 0) {
|
|
1255
|
+
const title = prompt.length > 60 ? prompt.slice(0, 57) + "..." : prompt;
|
|
1256
|
+
updateSessionTitle(sessionId, title);
|
|
1257
|
+
}
|
|
1187
1258
|
const userMsg = {
|
|
1188
1259
|
role: "user",
|
|
1189
1260
|
content: `discuss ${prompt}`,
|
|
@@ -1197,16 +1268,12 @@ function App({
|
|
|
1197
1268
|
round: currentRound
|
|
1198
1269
|
});
|
|
1199
1270
|
let allMessages = [...messages, userMsg];
|
|
1200
|
-
if (currentRound === 0 && !existingSessionId) {
|
|
1201
|
-
const title = prompt.length > 60 ? prompt.slice(0, 57) + "..." : prompt;
|
|
1202
|
-
updateSessionTitle(sessionId, title);
|
|
1203
|
-
}
|
|
1204
1271
|
for (let disc = 1; disc <= config.discussion.max_rounds; disc++) {
|
|
1205
1272
|
setDiscussionRound(disc);
|
|
1206
1273
|
const newMessages = await runAgents(
|
|
1207
1274
|
allMessages,
|
|
1208
1275
|
currentRound,
|
|
1209
|
-
|
|
1276
|
+
discussionTarget,
|
|
1210
1277
|
disc === 1 ? prompt : "Provide your response for this round.",
|
|
1211
1278
|
true
|
|
1212
1279
|
);
|
|
@@ -1214,7 +1281,8 @@ function App({
|
|
|
1214
1281
|
setMessages((prev) => [...prev, ...newMessages]);
|
|
1215
1282
|
allMessages = [...allMessages, ...newMessages];
|
|
1216
1283
|
currentRound++;
|
|
1217
|
-
const
|
|
1284
|
+
const activePair = adHocPair ?? pair;
|
|
1285
|
+
const consensusFlags = activePair.map((agent) => {
|
|
1218
1286
|
const msg = newMessages.find((m) => m.role === agent && !m.error);
|
|
1219
1287
|
return msg?.content.includes(CONSENSUS_MARKER) ?? false;
|
|
1220
1288
|
});
|
|
@@ -1256,7 +1324,7 @@ function App({
|
|
|
1256
1324
|
}
|
|
1257
1325
|
if (value === "/new") {
|
|
1258
1326
|
const newId = nanoid(12);
|
|
1259
|
-
|
|
1327
|
+
sessionCreatedRef.current = false;
|
|
1260
1328
|
setSessionId(newId);
|
|
1261
1329
|
setMessages([]);
|
|
1262
1330
|
setRoundNum(0);
|
|
@@ -1281,6 +1349,7 @@ function App({
|
|
|
1281
1349
|
};
|
|
1282
1350
|
return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", children: [
|
|
1283
1351
|
/* @__PURE__ */ jsx2(Header, { sessionId }),
|
|
1352
|
+
messages.length === 0 && state === "input" && /* @__PURE__ */ jsx2(QuickHelp, {}),
|
|
1284
1353
|
messages.map((msg, i) => {
|
|
1285
1354
|
if (msg.role === "user") {
|
|
1286
1355
|
return /* @__PURE__ */ jsx2(UserMessage, { content: msg.content }, i);
|
|
@@ -1424,7 +1493,7 @@ function resolveAgentModels(pair, opts, config) {
|
|
|
1424
1493
|
};
|
|
1425
1494
|
}
|
|
1426
1495
|
var program = new Command();
|
|
1427
|
-
program.name("tagteam").description("Tag Team - Orchestrate AI agents collaboratively").version("0.
|
|
1496
|
+
program.name("tagteam").description("Tag Team - Orchestrate AI agents collaboratively").version("0.3.0").option("--agents <pair>", "Agent pair to use (comma-separated, e.g. claude,gemini)").option("--claude-model <model>", "Claude model to use").option("--codex-model <model>", "Codex model to use").option("--gemini-model <model>", "Gemini model to use").argument("[prompt...]", "Prompt to send to both agents").action(async (promptParts, opts) => {
|
|
1428
1497
|
const config = loadConfig();
|
|
1429
1498
|
const pair = resolveAgentPair(opts, config);
|
|
1430
1499
|
preflight(pair);
|
|
@@ -1550,13 +1619,51 @@ program.command("resume [id]").description("Resume a session by ID, or pick inte
|
|
|
1550
1619
|
});
|
|
1551
1620
|
await instance.waitUntilExit();
|
|
1552
1621
|
});
|
|
1553
|
-
program.command("history").description("List
|
|
1622
|
+
var historyCmd = program.command("history").description("List, remove, or clear sessions").option("-n, --limit <n>", "Number of sessions to show", parseInt, 20).action((opts) => {
|
|
1554
1623
|
const sessions = listSessions(opts.limit);
|
|
1555
1624
|
console.log(chalk.bold("\n Recent sessions:\n"));
|
|
1556
1625
|
showSessionList(sessions);
|
|
1557
1626
|
console.log();
|
|
1558
1627
|
closeDb();
|
|
1559
1628
|
});
|
|
1629
|
+
historyCmd.command("rm <id>").description("Delete a session by ID or prefix").action((id) => {
|
|
1630
|
+
const session = getSession(id) || getSessionByPrefix(id);
|
|
1631
|
+
if (!session) {
|
|
1632
|
+
console.log(chalk.red(` Session not found: ${id}`));
|
|
1633
|
+
process.exit(1);
|
|
1634
|
+
}
|
|
1635
|
+
deleteSession(session.id);
|
|
1636
|
+
const sid = session.id.slice(0, 7);
|
|
1637
|
+
const title = session.title || "(untitled)";
|
|
1638
|
+
console.log(chalk.green(` Deleted session ${sid} \u2014 ${title}`));
|
|
1639
|
+
closeDb();
|
|
1640
|
+
});
|
|
1641
|
+
historyCmd.command("clear").description("Delete all sessions").action(async () => {
|
|
1642
|
+
const sessions = listSessions();
|
|
1643
|
+
if (sessions.length === 0) {
|
|
1644
|
+
console.log(chalk.yellow(" No sessions to delete."));
|
|
1645
|
+
closeDb();
|
|
1646
|
+
return;
|
|
1647
|
+
}
|
|
1648
|
+
const readline = await import("readline");
|
|
1649
|
+
const rl = readline.createInterface({
|
|
1650
|
+
input: process.stdin,
|
|
1651
|
+
output: process.stdout
|
|
1652
|
+
});
|
|
1653
|
+
rl.question(
|
|
1654
|
+
chalk.yellow(` Delete all ${sessions.length} session(s)? [y/N] `),
|
|
1655
|
+
(answer) => {
|
|
1656
|
+
rl.close();
|
|
1657
|
+
if (answer.trim().toLowerCase() === "y") {
|
|
1658
|
+
deleteAllSessions();
|
|
1659
|
+
console.log(chalk.green(` Deleted ${sessions.length} session(s).`));
|
|
1660
|
+
} else {
|
|
1661
|
+
console.log(" Cancelled.");
|
|
1662
|
+
}
|
|
1663
|
+
closeDb();
|
|
1664
|
+
}
|
|
1665
|
+
);
|
|
1666
|
+
});
|
|
1560
1667
|
program.command("show <id>").description("Print full transcript for a session").option("-m, --markdown", "Output as GitHub-compatible markdown").action((id, opts) => {
|
|
1561
1668
|
const session = getSession(id) || getSessionByPrefix(id);
|
|
1562
1669
|
if (!session) {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/config.ts","../src/ui.tsx","../src/agents/claude.ts","../src/agents/codex.ts","../src/agents/gemini.ts","../src/agents/registry.ts","../src/format.ts","../src/clipboard.ts","../src/db/index.ts","../src/db/sessions.ts","../src/db/messages.ts","../src/prompts.ts","../src/config-editor.tsx"],"sourcesContent":["import { Command } from \"commander\";\nimport { execSync } from \"node:child_process\";\nimport chalk from \"chalk\";\nimport { loadConfig, setConfigValue } from \"./config.js\";\nimport { startApp, showTranscript, showTranscriptMarkdown, showSessionList } from \"./ui.js\";\nimport { startConfigEditor } from \"./config-editor.js\";\nimport type { AgentName } from \"./agents/types.js\";\nimport { getAgent, validateAgentPair } from \"./agents/registry.js\";\nimport {\n getMostRecentSession,\n getSession,\n getSessionByPrefix,\n listSessions,\n} from \"./db/sessions.js\";\nimport { getMessages } from \"./db/messages.js\";\nimport { closeDb } from \"./db/index.js\";\n\nprocess.on(\"SIGTERM\", () => { closeDb(); process.exit(0); });\nprocess.on(\"SIGINT\", () => { closeDb(); process.exit(0); });\n\nfunction checkCli(name: string, installUrl: string): boolean {\n try {\n execSync(`${name} --version`, { stdio: \"ignore\" });\n return true;\n } catch {\n console.error(\n chalk.red(`\"${name}\" not found. Install it from: ${installUrl}`)\n );\n return false;\n }\n}\n\nfunction preflight(pair: [AgentName, AgentName]): void {\n let allFound = true;\n for (const agent of pair) {\n const descriptor = getAgent(agent);\n if (!checkCli(descriptor.cliBinary, descriptor.installUrl)) {\n allFound = false;\n }\n }\n if (!allFound) {\n process.exit(1);\n }\n}\n\nfunction resolveAgentPair(opts: any, config: ReturnType<typeof loadConfig>): [AgentName, AgentName] {\n if (opts.agents) {\n const names = opts.agents.split(\",\").map((s: string) => s.trim());\n return validateAgentPair(names);\n }\n return validateAgentPair(config.agents);\n}\n\nfunction resolveAgentModels(\n pair: [AgentName, AgentName],\n opts: any,\n config: ReturnType<typeof loadConfig>\n): Record<AgentName, string> {\n return {\n claude: opts.claudeModel ?? config.claude.model,\n codex: opts.codexModel ?? config.codex.model,\n gemini: opts.geminiModel ?? config.gemini.model,\n };\n}\n\nconst program = new Command();\n\nprogram\n .name(\"tagteam\")\n .description(\"Tag Team - Orchestrate AI agents collaboratively\")\n .version(\"0.2.0\")\n .option(\"--agents <pair>\", \"Agent pair to use (comma-separated, e.g. claude,gemini)\")\n .option(\"--claude-model <model>\", \"Claude model to use\")\n .option(\"--codex-model <model>\", \"Codex model to use\")\n .option(\"--gemini-model <model>\", \"Gemini model to use\")\n .argument(\"[prompt...]\", \"Prompt to send to both agents\")\n .action(async (promptParts: string[], opts) => {\n const config = loadConfig();\n const pair = resolveAgentPair(opts, config);\n preflight(pair);\n const prompt = promptParts.join(\" \") || undefined;\n\n const instance = startApp({\n initialPrompt: prompt,\n agents: pair,\n agentModels: resolveAgentModels(pair, opts, config),\n config,\n });\n\n await instance.waitUntilExit();\n });\n\n// Discuss - auto-loop until consensus\nprogram\n .command(\"discuss\")\n .description(\"Have agents discuss a topic until they reach consensus\")\n .argument(\"<prompt...>\", \"Topic to discuss\")\n .action(async (promptParts: string[]) => {\n const config = loadConfig();\n const parentOpts = program.opts();\n const pair = resolveAgentPair(parentOpts, config);\n preflight(pair);\n const prompt = promptParts.join(\" \");\n\n const instance = startApp({\n initialPrompt: prompt,\n agents: pair,\n agentModels: resolveAgentModels(pair, parentOpts, config),\n config,\n discuss: true,\n });\n\n await instance.waitUntilExit();\n });\n\n// Continue most recent session\nprogram\n .command(\"continue\")\n .description(\"Resume the most recent session\")\n .action(async () => {\n const config = loadConfig();\n const parentOpts = program.opts();\n const pair = resolveAgentPair(parentOpts, config);\n preflight(pair);\n const session = getMostRecentSession();\n\n if (!session) {\n console.log(chalk.red(\" No active sessions found.\"));\n process.exit(1);\n }\n\n const dbMessages = getMessages(session.id);\n const transcript = dbMessages.map((m) => ({\n role: m.role,\n content: m.content,\n round: m.round,\n }));\n\n const instance = startApp({\n sessionId: session.id,\n agents: pair,\n agentModels: resolveAgentModels(pair, parentOpts, config),\n config,\n showTranscript: transcript,\n });\n\n await instance.waitUntilExit();\n });\n\n// Resume a specific session\nprogram\n .command(\"resume [id]\")\n .description(\"Resume a session by ID, or pick interactively\")\n .action(async (id: string | undefined) => {\n const config = loadConfig();\n const parentOpts = program.opts();\n const pair = resolveAgentPair(parentOpts, config);\n preflight(pair);\n\n if (!id) {\n const sessions = listSessions(20);\n if (sessions.length === 0) {\n console.log(chalk.red(\" No sessions found.\"));\n process.exit(1);\n }\n\n console.log(chalk.bold(\"\\n Recent sessions:\\n\"));\n sessions.forEach((s, i) => {\n const sid = chalk.cyan(s.id.slice(0, 7));\n const title = s.title || chalk.dim(\"(untitled)\");\n const date = chalk.dim(s.updated_at);\n console.log(` ${chalk.dim(`${i + 1}.`)} ${sid} ${title} ${date}`);\n });\n console.log();\n\n const readline = await import(\"node:readline\");\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n return new Promise<void>((resolve) => {\n rl.question(\" Select session number: \", async (input) => {\n rl.close();\n const num = parseInt(input.trim(), 10);\n if (isNaN(num) || num < 1 || num > sessions.length) {\n console.log(chalk.red(\" Invalid selection.\"));\n closeDb();\n resolve();\n return;\n }\n\n const session = sessions[num - 1];\n const dbMessages = getMessages(session.id);\n const transcript = dbMessages.map((m) => ({\n role: m.role,\n content: m.content,\n round: m.round,\n }));\n\n const instance = startApp({\n sessionId: session.id,\n agents: pair,\n agentModels: resolveAgentModels(pair, parentOpts, config),\n config,\n showTranscript: transcript,\n });\n\n await instance.waitUntilExit();\n resolve();\n });\n });\n }\n\n const session = getSession(id) || getSessionByPrefix(id);\n if (!session) {\n console.log(chalk.red(` Session not found: ${id}`));\n process.exit(1);\n }\n\n const dbMessages = getMessages(session.id);\n const transcript = dbMessages.map((m) => ({\n role: m.role,\n content: m.content,\n round: m.round,\n }));\n\n const instance = startApp({\n sessionId: session.id,\n agents: pair,\n agentModels: resolveAgentModels(pair, parentOpts, config),\n config,\n showTranscript: transcript,\n });\n\n await instance.waitUntilExit();\n });\n\n// History\nprogram\n .command(\"history\")\n .description(\"List recent sessions\")\n .option(\"-n, --limit <n>\", \"Number of sessions to show\", parseInt, 20)\n .action((opts) => {\n const sessions = listSessions(opts.limit);\n console.log(chalk.bold(\"\\n Recent sessions:\\n\"));\n showSessionList(sessions);\n console.log();\n closeDb();\n });\n\n// Show transcript\nprogram\n .command(\"show <id>\")\n .description(\"Print full transcript for a session\")\n .option(\"-m, --markdown\", \"Output as GitHub-compatible markdown\")\n .action((id: string, opts: { markdown?: boolean }) => {\n const session = getSession(id) || getSessionByPrefix(id);\n if (!session) {\n console.log(chalk.red(` Session not found: ${id}`));\n process.exit(1);\n }\n\n if (opts.markdown) {\n process.stdout.write(showTranscriptMarkdown(session.id));\n } else {\n showTranscript(session.id);\n }\n closeDb();\n });\n\n// Config commands\nconst configCmd = program\n .command(\"config\")\n .description(\"Manage configuration\")\n .action(async () => {\n const instance = startConfigEditor();\n await instance.waitUntilExit();\n });\n\nconfigCmd\n .command(\"edit\")\n .description(\"Interactively edit configuration\")\n .action(async () => {\n const instance = startConfigEditor();\n await instance.waitUntilExit();\n });\n\nconfigCmd\n .command(\"show\")\n .description(\"Show current configuration\")\n .action(() => {\n const config = loadConfig();\n console.log(chalk.bold(\"\\n Configuration:\\n\"));\n console.log(\n chalk.dim(\" agents = \") + chalk.white(config.agents.join(\", \"))\n );\n console.log(\n chalk.dim(\" claude.model = \") + chalk.white(config.claude.model)\n );\n console.log(\n chalk.dim(\" codex.model = \") + chalk.white(config.codex.model)\n );\n console.log(\n chalk.dim(\" gemini.model = \") + chalk.white(config.gemini.model)\n );\n console.log(\n chalk.dim(\" discussion.max_rounds = \") + chalk.white(String(config.discussion.max_rounds))\n );\n console.log();\n });\n\nconfigCmd\n .command(\"set <key> <value>\")\n .description(\"Set a configuration value\")\n .action((key: string, value: string) => {\n try {\n setConfigValue(key, value);\n console.log(chalk.green(` Set ${key} = ${value}`));\n } catch (e: any) {\n console.log(chalk.red(` ${e.message}`));\n process.exit(1);\n }\n });\n\nprogram.parseAsync();\n","import { readFileSync, writeFileSync, mkdirSync, existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { parse, stringify } from \"smol-toml\";\n\nexport interface TagTeamConfig {\n agents: [string, string];\n claude: {\n model: string;\n };\n codex: {\n model: string;\n };\n gemini: {\n model: string;\n };\n discussion: {\n max_rounds: number;\n };\n}\n\nconst DEFAULT_CONFIG: TagTeamConfig = {\n agents: [\"claude\", \"codex\"],\n claude: {\n model: \"sonnet\",\n },\n codex: {\n model: \"gpt-5.3-codex\",\n },\n gemini: {\n model: \"gemini-2.5-pro\",\n },\n discussion: {\n max_rounds: 10,\n },\n};\n\nexport function getConfigDir(): string {\n if (process.platform === \"win32\") {\n return join(\n process.env.APPDATA || join(homedir(), \"AppData\", \"Roaming\"),\n \"tagteam\"\n );\n }\n return join(homedir(), \".tagteam\");\n}\n\nexport function getConfigPath(): string {\n return join(getConfigDir(), \"config.toml\");\n}\n\nexport function ensureConfigDir(): void {\n const dir = getConfigDir();\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n}\n\nexport function loadConfig(): TagTeamConfig {\n const configPath = getConfigPath();\n\n if (!existsSync(configPath)) {\n return { ...DEFAULT_CONFIG };\n }\n\n try {\n const raw = readFileSync(configPath, \"utf-8\");\n const parsed = parse(raw) as any;\n return {\n agents: Array.isArray(parsed.agents) && parsed.agents.length === 2\n ? parsed.agents as [string, string]\n : [...DEFAULT_CONFIG.agents],\n claude: { ...DEFAULT_CONFIG.claude, ...parsed.claude },\n codex: { ...DEFAULT_CONFIG.codex, ...parsed.codex },\n gemini: { ...DEFAULT_CONFIG.gemini, ...parsed.gemini },\n discussion: { ...DEFAULT_CONFIG.discussion, ...parsed.discussion },\n };\n } catch {\n return { ...DEFAULT_CONFIG };\n }\n}\n\nexport function saveConfig(config: TagTeamConfig): void {\n ensureConfigDir();\n const configPath = getConfigPath();\n writeFileSync(configPath, stringify(config as any), \"utf-8\");\n}\n\nexport function setConfigValue(\n key: string,\n value: string\n): TagTeamConfig {\n const config = loadConfig();\n const parts = key.split(\".\");\n\n if (parts.length === 1) {\n switch (parts[0]) {\n case \"agents\":\n config.agents = value.split(\",\").map((s) => s.trim()) as [string, string];\n break;\n case \"claude_model\":\n config.claude.model = value;\n break;\n case \"codex_model\":\n config.codex.model = value;\n break;\n case \"gemini_model\":\n config.gemini.model = value;\n break;\n case \"discussion_max_rounds\":\n config.discussion.max_rounds = Number(value);\n break;\n default:\n throw new Error(`Unknown config key: ${key}`);\n }\n } else if (parts.length === 2) {\n const [section, field] = parts;\n if (section === \"claude\" && field === \"model\") {\n config.claude.model = value;\n } else if (section === \"codex\" && field === \"model\") {\n config.codex.model = value;\n } else if (section === \"gemini\" && field === \"model\") {\n config.gemini.model = value;\n } else if (section === \"discussion\" && field === \"max_rounds\") {\n config.discussion.max_rounds = Number(value);\n } else {\n throw new Error(`Unknown config key: ${key}`);\n }\n } else {\n throw new Error(`Invalid config key format: ${key}`);\n }\n\n saveConfig(config);\n return config;\n}\n","import React, { useState, useEffect, useCallback, useRef } from \"react\";\nimport { render, Box, Text, useApp, useInput } from \"ink\";\nimport TextInput from \"ink-text-input\";\nimport Spinner from \"ink-spinner\";\nimport { marked } from \"marked\";\nimport { markedTerminal } from \"marked-terminal\";\nimport { nanoid } from \"nanoid\";\nimport type { AgentName, AgentResponse } from \"./agents/types.js\";\nimport { getAgent, isValidAgentName } from \"./agents/registry.js\";\nimport { formatAsMarkdown } from \"./format.js\";\nimport { copyToClipboard } from \"./clipboard.js\";\nimport { createSession, touchSession, updateSessionTitle } from \"./db/sessions.js\";\nimport { insertMessage, getMessages, deleteMessagesFromRound } from \"./db/messages.js\";\nimport { closeDb } from \"./db/index.js\";\nimport {\n collaborationPrompt,\n discussionPrompt,\n debatePrompt,\n debateRoundPrompt,\n CONSENSUS_MARKER,\n formatConversationHistory,\n} from \"./prompts.js\";\nimport { loadConfig } from \"./config.js\";\nimport type { TagTeamConfig } from \"./config.js\";\nimport { validateAgentPair } from \"./agents/registry.js\";\nimport { InlineConfigEditor } from \"./config-editor.js\";\n\nmarked.use(markedTerminal() as any);\n\n// --- Types ---\n\ninterface Message {\n role: string;\n content: string;\n round: number;\n error?: boolean;\n}\n\nexport interface AppProps {\n initialPrompt?: string;\n sessionId?: string;\n agents: [AgentName, AgentName];\n agentModels: Record<AgentName, string>;\n config: TagTeamConfig;\n showTranscript?: Message[];\n discuss?: boolean;\n}\n\ntype AppState = \"input\" | \"running\" | \"done\" | \"config\";\ntype Target = \"both\" | AgentName;\n\ninterface ParsedInput {\n target: Target;\n prompt: string;\n discuss: boolean;\n}\n\nfunction parseInput(input: string, pair: [AgentName, AgentName]): ParsedInput {\n const lower = input.toLowerCase();\n if (lower.startsWith(\"discuss \")) {\n return { target: \"both\", prompt: input.slice(8).trim(), discuss: true };\n }\n for (const agent of pair) {\n if (lower.startsWith(`${agent} `) || lower.startsWith(`${agent}, `)) {\n return { target: agent, prompt: input.slice(input.indexOf(\" \") + 1).trim(), discuss: false };\n }\n }\n return { target: \"both\", prompt: input, discuss: false };\n}\n\n// --- Components ---\n\nfunction RenderedMarkdown({ text }: { text: string }) {\n const rendered = (marked.parse(text) as string).trimEnd();\n return <Text>{rendered}</Text>;\n}\n\nfunction AgentResponseBlock({\n agent,\n content,\n error,\n}: {\n agent: AgentName;\n content: string;\n error?: boolean;\n}) {\n const descriptor = getAgent(agent);\n\n if (error) {\n return (\n <Box flexDirection=\"column\" marginLeft={1} marginBottom={1}>\n <Text color=\"red\" bold>\n {descriptor.displayName} error:\n </Text>\n <Box marginLeft={1}>\n <Text color=\"red\">{content}</Text>\n </Box>\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"column\" marginLeft={1} marginBottom={1}>\n <Text color={descriptor.color} bold>\n {descriptor.displayName}:\n </Text>\n <Box marginLeft={1}>\n <RenderedMarkdown text={content} />\n </Box>\n </Box>\n );\n}\n\nfunction Header({ sessionId }: { sessionId: string }) {\n return (\n <Box marginBottom={1}>\n <Text dimColor>{\"── \"}</Text>\n <Text bold>Tag Team</Text>\n <Text dimColor>{\" ── session \"}</Text>\n <Text color=\"cyan\">{sessionId.slice(0, 7)}</Text>\n <Text dimColor>{\" \" + \"─\".repeat(35)}</Text>\n </Box>\n );\n}\n\nfunction UserMessage({ content }: { content: string }) {\n return (\n <Box marginLeft={1} marginBottom={1}>\n <Text bold color=\"white\">\n You:{\" \"}\n </Text>\n <Text>{content}</Text>\n </Box>\n );\n}\n\nfunction ThinkingIndicator({ agent }: { agent: AgentName }) {\n const descriptor = getAgent(agent);\n return (\n <Box marginLeft={1}>\n <Text color={descriptor.color}>\n <Spinner type=\"dots\" />\n </Text>\n <Text color={descriptor.color}> {descriptor.displayName} is thinking...</Text>\n </Box>\n );\n}\n\nfunction DiscussionStatus({ round, maxRounds }: { round: number; maxRounds: number }) {\n return (\n <Box marginLeft={1} marginBottom={1}>\n <Text color=\"yellow\" bold>\n Discussion round {round}/{maxRounds}\n </Text>\n </Box>\n );\n}\n\nfunction ConsensusReached() {\n return (\n <Box marginLeft={1} marginBottom={1}>\n <Text color=\"green\" bold>\n Consensus reached.\n </Text>\n </Box>\n );\n}\n\nfunction PromptInput({\n onSubmit,\n}: {\n onSubmit: (value: string) => void;\n}) {\n const [value, setValue] = useState(\"\");\n\n const handleSubmit = useCallback(\n (submitted: string) => {\n if (submitted.trim()) {\n onSubmit(submitted.trim());\n setValue(\"\");\n }\n },\n [onSubmit]\n );\n\n return (\n <Box marginLeft={1}>\n <Text bold color=\"white\">\n {\"> \"}\n </Text>\n <TextInput\n value={value}\n onChange={setValue}\n onSubmit={handleSubmit}\n showCursor\n />\n </Box>\n );\n}\n\n// --- Main App ---\n\nfunction App({\n initialPrompt,\n sessionId: existingSessionId,\n agents: initialPair,\n agentModels: initialAgentModels,\n config: initialConfig,\n showTranscript,\n discuss: initialDiscuss,\n}: AppProps) {\n const { exit } = useApp();\n const [sessionId, setSessionId] = useState(() => existingSessionId ?? nanoid(12));\n const [messages, setMessages] = useState<Message[]>(showTranscript ?? []);\n const [state, setState] = useState<AppState>(\n initialPrompt ? \"running\" : \"input\"\n );\n const [pair, setPair] = useState<[AgentName, AgentName]>(initialPair);\n const [agentModels, setAgentModels] = useState<Record<AgentName, string>>(initialAgentModels);\n const [config, setConfig] = useState<TagTeamConfig>(initialConfig);\n const [thinkingAgents, setThinkingAgents] = useState<AgentName[]>([]);\n const [discussionRound, setDiscussionRound] = useState(0);\n const [consensusReached, setConsensusReached] = useState(false);\n const [statusMessage, setStatusMessage] = useState<string | null>(null);\n const [roundNum, setRoundNum] = useState(() => {\n if (showTranscript && showTranscript.length > 0) {\n return Math.max(...showTranscript.map((m) => m.round)) + 1;\n }\n return 0;\n });\n\n // Create session on first mount if new\n useEffect(() => {\n if (!existingSessionId) {\n createSession(sessionId, process.cwd());\n }\n }, []);\n\n // Handle initial prompt\n useEffect(() => {\n if (initialPrompt && state === \"running\") {\n if (initialDiscuss) {\n runDiscussion(initialPrompt);\n } else {\n runRound(initialPrompt);\n }\n }\n }, []);\n\n const abortRef = useRef<AbortController | null>(null);\n const runningRoundRef = useRef<number | null>(null);\n\n // Ctrl+C and Escape handling\n useInput((input, key) => {\n if (key.ctrl && input === \"c\") {\n abortRef.current?.abort();\n closeDb();\n exit();\n }\n if (key.escape && state === \"running\") {\n abortRef.current?.abort();\n abortRef.current = null;\n\n // Remove the user prompt and any partial results from DB and state\n if (runningRoundRef.current !== null) {\n deleteMessagesFromRound(sessionId, runningRoundRef.current);\n const fromRound = runningRoundRef.current;\n setMessages((prev) => prev.filter((m) => m.round < fromRound));\n runningRoundRef.current = null;\n }\n\n setThinkingAgents([]);\n setDiscussionRound(0);\n setStatusMessage(\"Interrupted.\");\n setState(\"input\");\n }\n });\n\n // Run agents, save results, return new messages\n const runAgents = async (\n currentMessages: Message[],\n round: number,\n target: Target,\n promptOverride?: string,\n isDebate = false,\n ): Promise<Message[]> => {\n // Determine which agents to run\n const activeAgents: AgentName[] = target === \"both\"\n ? [...pair]\n : [target];\n setThinkingAgents(activeAgents);\n\n const history = formatConversationHistory(\n currentMessages.map((m) => ({\n role: m.role,\n agent: isValidAgentName(m.role) ? m.role : undefined,\n content: m.content,\n }))\n );\n\n const cwd = process.cwd();\n const isFirstRound = round === 0 && !existingSessionId;\n\n const agentPrompt = (_agent: AgentName) => {\n if (promptOverride) return promptOverride;\n if (isFirstRound && target === \"both\") {\n return currentMessages[currentMessages.length - 1]?.content || \"\";\n }\n return \"Provide your response for this round.\";\n };\n\n const agentSystemPrompt = (agent: AgentName) => {\n if (isDebate) {\n if (isFirstRound) return debatePrompt(agent, pair);\n return debateRoundPrompt(agent, history, pair);\n }\n if (isFirstRound && target === \"both\") return collaborationPrompt(agent, pair);\n return discussionPrompt(agent, history, pair);\n };\n\n const ac = new AbortController();\n abortRef.current = ac;\n\n const results: Array<{ agent: AgentName; result: PromiseSettledResult<AgentResponse> }> = [];\n const promises: Array<Promise<void>> = [];\n\n for (const agent of activeAgents) {\n const descriptor = getAgent(agent);\n promises.push(\n descriptor.run({\n prompt: agentPrompt(agent),\n systemPrompt: agentSystemPrompt(agent),\n model: agentModels[agent],\n cwd,\n signal: ac.signal,\n }).then(\n (value) => { results.push({ agent, result: { status: \"fulfilled\", value } }); },\n (reason) => { results.push({ agent, result: { status: \"rejected\", reason } }); }\n )\n );\n }\n\n await Promise.all(promises);\n abortRef.current = null;\n\n // If aborted, bail out — the Escape handler already reset UI state\n if (ac.signal.aborted) return [];\n\n setThinkingAgents([]);\n\n const newMessages: Message[] = [];\n\n for (const { agent, result } of results) {\n if (result.status === \"fulfilled\") {\n const resp = result.value;\n const msg: Message = {\n role: agent,\n content: resp.error || resp.text,\n round,\n error: !!resp.error,\n };\n newMessages.push(msg);\n insertMessage({\n sessionId,\n role: agent,\n content: resp.error || resp.text,\n round,\n durationMs: resp.durationMs,\n });\n } else {\n const errorMsg = result.reason?.message || \"Failed to run\";\n const msg: Message = {\n role: agent,\n content: errorMsg,\n round,\n error: true,\n };\n newMessages.push(msg);\n insertMessage({\n sessionId,\n role: agent,\n content: `[Error: ${errorMsg}]`,\n round,\n });\n }\n }\n\n return newMessages;\n };\n\n const runRound = async (rawInput: string) => {\n const { target, prompt, discuss } = parseInput(rawInput, pair);\n\n if (discuss) {\n return runDiscussion(prompt);\n }\n\n const currentRound = roundNum;\n runningRoundRef.current = currentRound;\n\n // Add user message\n const userMsg: Message = {\n role: \"user\",\n content: rawInput,\n round: currentRound,\n };\n setMessages((prev) => [...prev, userMsg]);\n insertMessage({\n sessionId,\n role: \"user\",\n content: rawInput,\n round: currentRound,\n });\n\n const allMessages = [...messages, userMsg];\n const newMessages = await runAgents(allMessages, currentRound, target);\n\n // If aborted, the Escape handler already cleaned up\n if (newMessages.length === 0) return;\n\n setMessages((prev) => [...prev, ...newMessages]);\n setRoundNum(currentRound + 1);\n runningRoundRef.current = null;\n\n if (currentRound === 0 && !existingSessionId) {\n const title = prompt.length > 60 ? prompt.slice(0, 57) + \"...\" : prompt;\n updateSessionTitle(sessionId, title);\n }\n\n touchSession(sessionId);\n setState(\"input\");\n };\n\n const runDiscussion = async (prompt: string) => {\n setConsensusReached(false);\n let currentRound = roundNum;\n runningRoundRef.current = currentRound;\n\n // Add user message\n const userMsg: Message = {\n role: \"user\",\n content: `discuss ${prompt}`,\n round: currentRound,\n };\n setMessages((prev) => [...prev, userMsg]);\n insertMessage({\n sessionId,\n role: \"user\",\n content: `discuss ${prompt}`,\n round: currentRound,\n });\n\n let allMessages = [...messages, userMsg];\n\n if (currentRound === 0 && !existingSessionId) {\n const title = prompt.length > 60 ? prompt.slice(0, 57) + \"...\" : prompt;\n updateSessionTitle(sessionId, title);\n }\n\n for (let disc = 1; disc <= config.discussion.max_rounds; disc++) {\n setDiscussionRound(disc);\n\n const newMessages = await runAgents(\n allMessages,\n currentRound,\n \"both\",\n disc === 1 ? prompt : \"Provide your response for this round.\",\n true,\n );\n\n // If aborted, stop the discussion loop\n if (newMessages.length === 0) break;\n\n setMessages((prev) => [...prev, ...newMessages]);\n allMessages = [...allMessages, ...newMessages];\n currentRound++;\n\n // Check for consensus — both agents in the pair must include the marker\n const consensusFlags = pair.map((agent) => {\n const msg = newMessages.find((m) => m.role === agent && !m.error);\n return msg?.content.includes(CONSENSUS_MARKER) ?? false;\n });\n\n if (consensusFlags.every(Boolean)) {\n setConsensusReached(true);\n break;\n }\n }\n\n setRoundNum(currentRound);\n setDiscussionRound(0);\n runningRoundRef.current = null;\n touchSession(sessionId);\n setState(\"input\");\n };\n\n const handleSubmit = (value: string) => {\n setStatusMessage(null);\n\n if (value === \"/exit\") {\n closeDb();\n exit();\n return;\n }\n\n if (value === \"/help\") {\n setStatusMessage(\n [\n \"/help Show this help\",\n \"/config Edit configuration\",\n \"/new Start a new session\",\n \"/copy Copy conversation to clipboard\",\n \"/exit Exit the app\",\n \"\",\n \"Esc Interrupt running agents\",\n ].join(\"\\n\")\n );\n return;\n }\n\n if (value === \"/config\") {\n setState(\"config\");\n return;\n }\n\n if (value === \"/new\") {\n const newId = nanoid(12);\n createSession(newId, process.cwd());\n setSessionId(newId);\n setMessages([]);\n setRoundNum(0);\n setConsensusReached(false);\n setDiscussionRound(0);\n setStatusMessage(\"Started new session.\");\n return;\n }\n\n if (value === \"/copy\") {\n try {\n const md = formatAsMarkdown(messages);\n copyToClipboard(md);\n setStatusMessage(\"Copied conversation to clipboard.\");\n } catch {\n setStatusMessage(\"Failed to copy to clipboard.\");\n }\n return;\n }\n\n setConsensusReached(false);\n setState(\"running\");\n runRound(value);\n };\n\n return (\n <Box flexDirection=\"column\">\n <Header sessionId={sessionId} />\n\n {messages.map((msg, i) => {\n if (msg.role === \"user\") {\n return <UserMessage key={i} content={msg.content} />;\n }\n if (isValidAgentName(msg.role)) {\n return (\n <AgentResponseBlock\n key={i}\n agent={msg.role}\n content={msg.content}\n error={msg.error}\n />\n );\n }\n return null;\n })}\n\n {discussionRound > 0 && thinkingAgents.length > 0 && (\n <DiscussionStatus round={discussionRound} maxRounds={config.discussion.max_rounds} />\n )}\n\n {thinkingAgents.length > 0 && (\n <Box flexDirection=\"column\" marginBottom={1}>\n {thinkingAgents.map((agent) => (\n <ThinkingIndicator key={agent} agent={agent} />\n ))}\n </Box>\n )}\n\n {consensusReached && <ConsensusReached />}\n\n {statusMessage && (\n <Box marginLeft={1}>\n <Text dimColor italic>{statusMessage}</Text>\n </Box>\n )}\n\n {state === \"config\" && (\n <InlineConfigEditor\n isActive={state === \"config\"}\n onClose={() => {\n const updated = loadConfig();\n setConfig(updated);\n try {\n setPair(validateAgentPair(updated.agents));\n } catch {\n // keep current pair if new config is invalid\n }\n setAgentModels((prev) => ({\n ...prev,\n claude: updated.claude.model,\n codex: updated.codex.model,\n gemini: updated.gemini.model,\n }));\n setState(\"input\");\n }}\n />\n )}\n\n {state === \"input\" && <PromptInput onSubmit={handleSubmit} />}\n </Box>\n );\n}\n\n// --- Entry points ---\n\nexport function startApp(props: AppProps) {\n return render(<App {...props} />);\n}\n\nexport function showTranscriptMarkdown(sessionId: string): string {\n const dbMessages = getMessages(sessionId);\n const messages = dbMessages.map((m) => ({\n role: m.role,\n content: m.content,\n round: m.round,\n }));\n return formatAsMarkdown(messages);\n}\n\nexport function showTranscript(sessionId: string): void {\n const dbMessages = getMessages(sessionId);\n const messages: Message[] = dbMessages.map((m) => ({\n role: m.role,\n content: m.content,\n round: m.round,\n }));\n\n const { unmount } = render(\n <Box flexDirection=\"column\">\n <Header sessionId={sessionId} />\n {messages.map((msg, i) => {\n if (msg.role === \"user\") {\n return <UserMessage key={i} content={msg.content} />;\n }\n if (isValidAgentName(msg.role)) {\n return (\n <AgentResponseBlock key={i} agent={msg.role} content={msg.content} />\n );\n }\n return null;\n })}\n <Box>\n <Text dimColor>{\"─\".repeat(60)}</Text>\n </Box>\n </Box>\n );\n\n unmount();\n}\n\nexport function showSessionList(\n sessions: Array<{\n id: string;\n title: string | null;\n status: string;\n created_at: string;\n updated_at: string;\n }>\n): void {\n const { unmount } = render(\n <Box flexDirection=\"column\">\n {sessions.length === 0 ? (\n <Text dimColor> No sessions found.</Text>\n ) : (\n sessions.map((s) => (\n <Box key={s.id} marginLeft={1}>\n <Text color=\"cyan\">{s.id.slice(0, 7)}</Text>\n <Text>{\" \"}</Text>\n <Text>{s.title || \"(untitled)\"}</Text>\n <Text>{\" \"}</Text>\n <Text color={s.status === \"active\" ? \"green\" : undefined} dimColor={s.status !== \"active\"}>\n {s.status}\n </Text>\n <Text>{\" \"}</Text>\n <Text dimColor>{s.updated_at}</Text>\n </Box>\n ))\n )}\n </Box>\n );\n\n unmount();\n}\n","import { spawn } from \"node:child_process\";\nimport { createInterface } from \"node:readline\";\nimport type { AgentEvent, AgentOptions, AgentResponse } from \"./types.js\";\n\n/**\n * Parse Claude Code's stream-json JSONL output into AgentEvents.\n *\n * Event format (one JSON object per line):\n * { type: \"system\", subtype: \"init\", ... }\n * { type: \"assistant\", message: { content: [{ type: \"text\", text }, { type: \"tool_use\", ... }] } }\n * { type: \"user\", message: { content: [{ type: \"tool_result\", ... }] } }\n * { type: \"result\", subtype: \"success\", result: \"final text\", ... }\n */\n\nasync function* streamClaude(\n options: AgentOptions\n): AsyncGenerator<AgentEvent> {\n const args = [\n \"-p\",\n \"--verbose\",\n \"--output-format\",\n \"stream-json\",\n \"--no-session-persistence\",\n ];\n\n if (options.systemPrompt) {\n args.push(\"--system-prompt\", options.systemPrompt);\n }\n if (options.model) {\n args.push(\"--model\", options.model);\n }\n\n args.push(options.prompt);\n\n const proc = spawn(\"claude\", args, {\n cwd: options.cwd,\n stdio: [\"ignore\", \"pipe\", \"inherit\"],\n env: { ...process.env, CLAUDECODE: \"\" },\n });\n\n // Handle spawn errors (e.g., command not found)\n let spawnErrorMsg = \"\";\n proc.on(\"error\", (err) => {\n spawnErrorMsg = err.message;\n });\n\n // Abort support — kill the child process when signalled\n if (options.signal) {\n if (options.signal.aborted) {\n proc.kill();\n } else {\n options.signal.addEventListener(\"abort\", () => proc.kill(), { once: true });\n }\n }\n\n const rl = createInterface({ input: proc.stdout! });\n let gotResultText = false;\n\n for await (const line of rl) {\n if (!line.trim()) continue;\n\n let data: any;\n try {\n data = JSON.parse(line);\n } catch {\n continue;\n }\n\n if (data.type === \"assistant\" && data.message?.content) {\n for (const block of data.message.content) {\n if (block.type === \"text\" && block.text) {\n yield { type: \"text\", agent: \"claude\", content: block.text };\n gotResultText = true;\n } else if (block.type === \"tool_use\") {\n yield {\n type: \"tool_call\",\n agent: \"claude\",\n toolName: block.name,\n toolInput:\n typeof block.input === \"string\"\n ? block.input\n : JSON.stringify(block.input),\n };\n }\n }\n } else if (data.type === \"user\" && data.message?.content) {\n for (const block of data.message.content) {\n if (block.type === \"tool_result\") {\n const text =\n typeof block.content === \"string\"\n ? block.content\n : Array.isArray(block.content)\n ? block.content\n .filter((c: any) => c.type === \"text\")\n .map((c: any) => c.text)\n .join(\"\\n\")\n : \"\";\n if (text) {\n yield {\n type: \"tool_result\",\n agent: \"claude\",\n toolOutput: text,\n };\n }\n }\n }\n } else if (data.type === \"result\") {\n if (data.is_error) {\n yield {\n type: \"error\",\n agent: \"claude\",\n content: data.error || data.result || \"Unknown error\",\n };\n } else if (data.result && !gotResultText) {\n // Use result.result as fallback if no assistant text blocks were emitted\n yield { type: \"text\", agent: \"claude\", content: data.result };\n }\n }\n }\n\n // Wait for the process to exit\n await new Promise<void>((resolve) => {\n proc.on(\"close\", resolve);\n });\n\n if (spawnErrorMsg) {\n yield {\n type: \"error\",\n agent: \"claude\",\n content: `Failed to spawn claude: ${spawnErrorMsg}`,\n };\n }\n\n yield { type: \"done\", agent: \"claude\" };\n}\n\nexport async function runClaude(options: AgentOptions): Promise<AgentResponse> {\n const start = Date.now();\n const events: AgentEvent[] = [];\n const textParts: string[] = [];\n const errors: string[] = [];\n\n for await (const event of streamClaude(options)) {\n events.push(event);\n if (event.type === \"text\" && event.content) {\n textParts.push(event.content);\n } else if (event.type === \"error\" && event.content) {\n errors.push(event.content);\n }\n }\n\n return {\n agent: \"claude\",\n text: textParts.join(\"\"),\n events,\n durationMs: Date.now() - start,\n error: errors.length > 0 ? errors.join(\"\\n\") : undefined,\n };\n}\n","import { spawn } from \"node:child_process\";\nimport { createInterface } from \"node:readline\";\nimport type { AgentEvent, AgentOptions, AgentResponse } from \"./types.js\";\n\n/**\n * Parse Codex CLI's exec --json JSONL output into AgentEvents.\n *\n * Event format (one JSON object per line):\n * { type: \"thread.started\", thread_id: \"...\" }\n * { type: \"turn.started\" }\n * { type: \"item.completed\", item: { type: \"agent_message\", text: \"...\" } }\n * { type: \"item.started\"|\"item.completed\", item: { type: \"command_execution\", command, aggregated_output, exit_code } }\n * { type: \"turn.completed\", usage: { ... } }\n */\n\nasync function* streamCodex(\n options: AgentOptions\n): AsyncGenerator<AgentEvent> {\n const args = [\"exec\", \"--json\", \"--full-auto\", \"--ephemeral\"];\n\n if (options.model) {\n args.push(\"-m\", options.model);\n }\n\n // Build the full prompt with system context prepended\n let fullPrompt = options.prompt;\n if (options.systemPrompt) {\n fullPrompt = `${options.systemPrompt}\\n\\n---\\n\\n${options.prompt}`;\n }\n\n args.push(fullPrompt);\n\n const proc = spawn(\"codex\", args, {\n cwd: options.cwd,\n stdio: [\"ignore\", \"pipe\", \"inherit\"],\n env: process.env,\n });\n\n // Handle spawn errors (e.g., command not found)\n let spawnErrorMsg = \"\";\n proc.on(\"error\", (err) => {\n spawnErrorMsg = err.message;\n });\n\n // Abort support — kill the child process when signalled\n if (options.signal) {\n if (options.signal.aborted) {\n proc.kill();\n } else {\n options.signal.addEventListener(\"abort\", () => proc.kill(), { once: true });\n }\n }\n\n const rl = createInterface({ input: proc.stdout! });\n\n for await (const line of rl) {\n if (!line.trim()) continue;\n\n let data: any;\n try {\n data = JSON.parse(line);\n } catch {\n continue;\n }\n\n if (data.type === \"item.completed\" && data.item) {\n const item = data.item;\n\n if (item.type === \"agent_message\" && item.text) {\n yield { type: \"text\", agent: \"codex\", content: item.text };\n } else if (item.type === \"command_execution\") {\n yield {\n type: \"tool_call\",\n agent: \"codex\",\n toolName: \"command\",\n toolInput: item.command,\n };\n if (item.aggregated_output) {\n yield {\n type: \"tool_result\",\n agent: \"codex\",\n toolOutput: item.aggregated_output,\n };\n }\n } else if (item.type === \"file_change\" && item.changes) {\n const desc = item.changes\n .map((c: any) => `${c.kind}: ${c.path}`)\n .join(\", \");\n yield {\n type: \"tool_result\",\n agent: \"codex\",\n toolName: \"file_change\",\n toolOutput: desc,\n };\n } else if (item.type === \"error\") {\n yield {\n type: \"error\",\n agent: \"codex\",\n content: item.message || \"Unknown error\",\n };\n }\n } else if (data.type === \"turn.failed\") {\n yield {\n type: \"error\",\n agent: \"codex\",\n content: data.error?.message || \"Turn failed\",\n };\n } else if (data.type === \"error\") {\n yield {\n type: \"error\",\n agent: \"codex\",\n content: data.message || \"Stream error\",\n };\n }\n }\n\n // Wait for the process to exit\n await new Promise<void>((resolve) => {\n proc.on(\"close\", resolve);\n });\n\n if (spawnErrorMsg) {\n yield {\n type: \"error\",\n agent: \"codex\",\n content: `Failed to spawn codex: ${spawnErrorMsg}`,\n };\n }\n\n yield { type: \"done\", agent: \"codex\" };\n}\n\nexport async function runCodex(options: AgentOptions): Promise<AgentResponse> {\n const start = Date.now();\n const events: AgentEvent[] = [];\n const textParts: string[] = [];\n const errors: string[] = [];\n\n for await (const event of streamCodex(options)) {\n events.push(event);\n if (event.type === \"text\" && event.content) {\n textParts.push(event.content);\n } else if (event.type === \"error\" && event.content) {\n errors.push(event.content);\n }\n }\n\n return {\n agent: \"codex\",\n text: textParts.join(\"\"),\n events,\n durationMs: Date.now() - start,\n error: errors.length > 0 ? errors.join(\"\\n\") : undefined,\n };\n}\n","import { spawn } from \"node:child_process\";\nimport type { AgentEvent, AgentOptions, AgentResponse } from \"./types.js\";\n\n/**\n * Run the Gemini CLI and parse its JSON output into AgentEvents.\n *\n * Gemini CLI returns a single JSON blob (not streaming JSONL):\n * { response: \"text\", stats: {...}, error: \"...\" }\n *\n * No --system-prompt flag — prepend system prompt to user prompt (same as codex).\n * Flags: gemini -p \"prompt\" --output-format json -m model --yolo\n */\n\nasync function* streamGemini(\n options: AgentOptions\n): AsyncGenerator<AgentEvent> {\n const args = [\"-p\"];\n\n // Build the full prompt with system context prepended\n let fullPrompt = options.prompt;\n if (options.systemPrompt) {\n fullPrompt = `${options.systemPrompt}\\n\\n---\\n\\n${options.prompt}`;\n }\n\n args.push(fullPrompt, \"--output-format\", \"json\", \"--yolo\");\n\n if (options.model) {\n args.push(\"-m\", options.model);\n }\n\n const proc = spawn(\"gemini\", args, {\n cwd: options.cwd,\n stdio: [\"ignore\", \"pipe\", \"inherit\"],\n env: process.env,\n });\n\n // Handle spawn errors (e.g., command not found)\n let spawnErrorMsg = \"\";\n proc.on(\"error\", (err) => {\n spawnErrorMsg = err.message;\n });\n\n // Abort support — kill the child process when signalled\n if (options.signal) {\n if (options.signal.aborted) {\n proc.kill();\n } else {\n options.signal.addEventListener(\"abort\", () => proc.kill(), { once: true });\n }\n }\n\n // Collect all stdout into a single buffer\n const chunks: Buffer[] = [];\n proc.stdout!.on(\"data\", (chunk: Buffer) => {\n chunks.push(chunk);\n });\n\n // Wait for the process to exit\n await new Promise<void>((resolve) => {\n proc.on(\"close\", resolve);\n });\n\n if (spawnErrorMsg) {\n yield {\n type: \"error\",\n agent: \"gemini\",\n content: `Failed to spawn gemini: ${spawnErrorMsg}`,\n };\n yield { type: \"done\", agent: \"gemini\" };\n return;\n }\n\n const stdout = Buffer.concat(chunks).toString(\"utf-8\").trim();\n\n if (!stdout) {\n yield { type: \"error\", agent: \"gemini\", content: \"No output from gemini\" };\n yield { type: \"done\", agent: \"gemini\" };\n return;\n }\n\n try {\n const data = JSON.parse(stdout);\n\n if (data.error) {\n yield { type: \"error\", agent: \"gemini\", content: data.error };\n } else if (data.response) {\n yield { type: \"text\", agent: \"gemini\", content: data.response };\n } else {\n yield { type: \"error\", agent: \"gemini\", content: \"Unexpected response format\" };\n }\n } catch {\n // If it's not JSON, treat the entire stdout as text\n yield { type: \"text\", agent: \"gemini\", content: stdout };\n }\n\n yield { type: \"done\", agent: \"gemini\" };\n}\n\nexport async function runGemini(options: AgentOptions): Promise<AgentResponse> {\n const start = Date.now();\n const events: AgentEvent[] = [];\n const textParts: string[] = [];\n const errors: string[] = [];\n\n for await (const event of streamGemini(options)) {\n events.push(event);\n if (event.type === \"text\" && event.content) {\n textParts.push(event.content);\n } else if (event.type === \"error\" && event.content) {\n errors.push(event.content);\n }\n }\n\n return {\n agent: \"gemini\",\n text: textParts.join(\"\"),\n events,\n durationMs: Date.now() - start,\n error: errors.length > 0 ? errors.join(\"\\n\") : undefined,\n };\n}\n","import type { AgentDescriptor, AgentName } from \"./types.js\";\nimport { runClaude } from \"./claude.js\";\nimport { runCodex } from \"./codex.js\";\nimport { runGemini } from \"./gemini.js\";\n\nconst AGENTS: Record<AgentName, AgentDescriptor> = {\n claude: {\n name: \"claude\",\n displayName: \"Claude\",\n color: \"magenta\",\n cliBinary: \"claude\",\n installUrl: \"https://docs.anthropic.com/en/docs/claude-code\",\n org: \"Anthropic\",\n run: runClaude,\n },\n codex: {\n name: \"codex\",\n displayName: \"Codex\",\n color: \"green\",\n cliBinary: \"codex\",\n installUrl: \"https://github.com/openai/codex\",\n org: \"OpenAI\",\n run: runCodex,\n },\n gemini: {\n name: \"gemini\",\n displayName: \"Gemini\",\n color: \"blue\",\n cliBinary: \"gemini\",\n installUrl: \"https://github.com/google-gemini/gemini-cli\",\n org: \"Google\",\n run: runGemini,\n },\n};\n\nexport function getAgent(name: AgentName): AgentDescriptor {\n return AGENTS[name];\n}\n\nexport function getAllAgentNames(): AgentName[] {\n return Object.keys(AGENTS) as AgentName[];\n}\n\nexport function isValidAgentName(name: string): name is AgentName {\n return name in AGENTS;\n}\n\nexport function validateAgentPair(pair: string[]): [AgentName, AgentName] {\n if (pair.length !== 2) {\n throw new Error(\"Agent pair must contain exactly 2 agents\");\n }\n if (pair[0] === pair[1]) {\n throw new Error(\"Agent pair must contain 2 distinct agents\");\n }\n for (const name of pair) {\n if (!isValidAgentName(name)) {\n throw new Error(`Unknown agent: \"${name}\". Valid agents: ${getAllAgentNames().join(\", \")}`);\n }\n }\n return pair as [AgentName, AgentName];\n}\n","import { getAgent, isValidAgentName } from \"./agents/registry.js\";\n\ninterface Message {\n role: string;\n content: string;\n error?: boolean;\n}\n\nexport function formatAsMarkdown(messages: Message[]): string {\n const parts: string[] = [];\n\n for (const msg of messages) {\n if (msg.role === \"system\") continue;\n\n if (msg.role === \"user\") {\n parts.push(`**You:** ${msg.content}`);\n } else if (isValidAgentName(msg.role)) {\n const name = getAgent(msg.role).displayName;\n if (msg.error) {\n parts.push(`**${name}:** *(error)*\\n\\n${msg.content}`);\n } else {\n parts.push(`**${name}:**\\n\\n${msg.content}`);\n }\n }\n }\n\n return parts.join(\"\\n\\n---\\n\\n\") + \"\\n\";\n}\n","import { execSync } from \"node:child_process\";\n\nexport function copyToClipboard(text: string): void {\n const platform = process.platform;\n\n let cmd: string;\n if (platform === \"darwin\") {\n cmd = \"pbcopy\";\n } else if (platform === \"win32\") {\n cmd = \"clip\";\n } else {\n // Linux — try xclip first, fall back to xsel\n let hasXclip = false;\n let hasXsel = false;\n try {\n execSync(\"which xclip\", { stdio: \"ignore\" });\n hasXclip = true;\n } catch {}\n if (!hasXclip) {\n try {\n execSync(\"which xsel\", { stdio: \"ignore\" });\n hasXsel = true;\n } catch {}\n }\n\n if (hasXclip) {\n cmd = \"xclip -selection clipboard\";\n } else if (hasXsel) {\n cmd = \"xsel --clipboard --input\";\n } else {\n throw new Error(\n \"Clipboard requires xclip or xsel. Install one with: sudo apt install xclip\"\n );\n }\n }\n\n try {\n execSync(cmd, { input: text, stdio: [\"pipe\", \"ignore\", \"ignore\"] });\n } catch {\n throw new Error(\n `Failed to copy to clipboard using \"${cmd.split(\" \")[0]}\". Check that it is installed and working.`\n );\n }\n}\n","import Database from \"better-sqlite3\";\nimport { join } from \"node:path\";\nimport { getConfigDir, ensureConfigDir } from \"../config.js\";\n\nlet db: Database.Database | null = null;\n\nexport function getDbPath(): string {\n return join(getConfigDir(), \"tagteam.db\");\n}\n\nexport function getDb(): Database.Database {\n if (db) return db;\n\n ensureConfigDir();\n db = new Database(getDbPath());\n db.pragma(\"journal_mode = WAL\");\n db.pragma(\"foreign_keys = ON\");\n\n initSchema(db);\n return db;\n}\n\nfunction initSchema(db: Database.Database): void {\n db.exec(`\n CREATE TABLE IF NOT EXISTS sessions (\n id TEXT PRIMARY KEY,\n title TEXT,\n working_dir TEXT NOT NULL,\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n updated_at TEXT NOT NULL DEFAULT (datetime('now')),\n status TEXT NOT NULL DEFAULT 'active'\n );\n\n CREATE TABLE IF NOT EXISTS messages (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n session_id TEXT NOT NULL REFERENCES sessions(id),\n role TEXT NOT NULL,\n content TEXT NOT NULL,\n round INTEGER NOT NULL DEFAULT 0,\n duration_ms INTEGER,\n metadata TEXT,\n created_at TEXT NOT NULL DEFAULT (datetime('now'))\n );\n\n CREATE INDEX IF NOT EXISTS idx_messages_session ON messages(session_id, id);\n `);\n}\n\nexport function closeDb(): void {\n if (db) {\n db.close();\n db = null;\n }\n}\n","import { getDb } from \"./index.js\";\n\nexport interface Session {\n id: string;\n title: string | null;\n working_dir: string;\n created_at: string;\n updated_at: string;\n status: string;\n}\n\nexport function createSession(\n id: string,\n workingDir: string\n): Session {\n const db = getDb();\n db.prepare(\n `INSERT INTO sessions (id, working_dir) VALUES (?, ?)`\n ).run(id, workingDir);\n\n return getSession(id)!;\n}\n\nexport function getSession(id: string): Session | undefined {\n const db = getDb();\n return db.prepare(`SELECT * FROM sessions WHERE id = ?`).get(id) as\n | Session\n | undefined;\n}\n\nexport function getSessionByPrefix(prefix: string): Session | undefined {\n const db = getDb();\n return db\n .prepare(`SELECT * FROM sessions WHERE id LIKE ? ORDER BY updated_at DESC LIMIT 1`)\n .get(`${prefix}%`) as Session | undefined;\n}\n\nexport function getMostRecentSession(): Session | undefined {\n const db = getDb();\n return db\n .prepare(\n `SELECT * FROM sessions WHERE status = 'active' ORDER BY updated_at DESC LIMIT 1`\n )\n .get() as Session | undefined;\n}\n\nexport function listSessions(limit = 20): Session[] {\n const db = getDb();\n return db\n .prepare(`SELECT * FROM sessions ORDER BY updated_at DESC LIMIT ?`)\n .all(limit) as Session[];\n}\n\nexport function updateSessionTitle(id: string, title: string): void {\n const db = getDb();\n db.prepare(\n `UPDATE sessions SET title = ?, updated_at = datetime('now') WHERE id = ?`\n ).run(title, id);\n}\n\nexport function touchSession(id: string): void {\n const db = getDb();\n db.prepare(`UPDATE sessions SET updated_at = datetime('now') WHERE id = ?`).run(\n id\n );\n}\n","import { getDb } from \"./index.js\";\n\nexport interface Message {\n id: number;\n session_id: string;\n role: string;\n content: string;\n round: number;\n duration_ms: number | null;\n metadata: string | null;\n created_at: string;\n}\n\nexport function insertMessage(params: {\n sessionId: string;\n role: string;\n content: string;\n round: number;\n durationMs?: number;\n metadata?: Record<string, unknown>;\n}): Message {\n const db = getDb();\n const result = db\n .prepare(\n `INSERT INTO messages (session_id, role, content, round, duration_ms, metadata)\n VALUES (?, ?, ?, ?, ?, ?)`\n )\n .run(\n params.sessionId,\n params.role,\n params.content,\n params.round,\n params.durationMs ?? null,\n params.metadata ? JSON.stringify(params.metadata) : null\n );\n\n return db\n .prepare(`SELECT * FROM messages WHERE id = ?`)\n .get(result.lastInsertRowid) as Message;\n}\n\nexport function getMessages(sessionId: string): Message[] {\n const db = getDb();\n return db\n .prepare(`SELECT * FROM messages WHERE session_id = ? ORDER BY id`)\n .all(sessionId) as Message[];\n}\n\nexport function deleteMessagesFromRound(\n sessionId: string,\n fromRound: number\n): void {\n const db = getDb();\n db.prepare(\n `DELETE FROM messages WHERE session_id = ? AND round >= ?`\n ).run(sessionId, fromRound);\n}","import type { AgentName } from \"./agents/types.js\";\nimport { getAgent, isValidAgentName } from \"./agents/registry.js\";\n\nfunction otherAgent(agent: AgentName, pair: [AgentName, AgentName]): string {\n const other = pair[0] === agent ? pair[1] : pair[0];\n const desc = getAgent(other);\n return `${desc.displayName} (${desc.org})`;\n}\n\nexport function collaborationPrompt(agent: AgentName, pair: [AgentName, AgentName]): string {\n return `You are in a collaborative session with ${otherAgent(agent, pair)}. You'll both respond to the user's prompt independently, then see each other's responses. In discussion rounds: highlight where you agree, constructively address disagreements, and build on each other's ideas. Be concise - avoid repeating what was already said.`;\n}\n\nexport function discussionPrompt(\n agent: AgentName,\n conversationHistory: string,\n pair: [AgentName, AgentName]\n): string {\n return `${collaborationPrompt(agent, pair)}\n\nHere is the conversation so far:\n\n${conversationHistory}\n\nNow provide your response for this discussion round. Build on what was said, highlight agreements, and address any disagreements constructively. Be concise.`;\n}\n\nexport function debatePrompt(agent: AgentName, pair: [AgentName, AgentName]): string {\n const other = otherAgent(agent, pair);\n return `You are in a structured debate with ${other}. You'll both respond to the user's prompt, then see each other's responses and discuss.\n\nYour goal is to reach consensus through constructive discussion. In each round:\n- Address specific points of agreement and disagreement\n- Refine your position based on valid arguments from ${other}\n- Be concise — don't repeat points already established\n\nWhen you believe you and ${other} have reached substantial agreement on the key points, end your response with [CONSENSUS] on its own line. Only do this when you genuinely agree — don't force premature consensus.`;\n}\n\nexport function debateRoundPrompt(\n agent: AgentName,\n conversationHistory: string,\n pair: [AgentName, AgentName]\n): string {\n const other = otherAgent(agent, pair);\n return `${debatePrompt(agent, pair)}\n\nHere is the conversation so far:\n\n${conversationHistory}\n\nRespond to the latest round. If you agree with ${other}'s position on all key points, end with [CONSENSUS]. Otherwise, continue the discussion.`;\n}\n\nexport const CONSENSUS_MARKER = \"[CONSENSUS]\";\n\nexport function formatConversationHistory(\n messages: Array<{ role: string; agent?: AgentName; content: string }>\n): string {\n return messages\n .map((m) => {\n let label: string;\n if (m.role === \"user\") {\n label = \"User\";\n } else if (isValidAgentName(m.role)) {\n label = getAgent(m.role).displayName;\n } else if (m.agent && isValidAgentName(m.agent)) {\n label = getAgent(m.agent).displayName;\n } else {\n label = m.role;\n }\n return `[${label}]: ${m.content}`;\n })\n .join(\"\\n\\n\");\n}\n","import React, { useState } from \"react\";\nimport { render, Box, Text, useApp, useInput } from \"ink\";\nimport TextInput from \"ink-text-input\";\nimport { loadConfig, setConfigValue } from \"./config.js\";\nimport type { TagTeamConfig } from \"./config.js\";\nimport { validateAgentPair } from \"./agents/registry.js\";\n\ninterface ConfigField {\n key: string;\n label: string;\n get: (c: TagTeamConfig) => string;\n type: \"string\" | \"number\";\n validate?: (value: string) => string | null;\n}\n\nconst CONFIG_FIELDS: ConfigField[] = [\n {\n key: \"agents\",\n label: \"Agent pair\",\n get: (c) => c.agents.join(\", \"),\n type: \"string\",\n validate: (value) => {\n try {\n const names = value.split(\",\").map((s) => s.trim());\n validateAgentPair(names);\n return null;\n } catch (e: any) {\n return e.message;\n }\n },\n },\n {\n key: \"claude.model\",\n label: \"Claude model\",\n get: (c) => c.claude.model,\n type: \"string\",\n },\n {\n key: \"codex.model\",\n label: \"Codex model\",\n get: (c) => c.codex.model,\n type: \"string\",\n },\n {\n key: \"gemini.model\",\n label: \"Gemini model\",\n get: (c) => c.gemini.model,\n type: \"string\",\n },\n {\n key: \"discussion.max_rounds\",\n label: \"Discussion max rounds\",\n get: (c) => String(c.discussion.max_rounds),\n type: \"number\",\n },\n];\n\nconst LABEL_WIDTH = Math.max(...CONFIG_FIELDS.map((f) => f.label.length));\n\ntype EditMode = \"select\" | \"edit\";\n\ninterface InlineConfigEditorProps {\n isActive: boolean;\n onClose: () => void;\n}\n\nexport function InlineConfigEditor({ isActive, onClose }: InlineConfigEditorProps) {\n const [config, setConfig] = useState(() => loadConfig());\n const [selectedIndex, setSelectedIndex] = useState(0);\n const [mode, setMode] = useState<EditMode>(\"select\");\n const [editValue, setEditValue] = useState(\"\");\n const [savedMessage, setSavedMessage] = useState<string | null>(null);\n\n useInput(\n (input, key) => {\n if (key.upArrow) {\n setSavedMessage(null);\n setSelectedIndex((i) => (i > 0 ? i - 1 : CONFIG_FIELDS.length - 1));\n } else if (key.downArrow) {\n setSavedMessage(null);\n setSelectedIndex((i) => (i < CONFIG_FIELDS.length - 1 ? i + 1 : 0));\n } else if (key.return) {\n const field = CONFIG_FIELDS[selectedIndex];\n setEditValue(field.get(config));\n setSavedMessage(null);\n setMode(\"edit\");\n } else if (key.escape || input === \"q\") {\n onClose();\n }\n },\n { isActive: isActive && mode === \"select\" }\n );\n\n useInput(\n (_input, key) => {\n if (key.escape) {\n setMode(\"select\");\n }\n },\n { isActive: isActive && mode === \"edit\" }\n );\n\n const handleEditSubmit = (value: string) => {\n const field = CONFIG_FIELDS[selectedIndex];\n\n if (field.type === \"number\") {\n const n = Number(value);\n if (!Number.isInteger(n) || n < 1) {\n setSavedMessage(\"Error: must be a positive integer\");\n setMode(\"select\");\n return;\n }\n }\n\n if (field.validate) {\n const error = field.validate(value);\n if (error) {\n setSavedMessage(`Error: ${error}`);\n setMode(\"select\");\n return;\n }\n }\n\n try {\n const updated = setConfigValue(field.key, value);\n setConfig(updated);\n setSavedMessage(`Saved ${field.key} = ${value}`);\n } catch (e: any) {\n setSavedMessage(`Error: ${e.message}`);\n }\n\n setMode(\"select\");\n };\n\n return (\n <Box flexDirection=\"column\">\n <Box marginBottom={1}>\n <Text bold>Configuration</Text>\n <Text dimColor> ── edit values inline</Text>\n </Box>\n\n {CONFIG_FIELDS.map((field, i) => {\n const selected = i === selectedIndex;\n const pointer = selected ? \"> \" : \" \";\n const currentValue = field.get(config);\n\n return (\n <Box key={field.key} marginLeft={1}>\n <Text color={selected ? \"cyan\" : undefined} bold={selected}>\n {pointer}\n {field.label.padEnd(LABEL_WIDTH)}\n </Text>\n <Text dimColor> = </Text>\n {mode === \"edit\" && selected ? (\n <TextInput\n value={editValue}\n onChange={setEditValue}\n onSubmit={handleEditSubmit}\n showCursor\n />\n ) : (\n <Text color=\"white\">{currentValue}</Text>\n )}\n </Box>\n );\n })}\n\n {savedMessage && (\n <Box marginTop={1} marginLeft={1}>\n <Text color={savedMessage.startsWith(\"Error\") ? \"red\" : \"green\"}>\n {savedMessage}\n </Text>\n </Box>\n )}\n\n <Box marginTop={1} marginLeft={1}>\n <Text dimColor>\n {mode === \"edit\"\n ? \"Enter save Esc cancel\"\n : \"↑↓ navigate Enter edit Esc/q quit\"}\n </Text>\n </Box>\n </Box>\n );\n}\n\n// Standalone entrypoint for `tagteam config edit`\nfunction StandaloneConfigEditor() {\n const { exit } = useApp();\n return <InlineConfigEditor isActive={true} onClose={exit} />;\n}\n\nexport function startConfigEditor() {\n return render(<StandaloneConfigEditor />);\n}\n"],"mappings":"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","names":["execSync","useState","render","Box","Text","useApp","useInput","TextInput","spawn","createInterface","spawn","join","join","db","db","db","jsx","jsxs","Text","Box","useState","TextInput","showTranscript","useApp","useInput","render","execSync","session","dbMessages","transcript","instance"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/config.ts","../src/ui.tsx","../src/agents/claude.ts","../src/agents/codex.ts","../src/agents/gemini.ts","../src/agents/registry.ts","../src/format.ts","../src/clipboard.ts","../src/db/index.ts","../src/db/sessions.ts","../src/db/messages.ts","../src/prompts.ts","../src/config-editor.tsx"],"sourcesContent":["import { Command } from \"commander\";\nimport { execSync } from \"node:child_process\";\nimport chalk from \"chalk\";\nimport { loadConfig, setConfigValue } from \"./config.js\";\nimport { startApp, showTranscript, showTranscriptMarkdown, showSessionList } from \"./ui.js\";\nimport { startConfigEditor } from \"./config-editor.js\";\nimport type { AgentName } from \"./agents/types.js\";\nimport { getAgent, validateAgentPair } from \"./agents/registry.js\";\nimport {\n getMostRecentSession,\n getSession,\n getSessionByPrefix,\n listSessions,\n deleteSession,\n deleteAllSessions,\n} from \"./db/sessions.js\";\nimport { getMessages } from \"./db/messages.js\";\nimport { closeDb } from \"./db/index.js\";\n\nprocess.on(\"SIGTERM\", () => { closeDb(); process.exit(0); });\nprocess.on(\"SIGINT\", () => { closeDb(); process.exit(0); });\n\nfunction checkCli(name: string, installUrl: string): boolean {\n try {\n execSync(`${name} --version`, { stdio: \"ignore\" });\n return true;\n } catch {\n console.error(\n chalk.red(`\"${name}\" not found. Install it from: ${installUrl}`)\n );\n return false;\n }\n}\n\nfunction preflight(pair: [AgentName, AgentName]): void {\n let allFound = true;\n for (const agent of pair) {\n const descriptor = getAgent(agent);\n if (!checkCli(descriptor.cliBinary, descriptor.installUrl)) {\n allFound = false;\n }\n }\n if (!allFound) {\n process.exit(1);\n }\n}\n\nfunction resolveAgentPair(opts: any, config: ReturnType<typeof loadConfig>): [AgentName, AgentName] {\n if (opts.agents) {\n const names = opts.agents.split(\",\").map((s: string) => s.trim());\n return validateAgentPair(names);\n }\n return validateAgentPair(config.agents);\n}\n\nfunction resolveAgentModels(\n pair: [AgentName, AgentName],\n opts: any,\n config: ReturnType<typeof loadConfig>\n): Record<AgentName, string> {\n return {\n claude: opts.claudeModel ?? config.claude.model,\n codex: opts.codexModel ?? config.codex.model,\n gemini: opts.geminiModel ?? config.gemini.model,\n };\n}\n\nconst program = new Command();\n\nprogram\n .name(\"tagteam\")\n .description(\"Tag Team - Orchestrate AI agents collaboratively\")\n .version(\"0.3.0\")\n .option(\"--agents <pair>\", \"Agent pair to use (comma-separated, e.g. claude,gemini)\")\n .option(\"--claude-model <model>\", \"Claude model to use\")\n .option(\"--codex-model <model>\", \"Codex model to use\")\n .option(\"--gemini-model <model>\", \"Gemini model to use\")\n .argument(\"[prompt...]\", \"Prompt to send to both agents\")\n .action(async (promptParts: string[], opts) => {\n const config = loadConfig();\n const pair = resolveAgentPair(opts, config);\n preflight(pair);\n const prompt = promptParts.join(\" \") || undefined;\n\n const instance = startApp({\n initialPrompt: prompt,\n agents: pair,\n agentModels: resolveAgentModels(pair, opts, config),\n config,\n });\n\n await instance.waitUntilExit();\n });\n\n// Discuss - auto-loop until consensus\nprogram\n .command(\"discuss\")\n .description(\"Have agents discuss a topic until they reach consensus\")\n .argument(\"<prompt...>\", \"Topic to discuss\")\n .action(async (promptParts: string[]) => {\n const config = loadConfig();\n const parentOpts = program.opts();\n const pair = resolveAgentPair(parentOpts, config);\n preflight(pair);\n const prompt = promptParts.join(\" \");\n\n const instance = startApp({\n initialPrompt: prompt,\n agents: pair,\n agentModels: resolveAgentModels(pair, parentOpts, config),\n config,\n discuss: true,\n });\n\n await instance.waitUntilExit();\n });\n\n// Continue most recent session\nprogram\n .command(\"continue\")\n .description(\"Resume the most recent session\")\n .action(async () => {\n const config = loadConfig();\n const parentOpts = program.opts();\n const pair = resolveAgentPair(parentOpts, config);\n preflight(pair);\n const session = getMostRecentSession();\n\n if (!session) {\n console.log(chalk.red(\" No active sessions found.\"));\n process.exit(1);\n }\n\n const dbMessages = getMessages(session.id);\n const transcript = dbMessages.map((m) => ({\n role: m.role,\n content: m.content,\n round: m.round,\n }));\n\n const instance = startApp({\n sessionId: session.id,\n agents: pair,\n agentModels: resolveAgentModels(pair, parentOpts, config),\n config,\n showTranscript: transcript,\n });\n\n await instance.waitUntilExit();\n });\n\n// Resume a specific session\nprogram\n .command(\"resume [id]\")\n .description(\"Resume a session by ID, or pick interactively\")\n .action(async (id: string | undefined) => {\n const config = loadConfig();\n const parentOpts = program.opts();\n const pair = resolveAgentPair(parentOpts, config);\n preflight(pair);\n\n if (!id) {\n const sessions = listSessions(20);\n if (sessions.length === 0) {\n console.log(chalk.red(\" No sessions found.\"));\n process.exit(1);\n }\n\n console.log(chalk.bold(\"\\n Recent sessions:\\n\"));\n sessions.forEach((s, i) => {\n const sid = chalk.cyan(s.id.slice(0, 7));\n const title = s.title || chalk.dim(\"(untitled)\");\n const date = chalk.dim(s.updated_at);\n console.log(` ${chalk.dim(`${i + 1}.`)} ${sid} ${title} ${date}`);\n });\n console.log();\n\n const readline = await import(\"node:readline\");\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n return new Promise<void>((resolve) => {\n rl.question(\" Select session number: \", async (input) => {\n rl.close();\n const num = parseInt(input.trim(), 10);\n if (isNaN(num) || num < 1 || num > sessions.length) {\n console.log(chalk.red(\" Invalid selection.\"));\n closeDb();\n resolve();\n return;\n }\n\n const session = sessions[num - 1];\n const dbMessages = getMessages(session.id);\n const transcript = dbMessages.map((m) => ({\n role: m.role,\n content: m.content,\n round: m.round,\n }));\n\n const instance = startApp({\n sessionId: session.id,\n agents: pair,\n agentModels: resolveAgentModels(pair, parentOpts, config),\n config,\n showTranscript: transcript,\n });\n\n await instance.waitUntilExit();\n resolve();\n });\n });\n }\n\n const session = getSession(id) || getSessionByPrefix(id);\n if (!session) {\n console.log(chalk.red(` Session not found: ${id}`));\n process.exit(1);\n }\n\n const dbMessages = getMessages(session.id);\n const transcript = dbMessages.map((m) => ({\n role: m.role,\n content: m.content,\n round: m.round,\n }));\n\n const instance = startApp({\n sessionId: session.id,\n agents: pair,\n agentModels: resolveAgentModels(pair, parentOpts, config),\n config,\n showTranscript: transcript,\n });\n\n await instance.waitUntilExit();\n });\n\n// History\nconst historyCmd = program\n .command(\"history\")\n .description(\"List, remove, or clear sessions\")\n .option(\"-n, --limit <n>\", \"Number of sessions to show\", parseInt, 20)\n .action((opts) => {\n const sessions = listSessions(opts.limit);\n console.log(chalk.bold(\"\\n Recent sessions:\\n\"));\n showSessionList(sessions);\n console.log();\n closeDb();\n });\n\nhistoryCmd\n .command(\"rm <id>\")\n .description(\"Delete a session by ID or prefix\")\n .action((id: string) => {\n const session = getSession(id) || getSessionByPrefix(id);\n if (!session) {\n console.log(chalk.red(` Session not found: ${id}`));\n process.exit(1);\n }\n deleteSession(session.id);\n const sid = session.id.slice(0, 7);\n const title = session.title || \"(untitled)\";\n console.log(chalk.green(` Deleted session ${sid} — ${title}`));\n closeDb();\n });\n\nhistoryCmd\n .command(\"clear\")\n .description(\"Delete all sessions\")\n .action(async () => {\n const sessions = listSessions();\n if (sessions.length === 0) {\n console.log(chalk.yellow(\" No sessions to delete.\"));\n closeDb();\n return;\n }\n\n const readline = await import(\"node:readline\");\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n rl.question(\n chalk.yellow(` Delete all ${sessions.length} session(s)? [y/N] `),\n (answer) => {\n rl.close();\n if (answer.trim().toLowerCase() === \"y\") {\n deleteAllSessions();\n console.log(chalk.green(` Deleted ${sessions.length} session(s).`));\n } else {\n console.log(\" Cancelled.\");\n }\n closeDb();\n }\n );\n });\n\n// Show transcript\nprogram\n .command(\"show <id>\")\n .description(\"Print full transcript for a session\")\n .option(\"-m, --markdown\", \"Output as GitHub-compatible markdown\")\n .action((id: string, opts: { markdown?: boolean }) => {\n const session = getSession(id) || getSessionByPrefix(id);\n if (!session) {\n console.log(chalk.red(` Session not found: ${id}`));\n process.exit(1);\n }\n\n if (opts.markdown) {\n process.stdout.write(showTranscriptMarkdown(session.id));\n } else {\n showTranscript(session.id);\n }\n closeDb();\n });\n\n// Config commands\nconst configCmd = program\n .command(\"config\")\n .description(\"Manage configuration\")\n .action(async () => {\n const instance = startConfigEditor();\n await instance.waitUntilExit();\n });\n\nconfigCmd\n .command(\"edit\")\n .description(\"Interactively edit configuration\")\n .action(async () => {\n const instance = startConfigEditor();\n await instance.waitUntilExit();\n });\n\nconfigCmd\n .command(\"show\")\n .description(\"Show current configuration\")\n .action(() => {\n const config = loadConfig();\n console.log(chalk.bold(\"\\n Configuration:\\n\"));\n console.log(\n chalk.dim(\" agents = \") + chalk.white(config.agents.join(\", \"))\n );\n console.log(\n chalk.dim(\" claude.model = \") + chalk.white(config.claude.model)\n );\n console.log(\n chalk.dim(\" codex.model = \") + chalk.white(config.codex.model)\n );\n console.log(\n chalk.dim(\" gemini.model = \") + chalk.white(config.gemini.model)\n );\n console.log(\n chalk.dim(\" discussion.max_rounds = \") + chalk.white(String(config.discussion.max_rounds))\n );\n console.log();\n });\n\nconfigCmd\n .command(\"set <key> <value>\")\n .description(\"Set a configuration value\")\n .action((key: string, value: string) => {\n try {\n setConfigValue(key, value);\n console.log(chalk.green(` Set ${key} = ${value}`));\n } catch (e: any) {\n console.log(chalk.red(` ${e.message}`));\n process.exit(1);\n }\n });\n\nprogram.parseAsync();\n","import { readFileSync, writeFileSync, mkdirSync, existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport { parse, stringify } from \"smol-toml\";\n\nexport interface TagTeamConfig {\n agents: [string, string];\n claude: {\n model: string;\n };\n codex: {\n model: string;\n };\n gemini: {\n model: string;\n };\n discussion: {\n max_rounds: number;\n };\n}\n\nconst DEFAULT_CONFIG: TagTeamConfig = {\n agents: [\"claude\", \"codex\"],\n claude: {\n model: \"sonnet\",\n },\n codex: {\n model: \"gpt-5.3-codex\",\n },\n gemini: {\n model: \"gemini-2.5-pro\",\n },\n discussion: {\n max_rounds: 10,\n },\n};\n\nexport function getConfigDir(): string {\n if (process.platform === \"win32\") {\n return join(\n process.env.APPDATA || join(homedir(), \"AppData\", \"Roaming\"),\n \"tagteam\"\n );\n }\n return join(homedir(), \".tagteam\");\n}\n\nexport function getConfigPath(): string {\n return join(getConfigDir(), \"config.toml\");\n}\n\nexport function ensureConfigDir(): void {\n const dir = getConfigDir();\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n}\n\nexport function loadConfig(): TagTeamConfig {\n const configPath = getConfigPath();\n\n if (!existsSync(configPath)) {\n return { ...DEFAULT_CONFIG };\n }\n\n try {\n const raw = readFileSync(configPath, \"utf-8\");\n const parsed = parse(raw) as any;\n return {\n agents: Array.isArray(parsed.agents) && parsed.agents.length === 2\n ? parsed.agents as [string, string]\n : [...DEFAULT_CONFIG.agents],\n claude: { ...DEFAULT_CONFIG.claude, ...parsed.claude },\n codex: { ...DEFAULT_CONFIG.codex, ...parsed.codex },\n gemini: { ...DEFAULT_CONFIG.gemini, ...parsed.gemini },\n discussion: { ...DEFAULT_CONFIG.discussion, ...parsed.discussion },\n };\n } catch {\n return { ...DEFAULT_CONFIG };\n }\n}\n\nexport function saveConfig(config: TagTeamConfig): void {\n ensureConfigDir();\n const configPath = getConfigPath();\n writeFileSync(configPath, stringify(config as any), \"utf-8\");\n}\n\nexport function setConfigValue(\n key: string,\n value: string\n): TagTeamConfig {\n const config = loadConfig();\n const parts = key.split(\".\");\n\n if (parts.length === 1) {\n switch (parts[0]) {\n case \"agents\":\n config.agents = value.split(\",\").map((s) => s.trim()) as [string, string];\n break;\n case \"claude_model\":\n config.claude.model = value;\n break;\n case \"codex_model\":\n config.codex.model = value;\n break;\n case \"gemini_model\":\n config.gemini.model = value;\n break;\n case \"discussion_max_rounds\":\n config.discussion.max_rounds = Number(value);\n break;\n default:\n throw new Error(`Unknown config key: ${key}`);\n }\n } else if (parts.length === 2) {\n const [section, field] = parts;\n if (section === \"claude\" && field === \"model\") {\n config.claude.model = value;\n } else if (section === \"codex\" && field === \"model\") {\n config.codex.model = value;\n } else if (section === \"gemini\" && field === \"model\") {\n config.gemini.model = value;\n } else if (section === \"discussion\" && field === \"max_rounds\") {\n config.discussion.max_rounds = Number(value);\n } else {\n throw new Error(`Unknown config key: ${key}`);\n }\n } else {\n throw new Error(`Invalid config key format: ${key}`);\n }\n\n saveConfig(config);\n return config;\n}\n","import React, { useState, useEffect, useCallback, useRef } from \"react\";\nimport { render, Box, Text, useApp, useInput } from \"ink\";\nimport TextInput from \"ink-text-input\";\nimport Spinner from \"ink-spinner\";\nimport { marked } from \"marked\";\nimport { markedTerminal } from \"marked-terminal\";\nimport { nanoid } from \"nanoid\";\nimport type { AgentName, AgentResponse } from \"./agents/types.js\";\nimport { getAgent, getAllAgentNames, isValidAgentName } from \"./agents/registry.js\";\nimport { formatAsMarkdown } from \"./format.js\";\nimport { copyToClipboard } from \"./clipboard.js\";\nimport { createSession, touchSession, updateSessionTitle } from \"./db/sessions.js\";\nimport { insertMessage, getMessages, deleteMessagesFromRound } from \"./db/messages.js\";\nimport { closeDb } from \"./db/index.js\";\nimport {\n collaborationPrompt,\n discussionPrompt,\n debatePrompt,\n debateRoundPrompt,\n directPrompt,\n CONSENSUS_MARKER,\n formatConversationHistory,\n} from \"./prompts.js\";\nimport { loadConfig } from \"./config.js\";\nimport type { TagTeamConfig } from \"./config.js\";\nimport { validateAgentPair } from \"./agents/registry.js\";\nimport { InlineConfigEditor } from \"./config-editor.js\";\n\nmarked.use(markedTerminal() as any);\n\n// --- Types ---\n\ninterface Message {\n role: string;\n content: string;\n round: number;\n error?: boolean;\n}\n\nexport interface AppProps {\n initialPrompt?: string;\n sessionId?: string;\n agents: [AgentName, AgentName];\n agentModels: Record<AgentName, string>;\n config: TagTeamConfig;\n showTranscript?: Message[];\n discuss?: boolean;\n}\n\ntype AppState = \"input\" | \"running\" | \"done\" | \"config\";\ntype Target = \"both\" | AgentName | [AgentName, AgentName];\n\ninterface ParsedInput {\n target: Target;\n prompt: string;\n discuss: boolean;\n}\n\nconst PAIR_SEPARATORS = /^(\\w+)\\s*(?:and|&|\\/|,)\\s*(\\w+)[\\s,]\\s*/i;\n\nfunction tryParsePair(text: string): { pair: [AgentName, AgentName]; rest: string } | null {\n const match = text.toLowerCase().match(PAIR_SEPARATORS);\n if (!match) return null;\n const [fullMatch, first, second] = match;\n if (isValidAgentName(first) && isValidAgentName(second) && first !== second) {\n return { pair: [first, second], rest: text.slice(fullMatch.length).trim() };\n }\n return null;\n}\n\nfunction parseInput(input: string): ParsedInput {\n const lower = input.toLowerCase();\n if (lower.startsWith(\"discuss \")) {\n const rest = input.slice(8).trim();\n // Check for \"discuss gemini and codex ...\"\n const adHoc = tryParsePair(rest);\n if (adHoc) {\n return { target: adHoc.pair, prompt: adHoc.rest, discuss: true };\n }\n return { target: \"both\", prompt: rest, discuss: true };\n }\n // Check for ad-hoc pair: \"gemini and codex ...\", \"gemini/codex ...\", etc.\n const adHoc = tryParsePair(input);\n if (adHoc) {\n // \"gemini and codex discuss ...\" — natural word order\n const adHocLower = adHoc.rest.toLowerCase();\n if (adHocLower.startsWith(\"discuss \")) {\n return { target: adHoc.pair, prompt: adHoc.rest.slice(8).trim(), discuss: true };\n }\n return { target: adHoc.pair, prompt: adHoc.rest, discuss: false };\n }\n // Check for single agent prefix\n for (const agent of getAllAgentNames()) {\n if (lower.startsWith(`${agent} `) || lower.startsWith(`${agent}, `)) {\n return { target: agent, prompt: input.slice(input.indexOf(\" \") + 1).trim(), discuss: false };\n }\n }\n return { target: \"both\", prompt: input, discuss: false };\n}\n\n// --- Components ---\n\nfunction RenderedMarkdown({ text }: { text: string }) {\n const rendered = (marked.parse(text) as string).trimEnd();\n return <Text>{rendered}</Text>;\n}\n\nfunction AgentResponseBlock({\n agent,\n content,\n error,\n}: {\n agent: AgentName;\n content: string;\n error?: boolean;\n}) {\n const descriptor = getAgent(agent);\n\n if (error) {\n return (\n <Box flexDirection=\"column\" marginLeft={1} marginBottom={1}>\n <Text color=\"red\" bold>\n {descriptor.displayName} error:\n </Text>\n <Box marginLeft={1}>\n <Text color=\"red\">{content}</Text>\n </Box>\n </Box>\n );\n }\n\n return (\n <Box flexDirection=\"column\" marginLeft={1} marginBottom={1}>\n <Text color={descriptor.color} bold>\n {descriptor.displayName}:\n </Text>\n <Box marginLeft={1}>\n <RenderedMarkdown text={content} />\n </Box>\n </Box>\n );\n}\n\nfunction Header({ sessionId }: { sessionId: string }) {\n return (\n <Box marginBottom={1}>\n <Text dimColor>{\"── \"}</Text>\n <Text bold>Tag Team</Text>\n <Text dimColor>{\" ── session \"}</Text>\n <Text color=\"cyan\">{sessionId.slice(0, 7)}</Text>\n <Text dimColor>{\" \" + \"─\".repeat(35)}</Text>\n </Box>\n );\n}\n\nfunction QuickHelp() {\n const col = 38;\n const examples = [\n [\"ask anything\", \"sends to both agents\"],\n [\"gemini explain this\", \"sends to one agent\"],\n [\"discuss best approach\", \"multi-round debate\"],\n [\"gemini and codex discuss review app\", \"pick agents + debate\"],\n ];\n return (\n <Box flexDirection=\"column\" marginLeft={2} marginBottom={1}>\n {examples.map(([cmd, desc]) => (\n <Text key={cmd} dimColor>{cmd!.padEnd(col)}{\"→ \"}{desc}</Text>\n ))}\n <Text dimColor>{\"/help for more\"}</Text>\n </Box>\n );\n}\n\nfunction UserMessage({ content }: { content: string }) {\n return (\n <Box marginLeft={1} marginBottom={1}>\n <Text bold color=\"white\">\n You:{\" \"}\n </Text>\n <Text>{content}</Text>\n </Box>\n );\n}\n\nfunction ThinkingIndicator({ agent }: { agent: AgentName }) {\n const descriptor = getAgent(agent);\n return (\n <Box marginLeft={1}>\n <Text color={descriptor.color}>\n <Spinner type=\"dots\" />\n </Text>\n <Text color={descriptor.color}> {descriptor.displayName} is thinking...</Text>\n </Box>\n );\n}\n\nfunction DiscussionStatus({ round, maxRounds }: { round: number; maxRounds: number }) {\n return (\n <Box marginLeft={1} marginBottom={1}>\n <Text color=\"yellow\" bold>\n Discussion round {round}/{maxRounds}\n </Text>\n </Box>\n );\n}\n\nfunction ConsensusReached() {\n return (\n <Box marginLeft={1} marginBottom={1}>\n <Text color=\"green\" bold>\n Consensus reached.\n </Text>\n </Box>\n );\n}\n\nfunction PromptInput({\n onSubmit,\n}: {\n onSubmit: (value: string) => void;\n}) {\n const [value, setValue] = useState(\"\");\n\n const handleSubmit = useCallback(\n (submitted: string) => {\n if (submitted.trim()) {\n onSubmit(submitted.trim());\n setValue(\"\");\n }\n },\n [onSubmit]\n );\n\n return (\n <Box marginLeft={1}>\n <Text bold color=\"white\">\n {\"> \"}\n </Text>\n <TextInput\n value={value}\n onChange={setValue}\n onSubmit={handleSubmit}\n showCursor\n />\n </Box>\n );\n}\n\n// --- Main App ---\n\nfunction App({\n initialPrompt,\n sessionId: existingSessionId,\n agents: initialPair,\n agentModels: initialAgentModels,\n config: initialConfig,\n showTranscript,\n discuss: initialDiscuss,\n}: AppProps) {\n const { exit } = useApp();\n const [sessionId, setSessionId] = useState(() => existingSessionId ?? nanoid(12));\n const [messages, setMessages] = useState<Message[]>(showTranscript ?? []);\n const [state, setState] = useState<AppState>(\n initialPrompt ? \"running\" : \"input\"\n );\n const [pair, setPair] = useState<[AgentName, AgentName]>(initialPair);\n const [agentModels, setAgentModels] = useState<Record<AgentName, string>>(initialAgentModels);\n const [config, setConfig] = useState<TagTeamConfig>(initialConfig);\n const [thinkingAgents, setThinkingAgents] = useState<AgentName[]>([]);\n const [discussionRound, setDiscussionRound] = useState(0);\n const [consensusReached, setConsensusReached] = useState(false);\n const [statusMessage, setStatusMessage] = useState<string | null>(null);\n const [roundNum, setRoundNum] = useState(() => {\n if (showTranscript && showTranscript.length > 0) {\n return Math.max(...showTranscript.map((m) => m.round)) + 1;\n }\n return 0;\n });\n\n const sessionCreatedRef = useRef(!!existingSessionId);\n const ensureSession = (id: string) => {\n if (!sessionCreatedRef.current) {\n createSession(id, process.cwd());\n sessionCreatedRef.current = true;\n }\n };\n\n // Handle initial prompt\n useEffect(() => {\n if (initialPrompt && state === \"running\") {\n if (initialDiscuss) {\n runDiscussion(initialPrompt);\n } else {\n runRound(initialPrompt);\n }\n }\n }, []);\n\n const abortRef = useRef<AbortController | null>(null);\n const runningRoundRef = useRef<number | null>(null);\n\n // Ctrl+C and Escape handling\n useInput((input, key) => {\n if (key.ctrl && input === \"c\") {\n abortRef.current?.abort();\n closeDb();\n exit();\n }\n if (key.escape && state === \"running\") {\n abortRef.current?.abort();\n abortRef.current = null;\n\n // Remove the user prompt and any partial results from DB and state\n if (runningRoundRef.current !== null) {\n deleteMessagesFromRound(sessionId, runningRoundRef.current);\n const fromRound = runningRoundRef.current;\n setMessages((prev) => prev.filter((m) => m.round < fromRound));\n runningRoundRef.current = null;\n }\n\n setThinkingAgents([]);\n setDiscussionRound(0);\n setStatusMessage(\"Interrupted.\");\n setState(\"input\");\n }\n });\n\n // Run agents, save results, return new messages\n const runAgents = async (\n currentMessages: Message[],\n round: number,\n target: Target,\n promptOverride?: string,\n isDebate = false,\n ): Promise<Message[]> => {\n // Determine which agents to run\n const activeAgents: AgentName[] = Array.isArray(target)\n ? target\n : target === \"both\"\n ? [...pair]\n : [target];\n setThinkingAgents(activeAgents);\n\n const history = formatConversationHistory(\n currentMessages.map((m) => ({\n role: m.role,\n agent: isValidAgentName(m.role) ? m.role : undefined,\n content: m.content,\n }))\n );\n\n const cwd = process.cwd();\n const isFirstRound = round === 0 && !existingSessionId;\n\n const userPrompt = currentMessages[currentMessages.length - 1]?.content || \"\";\n const isSingleAgent = !Array.isArray(target) && target !== \"both\";\n // Use the ad-hoc pair for prompt context, or fall back to the configured pair\n const promptPair: [AgentName, AgentName] = Array.isArray(target) ? target : pair;\n\n const agentPrompt = (_agent: AgentName) => {\n if (promptOverride) return promptOverride;\n if (isSingleAgent) return userPrompt;\n if (isFirstRound) return userPrompt;\n return \"Provide your response for this round.\";\n };\n\n const agentSystemPrompt = (agent: AgentName) => {\n if (isSingleAgent) {\n return history ? directPrompt(history) : undefined;\n }\n if (isDebate) {\n if (isFirstRound) return debatePrompt(agent, promptPair);\n return debateRoundPrompt(agent, history, promptPair);\n }\n if (isFirstRound) return collaborationPrompt(agent, promptPair);\n return discussionPrompt(agent, history, promptPair);\n };\n\n const ac = new AbortController();\n abortRef.current = ac;\n\n const results: Array<{ agent: AgentName; result: PromiseSettledResult<AgentResponse> }> = [];\n const promises: Array<Promise<void>> = [];\n\n for (const agent of activeAgents) {\n const descriptor = getAgent(agent);\n promises.push(\n descriptor.run({\n prompt: agentPrompt(agent),\n systemPrompt: agentSystemPrompt(agent),\n model: agentModels[agent],\n cwd,\n signal: ac.signal,\n }).then(\n (value) => { results.push({ agent, result: { status: \"fulfilled\", value } }); },\n (reason) => { results.push({ agent, result: { status: \"rejected\", reason } }); }\n )\n );\n }\n\n await Promise.all(promises);\n abortRef.current = null;\n\n // If aborted, bail out — the Escape handler already reset UI state\n if (ac.signal.aborted) return [];\n\n setThinkingAgents([]);\n\n const newMessages: Message[] = [];\n\n for (const { agent, result } of results) {\n if (result.status === \"fulfilled\") {\n const resp = result.value;\n const msg: Message = {\n role: agent,\n content: resp.error || resp.text,\n round,\n error: !!resp.error,\n };\n newMessages.push(msg);\n insertMessage({\n sessionId,\n role: agent,\n content: resp.error || resp.text,\n round,\n durationMs: resp.durationMs,\n });\n } else {\n const errorMsg = result.reason?.message || \"Failed to run\";\n const msg: Message = {\n role: agent,\n content: errorMsg,\n round,\n error: true,\n };\n newMessages.push(msg);\n insertMessage({\n sessionId,\n role: agent,\n content: `[Error: ${errorMsg}]`,\n round,\n });\n }\n }\n\n return newMessages;\n };\n\n const runRound = async (rawInput: string) => {\n const { target, prompt, discuss } = parseInput(rawInput);\n\n if (discuss) {\n return runDiscussion(prompt, Array.isArray(target) ? target : undefined);\n }\n\n const currentRound = roundNum;\n runningRoundRef.current = currentRound;\n\n // Ensure session row exists and set title on first prompt\n ensureSession(sessionId);\n if (currentRound === 0) {\n const title = prompt.length > 60 ? prompt.slice(0, 57) + \"...\" : prompt;\n updateSessionTitle(sessionId, title);\n }\n\n // Add user message\n const userMsg: Message = {\n role: \"user\",\n content: rawInput,\n round: currentRound,\n };\n setMessages((prev) => [...prev, userMsg]);\n insertMessage({\n sessionId,\n role: \"user\",\n content: rawInput,\n round: currentRound,\n });\n\n const allMessages = [...messages, userMsg];\n const newMessages = await runAgents(allMessages, currentRound, target);\n\n // If aborted, the Escape handler already cleaned up\n if (newMessages.length === 0) return;\n\n setMessages((prev) => [...prev, ...newMessages]);\n setRoundNum(currentRound + 1);\n runningRoundRef.current = null;\n\n touchSession(sessionId);\n setState(\"input\");\n };\n\n const runDiscussion = async (prompt: string, adHocPair?: [AgentName, AgentName]) => {\n const discussionTarget: Target = adHocPair ?? \"both\";\n setConsensusReached(false);\n let currentRound = roundNum;\n runningRoundRef.current = currentRound;\n\n // Ensure session row exists and set title on first prompt\n ensureSession(sessionId);\n if (currentRound === 0) {\n const title = prompt.length > 60 ? prompt.slice(0, 57) + \"...\" : prompt;\n updateSessionTitle(sessionId, title);\n }\n\n // Add user message\n const userMsg: Message = {\n role: \"user\",\n content: `discuss ${prompt}`,\n round: currentRound,\n };\n setMessages((prev) => [...prev, userMsg]);\n insertMessage({\n sessionId,\n role: \"user\",\n content: `discuss ${prompt}`,\n round: currentRound,\n });\n\n let allMessages = [...messages, userMsg];\n\n for (let disc = 1; disc <= config.discussion.max_rounds; disc++) {\n setDiscussionRound(disc);\n\n const newMessages = await runAgents(\n allMessages,\n currentRound,\n discussionTarget,\n disc === 1 ? prompt : \"Provide your response for this round.\",\n true,\n );\n\n // If aborted, stop the discussion loop\n if (newMessages.length === 0) break;\n\n setMessages((prev) => [...prev, ...newMessages]);\n allMessages = [...allMessages, ...newMessages];\n currentRound++;\n\n // Check for consensus — both active agents must include the marker\n const activePair = adHocPair ?? pair;\n const consensusFlags = activePair.map((agent) => {\n const msg = newMessages.find((m) => m.role === agent && !m.error);\n return msg?.content.includes(CONSENSUS_MARKER) ?? false;\n });\n\n if (consensusFlags.every(Boolean)) {\n setConsensusReached(true);\n break;\n }\n }\n\n setRoundNum(currentRound);\n setDiscussionRound(0);\n runningRoundRef.current = null;\n touchSession(sessionId);\n setState(\"input\");\n };\n\n const handleSubmit = (value: string) => {\n setStatusMessage(null);\n\n if (value === \"/exit\") {\n closeDb();\n exit();\n return;\n }\n\n if (value === \"/help\") {\n setStatusMessage(\n [\n \"/help Show this help\",\n \"/config Edit configuration\",\n \"/new Start a new session\",\n \"/copy Copy conversation to clipboard\",\n \"/exit Exit the app\",\n \"\",\n \"Esc Interrupt running agents\",\n ].join(\"\\n\")\n );\n return;\n }\n\n if (value === \"/config\") {\n setState(\"config\");\n return;\n }\n\n if (value === \"/new\") {\n const newId = nanoid(12);\n sessionCreatedRef.current = false;\n setSessionId(newId);\n setMessages([]);\n setRoundNum(0);\n setConsensusReached(false);\n setDiscussionRound(0);\n setStatusMessage(\"Started new session.\");\n return;\n }\n\n if (value === \"/copy\") {\n try {\n const md = formatAsMarkdown(messages);\n copyToClipboard(md);\n setStatusMessage(\"Copied conversation to clipboard.\");\n } catch {\n setStatusMessage(\"Failed to copy to clipboard.\");\n }\n return;\n }\n\n setConsensusReached(false);\n setState(\"running\");\n runRound(value);\n };\n\n return (\n <Box flexDirection=\"column\">\n <Header sessionId={sessionId} />\n\n {messages.length === 0 && state === \"input\" && <QuickHelp />}\n\n {messages.map((msg, i) => {\n if (msg.role === \"user\") {\n return <UserMessage key={i} content={msg.content} />;\n }\n if (isValidAgentName(msg.role)) {\n return (\n <AgentResponseBlock\n key={i}\n agent={msg.role}\n content={msg.content}\n error={msg.error}\n />\n );\n }\n return null;\n })}\n\n {discussionRound > 0 && thinkingAgents.length > 0 && (\n <DiscussionStatus round={discussionRound} maxRounds={config.discussion.max_rounds} />\n )}\n\n {thinkingAgents.length > 0 && (\n <Box flexDirection=\"column\" marginBottom={1}>\n {thinkingAgents.map((agent) => (\n <ThinkingIndicator key={agent} agent={agent} />\n ))}\n </Box>\n )}\n\n {consensusReached && <ConsensusReached />}\n\n {statusMessage && (\n <Box marginLeft={1}>\n <Text dimColor italic>{statusMessage}</Text>\n </Box>\n )}\n\n {state === \"config\" && (\n <InlineConfigEditor\n isActive={state === \"config\"}\n onClose={() => {\n const updated = loadConfig();\n setConfig(updated);\n try {\n setPair(validateAgentPair(updated.agents));\n } catch {\n // keep current pair if new config is invalid\n }\n setAgentModels((prev) => ({\n ...prev,\n claude: updated.claude.model,\n codex: updated.codex.model,\n gemini: updated.gemini.model,\n }));\n setState(\"input\");\n }}\n />\n )}\n\n {state === \"input\" && <PromptInput onSubmit={handleSubmit} />}\n </Box>\n );\n}\n\n// --- Entry points ---\n\nexport function startApp(props: AppProps) {\n return render(<App {...props} />);\n}\n\nexport function showTranscriptMarkdown(sessionId: string): string {\n const dbMessages = getMessages(sessionId);\n const messages = dbMessages.map((m) => ({\n role: m.role,\n content: m.content,\n round: m.round,\n }));\n return formatAsMarkdown(messages);\n}\n\nexport function showTranscript(sessionId: string): void {\n const dbMessages = getMessages(sessionId);\n const messages: Message[] = dbMessages.map((m) => ({\n role: m.role,\n content: m.content,\n round: m.round,\n }));\n\n const { unmount } = render(\n <Box flexDirection=\"column\">\n <Header sessionId={sessionId} />\n {messages.map((msg, i) => {\n if (msg.role === \"user\") {\n return <UserMessage key={i} content={msg.content} />;\n }\n if (isValidAgentName(msg.role)) {\n return (\n <AgentResponseBlock key={i} agent={msg.role} content={msg.content} />\n );\n }\n return null;\n })}\n <Box>\n <Text dimColor>{\"─\".repeat(60)}</Text>\n </Box>\n </Box>\n );\n\n unmount();\n}\n\nexport function showSessionList(\n sessions: Array<{\n id: string;\n title: string | null;\n status: string;\n created_at: string;\n updated_at: string;\n }>\n): void {\n const { unmount } = render(\n <Box flexDirection=\"column\">\n {sessions.length === 0 ? (\n <Text dimColor> No sessions found.</Text>\n ) : (\n sessions.map((s) => (\n <Box key={s.id} marginLeft={1}>\n <Text color=\"cyan\">{s.id.slice(0, 7)}</Text>\n <Text>{\" \"}</Text>\n <Text>{s.title || \"(untitled)\"}</Text>\n <Text>{\" \"}</Text>\n <Text color={s.status === \"active\" ? \"green\" : undefined} dimColor={s.status !== \"active\"}>\n {s.status}\n </Text>\n <Text>{\" \"}</Text>\n <Text dimColor>{s.updated_at}</Text>\n </Box>\n ))\n )}\n </Box>\n );\n\n unmount();\n}\n","import { spawn } from \"node:child_process\";\nimport { createInterface } from \"node:readline\";\nimport type { AgentEvent, AgentOptions, AgentResponse } from \"./types.js\";\n\n/**\n * Parse Claude Code's stream-json JSONL output into AgentEvents.\n *\n * Event format (one JSON object per line):\n * { type: \"system\", subtype: \"init\", ... }\n * { type: \"assistant\", message: { content: [{ type: \"text\", text }, { type: \"tool_use\", ... }] } }\n * { type: \"user\", message: { content: [{ type: \"tool_result\", ... }] } }\n * { type: \"result\", subtype: \"success\", result: \"final text\", ... }\n */\n\nasync function* streamClaude(\n options: AgentOptions\n): AsyncGenerator<AgentEvent> {\n const args = [\n \"-p\",\n \"--verbose\",\n \"--output-format\",\n \"stream-json\",\n \"--no-session-persistence\",\n ];\n\n if (options.systemPrompt) {\n args.push(\"--system-prompt\", options.systemPrompt);\n }\n if (options.model) {\n args.push(\"--model\", options.model);\n }\n\n args.push(options.prompt);\n\n const proc = spawn(\"claude\", args, {\n cwd: options.cwd,\n stdio: [\"ignore\", \"pipe\", \"inherit\"],\n env: { ...process.env, CLAUDECODE: \"\" },\n });\n\n // Handle spawn errors (e.g., command not found)\n let spawnErrorMsg = \"\";\n proc.on(\"error\", (err) => {\n spawnErrorMsg = err.message;\n });\n\n // Abort support — kill the child process when signalled\n if (options.signal) {\n if (options.signal.aborted) {\n proc.kill();\n } else {\n options.signal.addEventListener(\"abort\", () => proc.kill(), { once: true });\n }\n }\n\n const rl = createInterface({ input: proc.stdout! });\n let gotResultText = false;\n\n for await (const line of rl) {\n if (!line.trim()) continue;\n\n let data: any;\n try {\n data = JSON.parse(line);\n } catch {\n continue;\n }\n\n if (data.type === \"assistant\" && data.message?.content) {\n for (const block of data.message.content) {\n if (block.type === \"text\" && block.text) {\n yield { type: \"text\", agent: \"claude\", content: block.text };\n gotResultText = true;\n } else if (block.type === \"tool_use\") {\n yield {\n type: \"tool_call\",\n agent: \"claude\",\n toolName: block.name,\n toolInput:\n typeof block.input === \"string\"\n ? block.input\n : JSON.stringify(block.input),\n };\n }\n }\n } else if (data.type === \"user\" && data.message?.content) {\n for (const block of data.message.content) {\n if (block.type === \"tool_result\") {\n const text =\n typeof block.content === \"string\"\n ? block.content\n : Array.isArray(block.content)\n ? block.content\n .filter((c: any) => c.type === \"text\")\n .map((c: any) => c.text)\n .join(\"\\n\")\n : \"\";\n if (text) {\n yield {\n type: \"tool_result\",\n agent: \"claude\",\n toolOutput: text,\n };\n }\n }\n }\n } else if (data.type === \"result\") {\n if (data.is_error) {\n yield {\n type: \"error\",\n agent: \"claude\",\n content: data.error || data.result || \"Unknown error\",\n };\n } else if (data.result && !gotResultText) {\n // Use result.result as fallback if no assistant text blocks were emitted\n yield { type: \"text\", agent: \"claude\", content: data.result };\n }\n }\n }\n\n // Wait for the process to exit\n await new Promise<void>((resolve) => {\n proc.on(\"close\", resolve);\n });\n\n if (spawnErrorMsg) {\n yield {\n type: \"error\",\n agent: \"claude\",\n content: `Failed to spawn claude: ${spawnErrorMsg}`,\n };\n }\n\n yield { type: \"done\", agent: \"claude\" };\n}\n\nexport async function runClaude(options: AgentOptions): Promise<AgentResponse> {\n const start = Date.now();\n const events: AgentEvent[] = [];\n const textParts: string[] = [];\n const errors: string[] = [];\n\n for await (const event of streamClaude(options)) {\n events.push(event);\n if (event.type === \"text\" && event.content) {\n textParts.push(event.content);\n } else if (event.type === \"error\" && event.content) {\n errors.push(event.content);\n }\n }\n\n return {\n agent: \"claude\",\n text: textParts.join(\"\"),\n events,\n durationMs: Date.now() - start,\n error: errors.length > 0 ? errors.join(\"\\n\") : undefined,\n };\n}\n","import { spawn } from \"node:child_process\";\nimport { createInterface } from \"node:readline\";\nimport type { AgentEvent, AgentOptions, AgentResponse } from \"./types.js\";\n\n/**\n * Parse Codex CLI's exec --json JSONL output into AgentEvents.\n *\n * Event format (one JSON object per line):\n * { type: \"thread.started\", thread_id: \"...\" }\n * { type: \"turn.started\" }\n * { type: \"item.completed\", item: { type: \"agent_message\", text: \"...\" } }\n * { type: \"item.started\"|\"item.completed\", item: { type: \"command_execution\", command, aggregated_output, exit_code } }\n * { type: \"turn.completed\", usage: { ... } }\n */\n\nasync function* streamCodex(\n options: AgentOptions\n): AsyncGenerator<AgentEvent> {\n const args = [\"exec\", \"--json\", \"--full-auto\", \"--ephemeral\"];\n\n if (options.model) {\n args.push(\"-m\", options.model);\n }\n\n // Build the full prompt with system context prepended\n let fullPrompt = options.prompt;\n if (options.systemPrompt) {\n fullPrompt = `${options.systemPrompt}\\n\\n---\\n\\n${options.prompt}`;\n }\n\n args.push(fullPrompt);\n\n const proc = spawn(\"codex\", args, {\n cwd: options.cwd,\n stdio: [\"ignore\", \"pipe\", \"inherit\"],\n env: process.env,\n });\n\n // Handle spawn errors (e.g., command not found)\n let spawnErrorMsg = \"\";\n proc.on(\"error\", (err) => {\n spawnErrorMsg = err.message;\n });\n\n // Abort support — kill the child process when signalled\n if (options.signal) {\n if (options.signal.aborted) {\n proc.kill();\n } else {\n options.signal.addEventListener(\"abort\", () => proc.kill(), { once: true });\n }\n }\n\n const rl = createInterface({ input: proc.stdout! });\n\n for await (const line of rl) {\n if (!line.trim()) continue;\n\n let data: any;\n try {\n data = JSON.parse(line);\n } catch {\n continue;\n }\n\n if (data.type === \"item.completed\" && data.item) {\n const item = data.item;\n\n if (item.type === \"agent_message\" && item.text) {\n yield { type: \"text\", agent: \"codex\", content: item.text };\n } else if (item.type === \"command_execution\") {\n yield {\n type: \"tool_call\",\n agent: \"codex\",\n toolName: \"command\",\n toolInput: item.command,\n };\n if (item.aggregated_output) {\n yield {\n type: \"tool_result\",\n agent: \"codex\",\n toolOutput: item.aggregated_output,\n };\n }\n } else if (item.type === \"file_change\" && item.changes) {\n const desc = item.changes\n .map((c: any) => `${c.kind}: ${c.path}`)\n .join(\", \");\n yield {\n type: \"tool_result\",\n agent: \"codex\",\n toolName: \"file_change\",\n toolOutput: desc,\n };\n } else if (item.type === \"error\") {\n yield {\n type: \"error\",\n agent: \"codex\",\n content: item.message || \"Unknown error\",\n };\n }\n } else if (data.type === \"turn.failed\") {\n yield {\n type: \"error\",\n agent: \"codex\",\n content: data.error?.message || \"Turn failed\",\n };\n } else if (data.type === \"error\") {\n yield {\n type: \"error\",\n agent: \"codex\",\n content: data.message || \"Stream error\",\n };\n }\n }\n\n // Wait for the process to exit\n await new Promise<void>((resolve) => {\n proc.on(\"close\", resolve);\n });\n\n if (spawnErrorMsg) {\n yield {\n type: \"error\",\n agent: \"codex\",\n content: `Failed to spawn codex: ${spawnErrorMsg}`,\n };\n }\n\n yield { type: \"done\", agent: \"codex\" };\n}\n\nexport async function runCodex(options: AgentOptions): Promise<AgentResponse> {\n const start = Date.now();\n const events: AgentEvent[] = [];\n const textParts: string[] = [];\n const errors: string[] = [];\n\n for await (const event of streamCodex(options)) {\n events.push(event);\n if (event.type === \"text\" && event.content) {\n textParts.push(event.content);\n } else if (event.type === \"error\" && event.content) {\n errors.push(event.content);\n }\n }\n\n return {\n agent: \"codex\",\n text: textParts.join(\"\"),\n events,\n durationMs: Date.now() - start,\n error: errors.length > 0 ? errors.join(\"\\n\") : undefined,\n };\n}\n","import { spawn } from \"node:child_process\";\nimport type { AgentEvent, AgentOptions, AgentResponse } from \"./types.js\";\n\n/**\n * Run the Gemini CLI and parse its JSON output into AgentEvents.\n *\n * Gemini CLI returns a single JSON blob (not streaming JSONL):\n * { response: \"text\", stats: {...}, error: \"...\" }\n *\n * No --system-prompt flag — prepend system prompt to user prompt (same as codex).\n * Flags: gemini -p \"prompt\" --output-format json -m model --yolo\n */\n\nasync function* streamGemini(\n options: AgentOptions\n): AsyncGenerator<AgentEvent> {\n const args = [\"-p\"];\n\n // Build the full prompt with system context prepended\n let fullPrompt = options.prompt;\n if (options.systemPrompt) {\n fullPrompt = `${options.systemPrompt}\\n\\n---\\n\\n${options.prompt}`;\n }\n\n args.push(fullPrompt, \"--output-format\", \"json\", \"--yolo\");\n\n if (options.model) {\n args.push(\"-m\", options.model);\n }\n\n const proc = spawn(\"gemini\", args, {\n cwd: options.cwd,\n stdio: [\"ignore\", \"pipe\", \"inherit\"],\n env: process.env,\n });\n\n // Handle spawn errors (e.g., command not found)\n let spawnErrorMsg = \"\";\n proc.on(\"error\", (err) => {\n spawnErrorMsg = err.message;\n });\n\n // Abort support — kill the child process when signalled\n if (options.signal) {\n if (options.signal.aborted) {\n proc.kill();\n } else {\n options.signal.addEventListener(\"abort\", () => proc.kill(), { once: true });\n }\n }\n\n // Collect all stdout into a single buffer\n const chunks: Buffer[] = [];\n proc.stdout!.on(\"data\", (chunk: Buffer) => {\n chunks.push(chunk);\n });\n\n // Wait for the process to exit\n await new Promise<void>((resolve) => {\n proc.on(\"close\", resolve);\n });\n\n if (spawnErrorMsg) {\n yield {\n type: \"error\",\n agent: \"gemini\",\n content: `Failed to spawn gemini: ${spawnErrorMsg}`,\n };\n yield { type: \"done\", agent: \"gemini\" };\n return;\n }\n\n const stdout = Buffer.concat(chunks).toString(\"utf-8\").trim();\n\n if (!stdout) {\n yield { type: \"error\", agent: \"gemini\", content: \"No output from gemini\" };\n yield { type: \"done\", agent: \"gemini\" };\n return;\n }\n\n try {\n const data = JSON.parse(stdout);\n\n if (data.error) {\n yield { type: \"error\", agent: \"gemini\", content: data.error };\n } else if (data.response) {\n yield { type: \"text\", agent: \"gemini\", content: data.response };\n } else {\n yield { type: \"error\", agent: \"gemini\", content: \"Unexpected response format\" };\n }\n } catch {\n // If it's not JSON, treat the entire stdout as text\n yield { type: \"text\", agent: \"gemini\", content: stdout };\n }\n\n yield { type: \"done\", agent: \"gemini\" };\n}\n\nexport async function runGemini(options: AgentOptions): Promise<AgentResponse> {\n const start = Date.now();\n const events: AgentEvent[] = [];\n const textParts: string[] = [];\n const errors: string[] = [];\n\n for await (const event of streamGemini(options)) {\n events.push(event);\n if (event.type === \"text\" && event.content) {\n textParts.push(event.content);\n } else if (event.type === \"error\" && event.content) {\n errors.push(event.content);\n }\n }\n\n return {\n agent: \"gemini\",\n text: textParts.join(\"\"),\n events,\n durationMs: Date.now() - start,\n error: errors.length > 0 ? errors.join(\"\\n\") : undefined,\n };\n}\n","import type { AgentDescriptor, AgentName } from \"./types.js\";\nimport { runClaude } from \"./claude.js\";\nimport { runCodex } from \"./codex.js\";\nimport { runGemini } from \"./gemini.js\";\n\nconst AGENTS: Record<AgentName, AgentDescriptor> = {\n claude: {\n name: \"claude\",\n displayName: \"Claude\",\n color: \"magenta\",\n cliBinary: \"claude\",\n installUrl: \"https://docs.anthropic.com/en/docs/claude-code\",\n org: \"Anthropic\",\n run: runClaude,\n },\n codex: {\n name: \"codex\",\n displayName: \"Codex\",\n color: \"green\",\n cliBinary: \"codex\",\n installUrl: \"https://github.com/openai/codex\",\n org: \"OpenAI\",\n run: runCodex,\n },\n gemini: {\n name: \"gemini\",\n displayName: \"Gemini\",\n color: \"blue\",\n cliBinary: \"gemini\",\n installUrl: \"https://github.com/google-gemini/gemini-cli\",\n org: \"Google\",\n run: runGemini,\n },\n};\n\nexport function getAgent(name: AgentName): AgentDescriptor {\n return AGENTS[name];\n}\n\nexport function getAllAgentNames(): AgentName[] {\n return Object.keys(AGENTS) as AgentName[];\n}\n\nexport function isValidAgentName(name: string): name is AgentName {\n return name in AGENTS;\n}\n\nexport function validateAgentPair(pair: string[]): [AgentName, AgentName] {\n if (pair.length !== 2) {\n throw new Error(\"Agent pair must contain exactly 2 agents\");\n }\n if (pair[0] === pair[1]) {\n throw new Error(\"Agent pair must contain 2 distinct agents\");\n }\n for (const name of pair) {\n if (!isValidAgentName(name)) {\n throw new Error(`Unknown agent: \"${name}\". Valid agents: ${getAllAgentNames().join(\", \")}`);\n }\n }\n return pair as [AgentName, AgentName];\n}\n","import { getAgent, isValidAgentName } from \"./agents/registry.js\";\n\ninterface Message {\n role: string;\n content: string;\n error?: boolean;\n}\n\nexport function formatAsMarkdown(messages: Message[]): string {\n const parts: string[] = [];\n\n for (const msg of messages) {\n if (msg.role === \"system\") continue;\n\n if (msg.role === \"user\") {\n parts.push(`**You:** ${msg.content}`);\n } else if (isValidAgentName(msg.role)) {\n const name = getAgent(msg.role).displayName;\n if (msg.error) {\n parts.push(`**${name}:** *(error)*\\n\\n${msg.content}`);\n } else {\n parts.push(`**${name}:**\\n\\n${msg.content}`);\n }\n }\n }\n\n return parts.join(\"\\n\\n---\\n\\n\") + \"\\n\";\n}\n","import { execSync } from \"node:child_process\";\n\nexport function copyToClipboard(text: string): void {\n const platform = process.platform;\n\n let cmd: string;\n if (platform === \"darwin\") {\n cmd = \"pbcopy\";\n } else if (platform === \"win32\") {\n cmd = \"clip\";\n } else {\n // Linux — try xclip first, fall back to xsel\n let hasXclip = false;\n let hasXsel = false;\n try {\n execSync(\"which xclip\", { stdio: \"ignore\" });\n hasXclip = true;\n } catch {}\n if (!hasXclip) {\n try {\n execSync(\"which xsel\", { stdio: \"ignore\" });\n hasXsel = true;\n } catch {}\n }\n\n if (hasXclip) {\n cmd = \"xclip -selection clipboard\";\n } else if (hasXsel) {\n cmd = \"xsel --clipboard --input\";\n } else {\n throw new Error(\n \"Clipboard requires xclip or xsel. Install one with: sudo apt install xclip\"\n );\n }\n }\n\n try {\n execSync(cmd, { input: text, stdio: [\"pipe\", \"ignore\", \"ignore\"] });\n } catch {\n throw new Error(\n `Failed to copy to clipboard using \"${cmd.split(\" \")[0]}\". Check that it is installed and working.`\n );\n }\n}\n","import Database from \"better-sqlite3\";\nimport { join } from \"node:path\";\nimport { getConfigDir, ensureConfigDir } from \"../config.js\";\n\nlet db: Database.Database | null = null;\n\nexport function getDbPath(): string {\n return join(getConfigDir(), \"tagteam.db\");\n}\n\nexport function getDb(): Database.Database {\n if (db) return db;\n\n ensureConfigDir();\n db = new Database(getDbPath());\n db.pragma(\"journal_mode = WAL\");\n db.pragma(\"foreign_keys = ON\");\n\n initSchema(db);\n return db;\n}\n\nfunction initSchema(db: Database.Database): void {\n db.exec(`\n CREATE TABLE IF NOT EXISTS sessions (\n id TEXT PRIMARY KEY,\n title TEXT,\n working_dir TEXT NOT NULL,\n created_at TEXT NOT NULL DEFAULT (datetime('now')),\n updated_at TEXT NOT NULL DEFAULT (datetime('now')),\n status TEXT NOT NULL DEFAULT 'active'\n );\n\n CREATE TABLE IF NOT EXISTS messages (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n session_id TEXT NOT NULL REFERENCES sessions(id),\n role TEXT NOT NULL,\n content TEXT NOT NULL,\n round INTEGER NOT NULL DEFAULT 0,\n duration_ms INTEGER,\n metadata TEXT,\n created_at TEXT NOT NULL DEFAULT (datetime('now'))\n );\n\n CREATE INDEX IF NOT EXISTS idx_messages_session ON messages(session_id, id);\n `);\n}\n\nexport function closeDb(): void {\n if (db) {\n db.close();\n db = null;\n }\n}\n","import { getDb } from \"./index.js\";\n\nexport interface Session {\n id: string;\n title: string | null;\n working_dir: string;\n created_at: string;\n updated_at: string;\n status: string;\n}\n\nexport function createSession(\n id: string,\n workingDir: string\n): Session {\n const db = getDb();\n db.prepare(\n `INSERT INTO sessions (id, working_dir) VALUES (?, ?)`\n ).run(id, workingDir);\n\n return getSession(id)!;\n}\n\nexport function getSession(id: string): Session | undefined {\n const db = getDb();\n return db.prepare(`SELECT * FROM sessions WHERE id = ?`).get(id) as\n | Session\n | undefined;\n}\n\nexport function getSessionByPrefix(prefix: string): Session | undefined {\n const db = getDb();\n return db\n .prepare(`SELECT * FROM sessions WHERE id LIKE ? ORDER BY updated_at DESC LIMIT 1`)\n .get(`${prefix}%`) as Session | undefined;\n}\n\nexport function getMostRecentSession(): Session | undefined {\n const db = getDb();\n return db\n .prepare(\n `SELECT * FROM sessions WHERE status = 'active' ORDER BY updated_at DESC LIMIT 1`\n )\n .get() as Session | undefined;\n}\n\nexport function listSessions(limit = 20): Session[] {\n const db = getDb();\n return db\n .prepare(`SELECT * FROM sessions ORDER BY updated_at DESC LIMIT ?`)\n .all(limit) as Session[];\n}\n\nexport function updateSessionTitle(id: string, title: string): void {\n const db = getDb();\n db.prepare(\n `UPDATE sessions SET title = ?, updated_at = datetime('now') WHERE id = ?`\n ).run(title, id);\n}\n\nexport function touchSession(id: string): void {\n const db = getDb();\n db.prepare(`UPDATE sessions SET updated_at = datetime('now') WHERE id = ?`).run(\n id\n );\n}\n\nexport function deleteSession(id: string): void {\n const db = getDb();\n db.prepare(`DELETE FROM messages WHERE session_id = ?`).run(id);\n db.prepare(`DELETE FROM sessions WHERE id = ?`).run(id);\n}\n\nexport function deleteAllSessions(): void {\n const db = getDb();\n db.prepare(`DELETE FROM messages`).run();\n db.prepare(`DELETE FROM sessions`).run();\n}\n","import { getDb } from \"./index.js\";\n\nexport interface Message {\n id: number;\n session_id: string;\n role: string;\n content: string;\n round: number;\n duration_ms: number | null;\n metadata: string | null;\n created_at: string;\n}\n\nexport function insertMessage(params: {\n sessionId: string;\n role: string;\n content: string;\n round: number;\n durationMs?: number;\n metadata?: Record<string, unknown>;\n}): Message {\n const db = getDb();\n const result = db\n .prepare(\n `INSERT INTO messages (session_id, role, content, round, duration_ms, metadata)\n VALUES (?, ?, ?, ?, ?, ?)`\n )\n .run(\n params.sessionId,\n params.role,\n params.content,\n params.round,\n params.durationMs ?? null,\n params.metadata ? JSON.stringify(params.metadata) : null\n );\n\n return db\n .prepare(`SELECT * FROM messages WHERE id = ?`)\n .get(result.lastInsertRowid) as Message;\n}\n\nexport function getMessages(sessionId: string): Message[] {\n const db = getDb();\n return db\n .prepare(`SELECT * FROM messages WHERE session_id = ? ORDER BY id`)\n .all(sessionId) as Message[];\n}\n\nexport function deleteMessagesFromRound(\n sessionId: string,\n fromRound: number\n): void {\n const db = getDb();\n db.prepare(\n `DELETE FROM messages WHERE session_id = ? AND round >= ?`\n ).run(sessionId, fromRound);\n}","import type { AgentName } from \"./agents/types.js\";\nimport { getAgent, isValidAgentName } from \"./agents/registry.js\";\n\nfunction otherAgent(agent: AgentName, pair: [AgentName, AgentName]): string {\n const other = pair[0] === agent ? pair[1] : pair[0];\n const desc = getAgent(other);\n return `${desc.displayName} (${desc.org})`;\n}\n\nexport function collaborationPrompt(agent: AgentName, pair: [AgentName, AgentName]): string {\n return `You are in a collaborative session with ${otherAgent(agent, pair)}. You'll both respond to the user's prompt independently, then see each other's responses. In discussion rounds: highlight where you agree, constructively address disagreements, and build on each other's ideas. Be concise - avoid repeating what was already said.`;\n}\n\nexport function discussionPrompt(\n agent: AgentName,\n conversationHistory: string,\n pair: [AgentName, AgentName]\n): string {\n return `${collaborationPrompt(agent, pair)}\n\nHere is the conversation so far:\n\n${conversationHistory}\n\nNow provide your response for this discussion round. Build on what was said, highlight agreements, and address any disagreements constructively. Be concise.`;\n}\n\nexport function debatePrompt(agent: AgentName, pair: [AgentName, AgentName]): string {\n const other = otherAgent(agent, pair);\n return `You are in a structured debate with ${other}. You'll both respond to the user's prompt, then see each other's responses and discuss.\n\nYour goal is to reach consensus through constructive discussion. In each round:\n- Address specific points of agreement and disagreement\n- Refine your position based on valid arguments from ${other}\n- Be concise — don't repeat points already established\n\nWhen you believe you and ${other} have reached substantial agreement on the key points, end your response with [CONSENSUS] on its own line. Only do this when you genuinely agree — don't force premature consensus.`;\n}\n\nexport function debateRoundPrompt(\n agent: AgentName,\n conversationHistory: string,\n pair: [AgentName, AgentName]\n): string {\n const other = otherAgent(agent, pair);\n return `${debatePrompt(agent, pair)}\n\nHere is the conversation so far:\n\n${conversationHistory}\n\nRespond to the latest round. If you agree with ${other}'s position on all key points, end with [CONSENSUS]. Otherwise, continue the discussion.`;\n}\n\nexport function directPrompt(\n conversationHistory: string,\n): string {\n return `You are being addressed directly in a multi-agent session. Here is the conversation so far:\n\n${conversationHistory}\n\nRespond to the user's latest message. Be concise.`;\n}\n\nexport const CONSENSUS_MARKER = \"[CONSENSUS]\";\n\nexport function formatConversationHistory(\n messages: Array<{ role: string; agent?: AgentName; content: string }>\n): string {\n return messages\n .map((m) => {\n let label: string;\n if (m.role === \"user\") {\n label = \"User\";\n } else if (isValidAgentName(m.role)) {\n label = getAgent(m.role).displayName;\n } else if (m.agent && isValidAgentName(m.agent)) {\n label = getAgent(m.agent).displayName;\n } else {\n label = m.role;\n }\n return `[${label}]: ${m.content}`;\n })\n .join(\"\\n\\n\");\n}\n","import React, { useState } from \"react\";\nimport { render, Box, Text, useApp, useInput } from \"ink\";\nimport TextInput from \"ink-text-input\";\nimport { loadConfig, setConfigValue } from \"./config.js\";\nimport type { TagTeamConfig } from \"./config.js\";\nimport { validateAgentPair } from \"./agents/registry.js\";\n\ninterface ConfigField {\n key: string;\n label: string;\n get: (c: TagTeamConfig) => string;\n type: \"string\" | \"number\";\n validate?: (value: string) => string | null;\n}\n\nconst CONFIG_FIELDS: ConfigField[] = [\n {\n key: \"agents\",\n label: \"Agent pair\",\n get: (c) => c.agents.join(\", \"),\n type: \"string\",\n validate: (value) => {\n try {\n const names = value.split(\",\").map((s) => s.trim());\n validateAgentPair(names);\n return null;\n } catch (e: any) {\n return e.message;\n }\n },\n },\n {\n key: \"claude.model\",\n label: \"Claude model\",\n get: (c) => c.claude.model,\n type: \"string\",\n },\n {\n key: \"codex.model\",\n label: \"Codex model\",\n get: (c) => c.codex.model,\n type: \"string\",\n },\n {\n key: \"gemini.model\",\n label: \"Gemini model\",\n get: (c) => c.gemini.model,\n type: \"string\",\n },\n {\n key: \"discussion.max_rounds\",\n label: \"Discussion max rounds\",\n get: (c) => String(c.discussion.max_rounds),\n type: \"number\",\n },\n];\n\nconst LABEL_WIDTH = Math.max(...CONFIG_FIELDS.map((f) => f.label.length));\n\ntype EditMode = \"select\" | \"edit\";\n\ninterface InlineConfigEditorProps {\n isActive: boolean;\n onClose: () => void;\n}\n\nexport function InlineConfigEditor({ isActive, onClose }: InlineConfigEditorProps) {\n const [config, setConfig] = useState(() => loadConfig());\n const [selectedIndex, setSelectedIndex] = useState(0);\n const [mode, setMode] = useState<EditMode>(\"select\");\n const [editValue, setEditValue] = useState(\"\");\n const [savedMessage, setSavedMessage] = useState<string | null>(null);\n\n useInput(\n (input, key) => {\n if (key.upArrow) {\n setSavedMessage(null);\n setSelectedIndex((i) => (i > 0 ? i - 1 : CONFIG_FIELDS.length - 1));\n } else if (key.downArrow) {\n setSavedMessage(null);\n setSelectedIndex((i) => (i < CONFIG_FIELDS.length - 1 ? i + 1 : 0));\n } else if (key.return) {\n const field = CONFIG_FIELDS[selectedIndex];\n setEditValue(field.get(config));\n setSavedMessage(null);\n setMode(\"edit\");\n } else if (key.escape || input === \"q\") {\n onClose();\n }\n },\n { isActive: isActive && mode === \"select\" }\n );\n\n useInput(\n (_input, key) => {\n if (key.escape) {\n setMode(\"select\");\n }\n },\n { isActive: isActive && mode === \"edit\" }\n );\n\n const handleEditSubmit = (value: string) => {\n const field = CONFIG_FIELDS[selectedIndex];\n\n if (field.type === \"number\") {\n const n = Number(value);\n if (!Number.isInteger(n) || n < 1) {\n setSavedMessage(\"Error: must be a positive integer\");\n setMode(\"select\");\n return;\n }\n }\n\n if (field.validate) {\n const error = field.validate(value);\n if (error) {\n setSavedMessage(`Error: ${error}`);\n setMode(\"select\");\n return;\n }\n }\n\n try {\n const updated = setConfigValue(field.key, value);\n setConfig(updated);\n setSavedMessage(`Saved ${field.key} = ${value}`);\n } catch (e: any) {\n setSavedMessage(`Error: ${e.message}`);\n }\n\n setMode(\"select\");\n };\n\n return (\n <Box flexDirection=\"column\">\n <Box marginBottom={1}>\n <Text bold>Configuration</Text>\n <Text dimColor> ── edit values inline</Text>\n </Box>\n\n {CONFIG_FIELDS.map((field, i) => {\n const selected = i === selectedIndex;\n const pointer = selected ? \"> \" : \" \";\n const currentValue = field.get(config);\n\n return (\n <Box key={field.key} marginLeft={1}>\n <Text color={selected ? \"cyan\" : undefined} bold={selected}>\n {pointer}\n {field.label.padEnd(LABEL_WIDTH)}\n </Text>\n <Text dimColor> = </Text>\n {mode === \"edit\" && selected ? (\n <TextInput\n value={editValue}\n onChange={setEditValue}\n onSubmit={handleEditSubmit}\n showCursor\n />\n ) : (\n <Text color=\"white\">{currentValue}</Text>\n )}\n </Box>\n );\n })}\n\n {savedMessage && (\n <Box marginTop={1} marginLeft={1}>\n <Text color={savedMessage.startsWith(\"Error\") ? \"red\" : \"green\"}>\n {savedMessage}\n </Text>\n </Box>\n )}\n\n <Box marginTop={1} marginLeft={1}>\n <Text dimColor>\n {mode === \"edit\"\n ? \"Enter save Esc cancel\"\n : \"↑↓ navigate Enter edit Esc/q quit\"}\n </Text>\n </Box>\n </Box>\n );\n}\n\n// Standalone entrypoint for `tagteam config edit`\nfunction StandaloneConfigEditor() {\n const { exit } = useApp();\n return <InlineConfigEditor isActive={true} onClose={exit} />;\n}\n\nexport function startConfigEditor() {\n return render(<StandaloneConfigEditor />);\n}\n"],"mappings":";;;AAAA,SAAS,eAAe;AACxB,SAAS,YAAAA,iBAAgB;AACzB,OAAO,WAAW;;;ACFlB,SAAS,cAAc,eAAe,WAAW,kBAAkB;AACnE,SAAS,YAAY;AACrB,SAAS,eAAe;AACxB,SAAS,OAAO,iBAAiB;AAkBjC,IAAM,iBAAgC;AAAA,EACpC,QAAQ,CAAC,UAAU,OAAO;AAAA,EAC1B,QAAQ;AAAA,IACN,OAAO;AAAA,EACT;AAAA,EACA,OAAO;AAAA,IACL,OAAO;AAAA,EACT;AAAA,EACA,QAAQ;AAAA,IACN,OAAO;AAAA,EACT;AAAA,EACA,YAAY;AAAA,IACV,YAAY;AAAA,EACd;AACF;AAEO,SAAS,eAAuB;AACrC,MAAI,QAAQ,aAAa,SAAS;AAChC,WAAO;AAAA,MACL,QAAQ,IAAI,WAAW,KAAK,QAAQ,GAAG,WAAW,SAAS;AAAA,MAC3D;AAAA,IACF;AAAA,EACF;AACA,SAAO,KAAK,QAAQ,GAAG,UAAU;AACnC;AAEO,SAAS,gBAAwB;AACtC,SAAO,KAAK,aAAa,GAAG,aAAa;AAC3C;AAEO,SAAS,kBAAwB;AACtC,QAAM,MAAM,aAAa;AACzB,MAAI,CAAC,WAAW,GAAG,GAAG;AACpB,cAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AAAA,EACpC;AACF;AAEO,SAAS,aAA4B;AAC1C,QAAM,aAAa,cAAc;AAEjC,MAAI,CAAC,WAAW,UAAU,GAAG;AAC3B,WAAO,EAAE,GAAG,eAAe;AAAA,EAC7B;AAEA,MAAI;AACF,UAAM,MAAM,aAAa,YAAY,OAAO;AAC5C,UAAM,SAAS,MAAM,GAAG;AACxB,WAAO;AAAA,MACL,QAAQ,MAAM,QAAQ,OAAO,MAAM,KAAK,OAAO,OAAO,WAAW,IAC7D,OAAO,SACP,CAAC,GAAG,eAAe,MAAM;AAAA,MAC7B,QAAQ,EAAE,GAAG,eAAe,QAAQ,GAAG,OAAO,OAAO;AAAA,MACrD,OAAO,EAAE,GAAG,eAAe,OAAO,GAAG,OAAO,MAAM;AAAA,MAClD,QAAQ,EAAE,GAAG,eAAe,QAAQ,GAAG,OAAO,OAAO;AAAA,MACrD,YAAY,EAAE,GAAG,eAAe,YAAY,GAAG,OAAO,WAAW;AAAA,IACnE;AAAA,EACF,QAAQ;AACN,WAAO,EAAE,GAAG,eAAe;AAAA,EAC7B;AACF;AAEO,SAAS,WAAW,QAA6B;AACtD,kBAAgB;AAChB,QAAM,aAAa,cAAc;AACjC,gBAAc,YAAY,UAAU,MAAa,GAAG,OAAO;AAC7D;AAEO,SAAS,eACd,KACA,OACe;AACf,QAAM,SAAS,WAAW;AAC1B,QAAM,QAAQ,IAAI,MAAM,GAAG;AAE3B,MAAI,MAAM,WAAW,GAAG;AACtB,YAAQ,MAAM,CAAC,GAAG;AAAA,MAChB,KAAK;AACH,eAAO,SAAS,MAAM,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC;AACpD;AAAA,MACF,KAAK;AACH,eAAO,OAAO,QAAQ;AACtB;AAAA,MACF,KAAK;AACH,eAAO,MAAM,QAAQ;AACrB;AAAA,MACF,KAAK;AACH,eAAO,OAAO,QAAQ;AACtB;AAAA,MACF,KAAK;AACH,eAAO,WAAW,aAAa,OAAO,KAAK;AAC3C;AAAA,MACF;AACE,cAAM,IAAI,MAAM,uBAAuB,GAAG,EAAE;AAAA,IAChD;AAAA,EACF,WAAW,MAAM,WAAW,GAAG;AAC7B,UAAM,CAAC,SAAS,KAAK,IAAI;AACzB,QAAI,YAAY,YAAY,UAAU,SAAS;AAC7C,aAAO,OAAO,QAAQ;AAAA,IACxB,WAAW,YAAY,WAAW,UAAU,SAAS;AACnD,aAAO,MAAM,QAAQ;AAAA,IACvB,WAAW,YAAY,YAAY,UAAU,SAAS;AACpD,aAAO,OAAO,QAAQ;AAAA,IACxB,WAAW,YAAY,gBAAgB,UAAU,cAAc;AAC7D,aAAO,WAAW,aAAa,OAAO,KAAK;AAAA,IAC7C,OAAO;AACL,YAAM,IAAI,MAAM,uBAAuB,GAAG,EAAE;AAAA,IAC9C;AAAA,EACF,OAAO;AACL,UAAM,IAAI,MAAM,8BAA8B,GAAG,EAAE;AAAA,EACrD;AAEA,aAAW,MAAM;AACjB,SAAO;AACT;;;ACtIA,SAAgB,YAAAC,WAAU,WAAW,aAAa,cAAc;AAChE,SAAS,UAAAC,SAAQ,OAAAC,MAAK,QAAAC,OAAM,UAAAC,SAAQ,YAAAC,iBAAgB;AACpD,OAAOC,gBAAe;AACtB,OAAO,aAAa;AACpB,SAAS,cAAc;AACvB,SAAS,sBAAsB;AAC/B,SAAS,cAAc;;;ACNvB,SAAS,aAAa;AACtB,SAAS,uBAAuB;AAahC,gBAAgB,aACd,SAC4B;AAC5B,QAAM,OAAO;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,MAAI,QAAQ,cAAc;AACxB,SAAK,KAAK,mBAAmB,QAAQ,YAAY;AAAA,EACnD;AACA,MAAI,QAAQ,OAAO;AACjB,SAAK,KAAK,WAAW,QAAQ,KAAK;AAAA,EACpC;AAEA,OAAK,KAAK,QAAQ,MAAM;AAExB,QAAM,OAAO,MAAM,UAAU,MAAM;AAAA,IACjC,KAAK,QAAQ;AAAA,IACb,OAAO,CAAC,UAAU,QAAQ,SAAS;AAAA,IACnC,KAAK,EAAE,GAAG,QAAQ,KAAK,YAAY,GAAG;AAAA,EACxC,CAAC;AAGD,MAAI,gBAAgB;AACpB,OAAK,GAAG,SAAS,CAAC,QAAQ;AACxB,oBAAgB,IAAI;AAAA,EACtB,CAAC;AAGD,MAAI,QAAQ,QAAQ;AAClB,QAAI,QAAQ,OAAO,SAAS;AAC1B,WAAK,KAAK;AAAA,IACZ,OAAO;AACL,cAAQ,OAAO,iBAAiB,SAAS,MAAM,KAAK,KAAK,GAAG,EAAE,MAAM,KAAK,CAAC;AAAA,IAC5E;AAAA,EACF;AAEA,QAAM,KAAK,gBAAgB,EAAE,OAAO,KAAK,OAAQ,CAAC;AAClD,MAAI,gBAAgB;AAEpB,mBAAiB,QAAQ,IAAI;AAC3B,QAAI,CAAC,KAAK,KAAK,EAAG;AAElB,QAAI;AACJ,QAAI;AACF,aAAO,KAAK,MAAM,IAAI;AAAA,IACxB,QAAQ;AACN;AAAA,IACF;AAEA,QAAI,KAAK,SAAS,eAAe,KAAK,SAAS,SAAS;AACtD,iBAAW,SAAS,KAAK,QAAQ,SAAS;AACxC,YAAI,MAAM,SAAS,UAAU,MAAM,MAAM;AACvC,gBAAM,EAAE,MAAM,QAAQ,OAAO,UAAU,SAAS,MAAM,KAAK;AAC3D,0BAAgB;AAAA,QAClB,WAAW,MAAM,SAAS,YAAY;AACpC,gBAAM;AAAA,YACJ,MAAM;AAAA,YACN,OAAO;AAAA,YACP,UAAU,MAAM;AAAA,YAChB,WACE,OAAO,MAAM,UAAU,WACnB,MAAM,QACN,KAAK,UAAU,MAAM,KAAK;AAAA,UAClC;AAAA,QACF;AAAA,MACF;AAAA,IACF,WAAW,KAAK,SAAS,UAAU,KAAK,SAAS,SAAS;AACxD,iBAAW,SAAS,KAAK,QAAQ,SAAS;AACxC,YAAI,MAAM,SAAS,eAAe;AAChC,gBAAM,OACJ,OAAO,MAAM,YAAY,WACrB,MAAM,UACN,MAAM,QAAQ,MAAM,OAAO,IACzB,MAAM,QACH,OAAO,CAAC,MAAW,EAAE,SAAS,MAAM,EACpC,IAAI,CAAC,MAAW,EAAE,IAAI,EACtB,KAAK,IAAI,IACZ;AACR,cAAI,MAAM;AACR,kBAAM;AAAA,cACJ,MAAM;AAAA,cACN,OAAO;AAAA,cACP,YAAY;AAAA,YACd;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF,WAAW,KAAK,SAAS,UAAU;AACjC,UAAI,KAAK,UAAU;AACjB,cAAM;AAAA,UACJ,MAAM;AAAA,UACN,OAAO;AAAA,UACP,SAAS,KAAK,SAAS,KAAK,UAAU;AAAA,QACxC;AAAA,MACF,WAAW,KAAK,UAAU,CAAC,eAAe;AAExC,cAAM,EAAE,MAAM,QAAQ,OAAO,UAAU,SAAS,KAAK,OAAO;AAAA,MAC9D;AAAA,IACF;AAAA,EACF;AAGA,QAAM,IAAI,QAAc,CAAC,YAAY;AACnC,SAAK,GAAG,SAAS,OAAO;AAAA,EAC1B,CAAC;AAED,MAAI,eAAe;AACjB,UAAM;AAAA,MACJ,MAAM;AAAA,MACN,OAAO;AAAA,MACP,SAAS,2BAA2B,aAAa;AAAA,IACnD;AAAA,EACF;AAEA,QAAM,EAAE,MAAM,QAAQ,OAAO,SAAS;AACxC;AAEA,eAAsB,UAAU,SAA+C;AAC7E,QAAM,QAAQ,KAAK,IAAI;AACvB,QAAM,SAAuB,CAAC;AAC9B,QAAM,YAAsB,CAAC;AAC7B,QAAM,SAAmB,CAAC;AAE1B,mBAAiB,SAAS,aAAa,OAAO,GAAG;AAC/C,WAAO,KAAK,KAAK;AACjB,QAAI,MAAM,SAAS,UAAU,MAAM,SAAS;AAC1C,gBAAU,KAAK,MAAM,OAAO;AAAA,IAC9B,WAAW,MAAM,SAAS,WAAW,MAAM,SAAS;AAClD,aAAO,KAAK,MAAM,OAAO;AAAA,IAC3B;AAAA,EACF;AAEA,SAAO;AAAA,IACL,OAAO;AAAA,IACP,MAAM,UAAU,KAAK,EAAE;AAAA,IACvB;AAAA,IACA,YAAY,KAAK,IAAI,IAAI;AAAA,IACzB,OAAO,OAAO,SAAS,IAAI,OAAO,KAAK,IAAI,IAAI;AAAA,EACjD;AACF;;;AC9JA,SAAS,SAAAC,cAAa;AACtB,SAAS,mBAAAC,wBAAuB;AAchC,gBAAgB,YACd,SAC4B;AAC5B,QAAM,OAAO,CAAC,QAAQ,UAAU,eAAe,aAAa;AAE5D,MAAI,QAAQ,OAAO;AACjB,SAAK,KAAK,MAAM,QAAQ,KAAK;AAAA,EAC/B;AAGA,MAAI,aAAa,QAAQ;AACzB,MAAI,QAAQ,cAAc;AACxB,iBAAa,GAAG,QAAQ,YAAY;AAAA;AAAA;AAAA;AAAA,EAAc,QAAQ,MAAM;AAAA,EAClE;AAEA,OAAK,KAAK,UAAU;AAEpB,QAAM,OAAOD,OAAM,SAAS,MAAM;AAAA,IAChC,KAAK,QAAQ;AAAA,IACb,OAAO,CAAC,UAAU,QAAQ,SAAS;AAAA,IACnC,KAAK,QAAQ;AAAA,EACf,CAAC;AAGD,MAAI,gBAAgB;AACpB,OAAK,GAAG,SAAS,CAAC,QAAQ;AACxB,oBAAgB,IAAI;AAAA,EACtB,CAAC;AAGD,MAAI,QAAQ,QAAQ;AAClB,QAAI,QAAQ,OAAO,SAAS;AAC1B,WAAK,KAAK;AAAA,IACZ,OAAO;AACL,cAAQ,OAAO,iBAAiB,SAAS,MAAM,KAAK,KAAK,GAAG,EAAE,MAAM,KAAK,CAAC;AAAA,IAC5E;AAAA,EACF;AAEA,QAAM,KAAKC,iBAAgB,EAAE,OAAO,KAAK,OAAQ,CAAC;AAElD,mBAAiB,QAAQ,IAAI;AAC3B,QAAI,CAAC,KAAK,KAAK,EAAG;AAElB,QAAI;AACJ,QAAI;AACF,aAAO,KAAK,MAAM,IAAI;AAAA,IACxB,QAAQ;AACN;AAAA,IACF;AAEA,QAAI,KAAK,SAAS,oBAAoB,KAAK,MAAM;AAC/C,YAAM,OAAO,KAAK;AAElB,UAAI,KAAK,SAAS,mBAAmB,KAAK,MAAM;AAC9C,cAAM,EAAE,MAAM,QAAQ,OAAO,SAAS,SAAS,KAAK,KAAK;AAAA,MAC3D,WAAW,KAAK,SAAS,qBAAqB;AAC5C,cAAM;AAAA,UACJ,MAAM;AAAA,UACN,OAAO;AAAA,UACP,UAAU;AAAA,UACV,WAAW,KAAK;AAAA,QAClB;AACA,YAAI,KAAK,mBAAmB;AAC1B,gBAAM;AAAA,YACJ,MAAM;AAAA,YACN,OAAO;AAAA,YACP,YAAY,KAAK;AAAA,UACnB;AAAA,QACF;AAAA,MACF,WAAW,KAAK,SAAS,iBAAiB,KAAK,SAAS;AACtD,cAAM,OAAO,KAAK,QACf,IAAI,CAAC,MAAW,GAAG,EAAE,IAAI,KAAK,EAAE,IAAI,EAAE,EACtC,KAAK,IAAI;AACZ,cAAM;AAAA,UACJ,MAAM;AAAA,UACN,OAAO;AAAA,UACP,UAAU;AAAA,UACV,YAAY;AAAA,QACd;AAAA,MACF,WAAW,KAAK,SAAS,SAAS;AAChC,cAAM;AAAA,UACJ,MAAM;AAAA,UACN,OAAO;AAAA,UACP,SAAS,KAAK,WAAW;AAAA,QAC3B;AAAA,MACF;AAAA,IACF,WAAW,KAAK,SAAS,eAAe;AACtC,YAAM;AAAA,QACJ,MAAM;AAAA,QACN,OAAO;AAAA,QACP,SAAS,KAAK,OAAO,WAAW;AAAA,MAClC;AAAA,IACF,WAAW,KAAK,SAAS,SAAS;AAChC,YAAM;AAAA,QACJ,MAAM;AAAA,QACN,OAAO;AAAA,QACP,SAAS,KAAK,WAAW;AAAA,MAC3B;AAAA,IACF;AAAA,EACF;AAGA,QAAM,IAAI,QAAc,CAAC,YAAY;AACnC,SAAK,GAAG,SAAS,OAAO;AAAA,EAC1B,CAAC;AAED,MAAI,eAAe;AACjB,UAAM;AAAA,MACJ,MAAM;AAAA,MACN,OAAO;AAAA,MACP,SAAS,0BAA0B,aAAa;AAAA,IAClD;AAAA,EACF;AAEA,QAAM,EAAE,MAAM,QAAQ,OAAO,QAAQ;AACvC;AAEA,eAAsB,SAAS,SAA+C;AAC5E,QAAM,QAAQ,KAAK,IAAI;AACvB,QAAM,SAAuB,CAAC;AAC9B,QAAM,YAAsB,CAAC;AAC7B,QAAM,SAAmB,CAAC;AAE1B,mBAAiB,SAAS,YAAY,OAAO,GAAG;AAC9C,WAAO,KAAK,KAAK;AACjB,QAAI,MAAM,SAAS,UAAU,MAAM,SAAS;AAC1C,gBAAU,KAAK,MAAM,OAAO;AAAA,IAC9B,WAAW,MAAM,SAAS,WAAW,MAAM,SAAS;AAClD,aAAO,KAAK,MAAM,OAAO;AAAA,IAC3B;AAAA,EACF;AAEA,SAAO;AAAA,IACL,OAAO;AAAA,IACP,MAAM,UAAU,KAAK,EAAE;AAAA,IACvB;AAAA,IACA,YAAY,KAAK,IAAI,IAAI;AAAA,IACzB,OAAO,OAAO,SAAS,IAAI,OAAO,KAAK,IAAI,IAAI;AAAA,EACjD;AACF;;;AC1JA,SAAS,SAAAC,cAAa;AAatB,gBAAgB,aACd,SAC4B;AAC5B,QAAM,OAAO,CAAC,IAAI;AAGlB,MAAI,aAAa,QAAQ;AACzB,MAAI,QAAQ,cAAc;AACxB,iBAAa,GAAG,QAAQ,YAAY;AAAA;AAAA;AAAA;AAAA,EAAc,QAAQ,MAAM;AAAA,EAClE;AAEA,OAAK,KAAK,YAAY,mBAAmB,QAAQ,QAAQ;AAEzD,MAAI,QAAQ,OAAO;AACjB,SAAK,KAAK,MAAM,QAAQ,KAAK;AAAA,EAC/B;AAEA,QAAM,OAAOA,OAAM,UAAU,MAAM;AAAA,IACjC,KAAK,QAAQ;AAAA,IACb,OAAO,CAAC,UAAU,QAAQ,SAAS;AAAA,IACnC,KAAK,QAAQ;AAAA,EACf,CAAC;AAGD,MAAI,gBAAgB;AACpB,OAAK,GAAG,SAAS,CAAC,QAAQ;AACxB,oBAAgB,IAAI;AAAA,EACtB,CAAC;AAGD,MAAI,QAAQ,QAAQ;AAClB,QAAI,QAAQ,OAAO,SAAS;AAC1B,WAAK,KAAK;AAAA,IACZ,OAAO;AACL,cAAQ,OAAO,iBAAiB,SAAS,MAAM,KAAK,KAAK,GAAG,EAAE,MAAM,KAAK,CAAC;AAAA,IAC5E;AAAA,EACF;AAGA,QAAM,SAAmB,CAAC;AAC1B,OAAK,OAAQ,GAAG,QAAQ,CAAC,UAAkB;AACzC,WAAO,KAAK,KAAK;AAAA,EACnB,CAAC;AAGD,QAAM,IAAI,QAAc,CAAC,YAAY;AACnC,SAAK,GAAG,SAAS,OAAO;AAAA,EAC1B,CAAC;AAED,MAAI,eAAe;AACjB,UAAM;AAAA,MACJ,MAAM;AAAA,MACN,OAAO;AAAA,MACP,SAAS,2BAA2B,aAAa;AAAA,IACnD;AACA,UAAM,EAAE,MAAM,QAAQ,OAAO,SAAS;AACtC;AAAA,EACF;AAEA,QAAM,SAAS,OAAO,OAAO,MAAM,EAAE,SAAS,OAAO,EAAE,KAAK;AAE5D,MAAI,CAAC,QAAQ;AACX,UAAM,EAAE,MAAM,SAAS,OAAO,UAAU,SAAS,wBAAwB;AACzE,UAAM,EAAE,MAAM,QAAQ,OAAO,SAAS;AACtC;AAAA,EACF;AAEA,MAAI;AACF,UAAM,OAAO,KAAK,MAAM,MAAM;AAE9B,QAAI,KAAK,OAAO;AACd,YAAM,EAAE,MAAM,SAAS,OAAO,UAAU,SAAS,KAAK,MAAM;AAAA,IAC9D,WAAW,KAAK,UAAU;AACxB,YAAM,EAAE,MAAM,QAAQ,OAAO,UAAU,SAAS,KAAK,SAAS;AAAA,IAChE,OAAO;AACL,YAAM,EAAE,MAAM,SAAS,OAAO,UAAU,SAAS,6BAA6B;AAAA,IAChF;AAAA,EACF,QAAQ;AAEN,UAAM,EAAE,MAAM,QAAQ,OAAO,UAAU,SAAS,OAAO;AAAA,EACzD;AAEA,QAAM,EAAE,MAAM,QAAQ,OAAO,SAAS;AACxC;AAEA,eAAsB,UAAU,SAA+C;AAC7E,QAAM,QAAQ,KAAK,IAAI;AACvB,QAAM,SAAuB,CAAC;AAC9B,QAAM,YAAsB,CAAC;AAC7B,QAAM,SAAmB,CAAC;AAE1B,mBAAiB,SAAS,aAAa,OAAO,GAAG;AAC/C,WAAO,KAAK,KAAK;AACjB,QAAI,MAAM,SAAS,UAAU,MAAM,SAAS;AAC1C,gBAAU,KAAK,MAAM,OAAO;AAAA,IAC9B,WAAW,MAAM,SAAS,WAAW,MAAM,SAAS;AAClD,aAAO,KAAK,MAAM,OAAO;AAAA,IAC3B;AAAA,EACF;AAEA,SAAO;AAAA,IACL,OAAO;AAAA,IACP,MAAM,UAAU,KAAK,EAAE;AAAA,IACvB;AAAA,IACA,YAAY,KAAK,IAAI,IAAI;AAAA,IACzB,OAAO,OAAO,SAAS,IAAI,OAAO,KAAK,IAAI,IAAI;AAAA,EACjD;AACF;;;ACnHA,IAAM,SAA6C;AAAA,EACjD,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,aAAa;AAAA,IACb,OAAO;AAAA,IACP,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,KAAK;AAAA,IACL,KAAK;AAAA,EACP;AAAA,EACA,OAAO;AAAA,IACL,MAAM;AAAA,IACN,aAAa;AAAA,IACb,OAAO;AAAA,IACP,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,KAAK;AAAA,IACL,KAAK;AAAA,EACP;AAAA,EACA,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,aAAa;AAAA,IACb,OAAO;AAAA,IACP,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,KAAK;AAAA,IACL,KAAK;AAAA,EACP;AACF;AAEO,SAAS,SAAS,MAAkC;AACzD,SAAO,OAAO,IAAI;AACpB;AAEO,SAAS,mBAAgC;AAC9C,SAAO,OAAO,KAAK,MAAM;AAC3B;AAEO,SAAS,iBAAiB,MAAiC;AAChE,SAAO,QAAQ;AACjB;AAEO,SAAS,kBAAkB,MAAwC;AACxE,MAAI,KAAK,WAAW,GAAG;AACrB,UAAM,IAAI,MAAM,0CAA0C;AAAA,EAC5D;AACA,MAAI,KAAK,CAAC,MAAM,KAAK,CAAC,GAAG;AACvB,UAAM,IAAI,MAAM,2CAA2C;AAAA,EAC7D;AACA,aAAW,QAAQ,MAAM;AACvB,QAAI,CAAC,iBAAiB,IAAI,GAAG;AAC3B,YAAM,IAAI,MAAM,mBAAmB,IAAI,oBAAoB,iBAAiB,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,IAC5F;AAAA,EACF;AACA,SAAO;AACT;;;ACpDO,SAAS,iBAAiB,UAA6B;AAC5D,QAAM,QAAkB,CAAC;AAEzB,aAAW,OAAO,UAAU;AAC1B,QAAI,IAAI,SAAS,SAAU;AAE3B,QAAI,IAAI,SAAS,QAAQ;AACvB,YAAM,KAAK,YAAY,IAAI,OAAO,EAAE;AAAA,IACtC,WAAW,iBAAiB,IAAI,IAAI,GAAG;AACrC,YAAM,OAAO,SAAS,IAAI,IAAI,EAAE;AAChC,UAAI,IAAI,OAAO;AACb,cAAM,KAAK,KAAK,IAAI;AAAA;AAAA,EAAoB,IAAI,OAAO,EAAE;AAAA,MACvD,OAAO;AACL,cAAM,KAAK,KAAK,IAAI;AAAA;AAAA,EAAU,IAAI,OAAO,EAAE;AAAA,MAC7C;AAAA,IACF;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,aAAa,IAAI;AACrC;;;AC3BA,SAAS,gBAAgB;AAElB,SAAS,gBAAgB,MAAoB;AAClD,QAAM,WAAW,QAAQ;AAEzB,MAAI;AACJ,MAAI,aAAa,UAAU;AACzB,UAAM;AAAA,EACR,WAAW,aAAa,SAAS;AAC/B,UAAM;AAAA,EACR,OAAO;AAEL,QAAI,WAAW;AACf,QAAI,UAAU;AACd,QAAI;AACF,eAAS,eAAe,EAAE,OAAO,SAAS,CAAC;AAC3C,iBAAW;AAAA,IACb,QAAQ;AAAA,IAAC;AACT,QAAI,CAAC,UAAU;AACb,UAAI;AACF,iBAAS,cAAc,EAAE,OAAO,SAAS,CAAC;AAC1C,kBAAU;AAAA,MACZ,QAAQ;AAAA,MAAC;AAAA,IACX;AAEA,QAAI,UAAU;AACZ,YAAM;AAAA,IACR,WAAW,SAAS;AAClB,YAAM;AAAA,IACR,OAAO;AACL,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI;AACF,aAAS,KAAK,EAAE,OAAO,MAAM,OAAO,CAAC,QAAQ,UAAU,QAAQ,EAAE,CAAC;AAAA,EACpE,QAAQ;AACN,UAAM,IAAI;AAAA,MACR,sCAAsC,IAAI,MAAM,GAAG,EAAE,CAAC,CAAC;AAAA,IACzD;AAAA,EACF;AACF;;;AC3CA,OAAO,cAAc;AACrB,SAAS,QAAAC,aAAY;AAGrB,IAAI,KAA+B;AAE5B,SAAS,YAAoB;AAClC,SAAOC,MAAK,aAAa,GAAG,YAAY;AAC1C;AAEO,SAAS,QAA2B;AACzC,MAAI,GAAI,QAAO;AAEf,kBAAgB;AAChB,OAAK,IAAI,SAAS,UAAU,CAAC;AAC7B,KAAG,OAAO,oBAAoB;AAC9B,KAAG,OAAO,mBAAmB;AAE7B,aAAW,EAAE;AACb,SAAO;AACT;AAEA,SAAS,WAAWC,KAA6B;AAC/C,EAAAA,IAAG,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAsBP;AACH;AAEO,SAAS,UAAgB;AAC9B,MAAI,IAAI;AACN,OAAG,MAAM;AACT,SAAK;AAAA,EACP;AACF;;;AC1CO,SAAS,cACd,IACA,YACS;AACT,QAAMC,MAAK,MAAM;AACjB,EAAAA,IAAG;AAAA,IACD;AAAA,EACF,EAAE,IAAI,IAAI,UAAU;AAEpB,SAAO,WAAW,EAAE;AACtB;AAEO,SAAS,WAAW,IAAiC;AAC1D,QAAMA,MAAK,MAAM;AACjB,SAAOA,IAAG,QAAQ,qCAAqC,EAAE,IAAI,EAAE;AAGjE;AAEO,SAAS,mBAAmB,QAAqC;AACtE,QAAMA,MAAK,MAAM;AACjB,SAAOA,IACJ,QAAQ,yEAAyE,EACjF,IAAI,GAAG,MAAM,GAAG;AACrB;AAEO,SAAS,uBAA4C;AAC1D,QAAMA,MAAK,MAAM;AACjB,SAAOA,IACJ;AAAA,IACC;AAAA,EACF,EACC,IAAI;AACT;AAEO,SAAS,aAAa,QAAQ,IAAe;AAClD,QAAMA,MAAK,MAAM;AACjB,SAAOA,IACJ,QAAQ,yDAAyD,EACjE,IAAI,KAAK;AACd;AAEO,SAAS,mBAAmB,IAAY,OAAqB;AAClE,QAAMA,MAAK,MAAM;AACjB,EAAAA,IAAG;AAAA,IACD;AAAA,EACF,EAAE,IAAI,OAAO,EAAE;AACjB;AAEO,SAAS,aAAa,IAAkB;AAC7C,QAAMA,MAAK,MAAM;AACjB,EAAAA,IAAG,QAAQ,+DAA+D,EAAE;AAAA,IAC1E;AAAA,EACF;AACF;AAEO,SAAS,cAAc,IAAkB;AAC9C,QAAMA,MAAK,MAAM;AACjB,EAAAA,IAAG,QAAQ,2CAA2C,EAAE,IAAI,EAAE;AAC9D,EAAAA,IAAG,QAAQ,mCAAmC,EAAE,IAAI,EAAE;AACxD;AAEO,SAAS,oBAA0B;AACxC,QAAMA,MAAK,MAAM;AACjB,EAAAA,IAAG,QAAQ,sBAAsB,EAAE,IAAI;AACvC,EAAAA,IAAG,QAAQ,sBAAsB,EAAE,IAAI;AACzC;;;AChEO,SAAS,cAAc,QAOlB;AACV,QAAMC,MAAK,MAAM;AACjB,QAAM,SAASA,IACZ;AAAA,IACC;AAAA;AAAA,EAEF,EACC;AAAA,IACC,OAAO;AAAA,IACP,OAAO;AAAA,IACP,OAAO;AAAA,IACP,OAAO;AAAA,IACP,OAAO,cAAc;AAAA,IACrB,OAAO,WAAW,KAAK,UAAU,OAAO,QAAQ,IAAI;AAAA,EACtD;AAEF,SAAOA,IACJ,QAAQ,qCAAqC,EAC7C,IAAI,OAAO,eAAe;AAC/B;AAEO,SAAS,YAAY,WAA8B;AACxD,QAAMA,MAAK,MAAM;AACjB,SAAOA,IACJ,QAAQ,yDAAyD,EACjE,IAAI,SAAS;AAClB;AAEO,SAAS,wBACd,WACA,WACM;AACN,QAAMA,MAAK,MAAM;AACjB,EAAAA,IAAG;AAAA,IACD;AAAA,EACF,EAAE,IAAI,WAAW,SAAS;AAC5B;;;ACrDA,SAAS,WAAW,OAAkB,MAAsC;AAC1E,QAAM,QAAQ,KAAK,CAAC,MAAM,QAAQ,KAAK,CAAC,IAAI,KAAK,CAAC;AAClD,QAAM,OAAO,SAAS,KAAK;AAC3B,SAAO,GAAG,KAAK,WAAW,KAAK,KAAK,GAAG;AACzC;AAEO,SAAS,oBAAoB,OAAkB,MAAsC;AAC1F,SAAO,2CAA2C,WAAW,OAAO,IAAI,CAAC;AAC3E;AAEO,SAAS,iBACd,OACA,qBACA,MACQ;AACR,SAAO,GAAG,oBAAoB,OAAO,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA,EAI1C,mBAAmB;AAAA;AAAA;AAGrB;AAEO,SAAS,aAAa,OAAkB,MAAsC;AACnF,QAAM,QAAQ,WAAW,OAAO,IAAI;AACpC,SAAO,uCAAuC,KAAK;AAAA;AAAA;AAAA;AAAA,uDAIE,KAAK;AAAA;AAAA;AAAA,2BAGjC,KAAK;AAChC;AAEO,SAAS,kBACd,OACA,qBACA,MACQ;AACR,QAAM,QAAQ,WAAW,OAAO,IAAI;AACpC,SAAO,GAAG,aAAa,OAAO,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA,EAInC,mBAAmB;AAAA;AAAA,iDAE4B,KAAK;AACtD;AAEO,SAAS,aACd,qBACQ;AACR,SAAO;AAAA;AAAA,EAEP,mBAAmB;AAAA;AAAA;AAGrB;AAEO,IAAM,mBAAmB;AAEzB,SAAS,0BACd,UACQ;AACR,SAAO,SACJ,IAAI,CAAC,MAAM;AACV,QAAI;AACJ,QAAI,EAAE,SAAS,QAAQ;AACrB,cAAQ;AAAA,IACV,WAAW,iBAAiB,EAAE,IAAI,GAAG;AACnC,cAAQ,SAAS,EAAE,IAAI,EAAE;AAAA,IAC3B,WAAW,EAAE,SAAS,iBAAiB,EAAE,KAAK,GAAG;AAC/C,cAAQ,SAAS,EAAE,KAAK,EAAE;AAAA,IAC5B,OAAO;AACL,cAAQ,EAAE;AAAA,IACZ;AACA,WAAO,IAAI,KAAK,MAAM,EAAE,OAAO;AAAA,EACjC,CAAC,EACA,KAAK,MAAM;AAChB;;;ACpFA,SAAgB,gBAAgB;AAChC,SAAS,QAAQ,KAAK,MAAM,QAAQ,gBAAgB;AACpD,OAAO,eAAe;AAsIhB,SACE,KADF;AAzHN,IAAM,gBAA+B;AAAA,EACnC;AAAA,IACE,KAAK;AAAA,IACL,OAAO;AAAA,IACP,KAAK,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI;AAAA,IAC9B,MAAM;AAAA,IACN,UAAU,CAAC,UAAU;AACnB,UAAI;AACF,cAAM,QAAQ,MAAM,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC;AAClD,0BAAkB,KAAK;AACvB,eAAO;AAAA,MACT,SAAS,GAAQ;AACf,eAAO,EAAE;AAAA,MACX;AAAA,IACF;AAAA,EACF;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,OAAO;AAAA,IACP,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,IACrB,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,OAAO;AAAA,IACP,KAAK,CAAC,MAAM,EAAE,MAAM;AAAA,IACpB,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,OAAO;AAAA,IACP,KAAK,CAAC,MAAM,EAAE,OAAO;AAAA,IACrB,MAAM;AAAA,EACR;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,OAAO;AAAA,IACP,KAAK,CAAC,MAAM,OAAO,EAAE,WAAW,UAAU;AAAA,IAC1C,MAAM;AAAA,EACR;AACF;AAEA,IAAM,cAAc,KAAK,IAAI,GAAG,cAAc,IAAI,CAAC,MAAM,EAAE,MAAM,MAAM,CAAC;AASjE,SAAS,mBAAmB,EAAE,UAAU,QAAQ,GAA4B;AACjF,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,MAAM,WAAW,CAAC;AACvD,QAAM,CAAC,eAAe,gBAAgB,IAAI,SAAS,CAAC;AACpD,QAAM,CAAC,MAAM,OAAO,IAAI,SAAmB,QAAQ;AACnD,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,EAAE;AAC7C,QAAM,CAAC,cAAc,eAAe,IAAI,SAAwB,IAAI;AAEpE;AAAA,IACE,CAAC,OAAO,QAAQ;AACd,UAAI,IAAI,SAAS;AACf,wBAAgB,IAAI;AACpB,yBAAiB,CAAC,MAAO,IAAI,IAAI,IAAI,IAAI,cAAc,SAAS,CAAE;AAAA,MACpE,WAAW,IAAI,WAAW;AACxB,wBAAgB,IAAI;AACpB,yBAAiB,CAAC,MAAO,IAAI,cAAc,SAAS,IAAI,IAAI,IAAI,CAAE;AAAA,MACpE,WAAW,IAAI,QAAQ;AACrB,cAAM,QAAQ,cAAc,aAAa;AACzC,qBAAa,MAAM,IAAI,MAAM,CAAC;AAC9B,wBAAgB,IAAI;AACpB,gBAAQ,MAAM;AAAA,MAChB,WAAW,IAAI,UAAU,UAAU,KAAK;AACtC,gBAAQ;AAAA,MACV;AAAA,IACF;AAAA,IACA,EAAE,UAAU,YAAY,SAAS,SAAS;AAAA,EAC5C;AAEA;AAAA,IACE,CAAC,QAAQ,QAAQ;AACf,UAAI,IAAI,QAAQ;AACd,gBAAQ,QAAQ;AAAA,MAClB;AAAA,IACF;AAAA,IACA,EAAE,UAAU,YAAY,SAAS,OAAO;AAAA,EAC1C;AAEA,QAAM,mBAAmB,CAAC,UAAkB;AAC1C,UAAM,QAAQ,cAAc,aAAa;AAEzC,QAAI,MAAM,SAAS,UAAU;AAC3B,YAAM,IAAI,OAAO,KAAK;AACtB,UAAI,CAAC,OAAO,UAAU,CAAC,KAAK,IAAI,GAAG;AACjC,wBAAgB,mCAAmC;AACnD,gBAAQ,QAAQ;AAChB;AAAA,MACF;AAAA,IACF;AAEA,QAAI,MAAM,UAAU;AAClB,YAAM,QAAQ,MAAM,SAAS,KAAK;AAClC,UAAI,OAAO;AACT,wBAAgB,UAAU,KAAK,EAAE;AACjC,gBAAQ,QAAQ;AAChB;AAAA,MACF;AAAA,IACF;AAEA,QAAI;AACF,YAAM,UAAU,eAAe,MAAM,KAAK,KAAK;AAC/C,gBAAU,OAAO;AACjB,sBAAgB,SAAS,MAAM,GAAG,MAAM,KAAK,EAAE;AAAA,IACjD,SAAS,GAAQ;AACf,sBAAgB,UAAU,EAAE,OAAO,EAAE;AAAA,IACvC;AAEA,YAAQ,QAAQ;AAAA,EAClB;AAEA,SACE,qBAAC,OAAI,eAAc,UACjB;AAAA,yBAAC,OAAI,cAAc,GACjB;AAAA,0BAAC,QAAK,MAAI,MAAC,2BAAa;AAAA,MACxB,oBAAC,QAAK,UAAQ,MAAC,8CAAsB;AAAA,OACvC;AAAA,IAEC,cAAc,IAAI,CAAC,OAAO,MAAM;AAC/B,YAAM,WAAW,MAAM;AACvB,YAAM,UAAU,WAAW,OAAO;AAClC,YAAM,eAAe,MAAM,IAAI,MAAM;AAErC,aACE,qBAAC,OAAoB,YAAY,GAC/B;AAAA,6BAAC,QAAK,OAAO,WAAW,SAAS,QAAW,MAAM,UAC/C;AAAA;AAAA,UACA,MAAM,MAAM,OAAO,WAAW;AAAA,WACjC;AAAA,QACA,oBAAC,QAAK,UAAQ,MAAC,iBAAG;AAAA,QACjB,SAAS,UAAU,WAClB;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,YACP,UAAU;AAAA,YACV,UAAU;AAAA,YACV,YAAU;AAAA;AAAA,QACZ,IAEA,oBAAC,QAAK,OAAM,SAAS,wBAAa;AAAA,WAd5B,MAAM,GAgBhB;AAAA,IAEJ,CAAC;AAAA,IAEA,gBACC,oBAAC,OAAI,WAAW,GAAG,YAAY,GAC7B,8BAAC,QAAK,OAAO,aAAa,WAAW,OAAO,IAAI,QAAQ,SACrD,wBACH,GACF;AAAA,IAGF,oBAAC,OAAI,WAAW,GAAG,YAAY,GAC7B,8BAAC,QAAK,UAAQ,MACX,mBAAS,SACN,2BACA,iDACN,GACF;AAAA,KACF;AAEJ;AAGA,SAAS,yBAAyB;AAChC,QAAM,EAAE,KAAK,IAAI,OAAO;AACxB,SAAO,oBAAC,sBAAmB,UAAU,MAAM,SAAS,MAAM;AAC5D;AAEO,SAAS,oBAAoB;AAClC,SAAO,OAAO,oBAAC,0BAAuB,CAAE;AAC1C;;;AX1FS,gBAAAC,MAiBD,QAAAC,aAjBC;AA5ET,OAAO,IAAI,eAAe,CAAQ;AA8BlC,IAAM,kBAAkB;AAExB,SAAS,aAAa,MAAqE;AACzF,QAAM,QAAQ,KAAK,YAAY,EAAE,MAAM,eAAe;AACtD,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,CAAC,WAAW,OAAO,MAAM,IAAI;AACnC,MAAI,iBAAiB,KAAK,KAAK,iBAAiB,MAAM,KAAK,UAAU,QAAQ;AAC3E,WAAO,EAAE,MAAM,CAAC,OAAO,MAAM,GAAG,MAAM,KAAK,MAAM,UAAU,MAAM,EAAE,KAAK,EAAE;AAAA,EAC5E;AACA,SAAO;AACT;AAEA,SAAS,WAAW,OAA4B;AAC9C,QAAM,QAAQ,MAAM,YAAY;AAChC,MAAI,MAAM,WAAW,UAAU,GAAG;AAChC,UAAM,OAAO,MAAM,MAAM,CAAC,EAAE,KAAK;AAEjC,UAAMC,SAAQ,aAAa,IAAI;AAC/B,QAAIA,QAAO;AACT,aAAO,EAAE,QAAQA,OAAM,MAAM,QAAQA,OAAM,MAAM,SAAS,KAAK;AAAA,IACjE;AACA,WAAO,EAAE,QAAQ,QAAQ,QAAQ,MAAM,SAAS,KAAK;AAAA,EACvD;AAEA,QAAM,QAAQ,aAAa,KAAK;AAChC,MAAI,OAAO;AAET,UAAM,aAAa,MAAM,KAAK,YAAY;AAC1C,QAAI,WAAW,WAAW,UAAU,GAAG;AACrC,aAAO,EAAE,QAAQ,MAAM,MAAM,QAAQ,MAAM,KAAK,MAAM,CAAC,EAAE,KAAK,GAAG,SAAS,KAAK;AAAA,IACjF;AACA,WAAO,EAAE,QAAQ,MAAM,MAAM,QAAQ,MAAM,MAAM,SAAS,MAAM;AAAA,EAClE;AAEA,aAAW,SAAS,iBAAiB,GAAG;AACtC,QAAI,MAAM,WAAW,GAAG,KAAK,GAAG,KAAK,MAAM,WAAW,GAAG,KAAK,IAAI,GAAG;AACnE,aAAO,EAAE,QAAQ,OAAO,QAAQ,MAAM,MAAM,MAAM,QAAQ,GAAG,IAAI,CAAC,EAAE,KAAK,GAAG,SAAS,MAAM;AAAA,IAC7F;AAAA,EACF;AACA,SAAO,EAAE,QAAQ,QAAQ,QAAQ,OAAO,SAAS,MAAM;AACzD;AAIA,SAAS,iBAAiB,EAAE,KAAK,GAAqB;AACpD,QAAM,WAAY,OAAO,MAAM,IAAI,EAAa,QAAQ;AACxD,SAAO,gBAAAF,KAACG,OAAA,EAAM,oBAAS;AACzB;AAEA,SAAS,mBAAmB;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,QAAM,aAAa,SAAS,KAAK;AAEjC,MAAI,OAAO;AACT,WACE,gBAAAF,MAACG,MAAA,EAAI,eAAc,UAAS,YAAY,GAAG,cAAc,GACvD;AAAA,sBAAAH,MAACE,OAAA,EAAK,OAAM,OAAM,MAAI,MACnB;AAAA,mBAAW;AAAA,QAAY;AAAA,SAC1B;AAAA,MACA,gBAAAH,KAACI,MAAA,EAAI,YAAY,GACf,0BAAAJ,KAACG,OAAA,EAAK,OAAM,OAAO,mBAAQ,GAC7B;AAAA,OACF;AAAA,EAEJ;AAEA,SACE,gBAAAF,MAACG,MAAA,EAAI,eAAc,UAAS,YAAY,GAAG,cAAc,GACvD;AAAA,oBAAAH,MAACE,OAAA,EAAK,OAAO,WAAW,OAAO,MAAI,MAChC;AAAA,iBAAW;AAAA,MAAY;AAAA,OAC1B;AAAA,IACA,gBAAAH,KAACI,MAAA,EAAI,YAAY,GACf,0BAAAJ,KAAC,oBAAiB,MAAM,SAAS,GACnC;AAAA,KACF;AAEJ;AAEA,SAAS,OAAO,EAAE,UAAU,GAA0B;AACpD,SACE,gBAAAC,MAACG,MAAA,EAAI,cAAc,GACjB;AAAA,oBAAAJ,KAACG,OAAA,EAAK,UAAQ,MAAE,2BAAM;AAAA,IACtB,gBAAAH,KAACG,OAAA,EAAK,MAAI,MAAC,sBAAQ;AAAA,IACnB,gBAAAH,KAACG,OAAA,EAAK,UAAQ,MAAE,oCAAe;AAAA,IAC/B,gBAAAH,KAACG,OAAA,EAAK,OAAM,QAAQ,oBAAU,MAAM,GAAG,CAAC,GAAE;AAAA,IAC1C,gBAAAH,KAACG,OAAA,EAAK,UAAQ,MAAE,gBAAM,SAAI,OAAO,EAAE,GAAE;AAAA,KACvC;AAEJ;AAEA,SAAS,YAAY;AACnB,QAAM,MAAM;AACZ,QAAM,WAAW;AAAA,IACf,CAAC,gBAAgB,sBAAsB;AAAA,IACvC,CAAC,uBAAuB,oBAAoB;AAAA,IAC5C,CAAC,yBAAyB,oBAAoB;AAAA,IAC9C,CAAC,uCAAuC,sBAAsB;AAAA,EAChE;AACA,SACE,gBAAAF,MAACG,MAAA,EAAI,eAAc,UAAS,YAAY,GAAG,cAAc,GACtD;AAAA,aAAS,IAAI,CAAC,CAAC,KAAK,IAAI,MACvB,gBAAAH,MAACE,OAAA,EAAe,UAAQ,MAAE;AAAA,UAAK,OAAO,GAAG;AAAA,MAAG;AAAA,MAAM;AAAA,SAAvC,GAA4C,CACxD;AAAA,IACD,gBAAAH,KAACG,OAAA,EAAK,UAAQ,MAAE,4BAAiB;AAAA,KACnC;AAEJ;AAEA,SAAS,YAAY,EAAE,QAAQ,GAAwB;AACrD,SACE,gBAAAF,MAACG,MAAA,EAAI,YAAY,GAAG,cAAc,GAChC;AAAA,oBAAAH,MAACE,OAAA,EAAK,MAAI,MAAC,OAAM,SAAQ;AAAA;AAAA,MAClB;AAAA,OACP;AAAA,IACA,gBAAAH,KAACG,OAAA,EAAM,mBAAQ;AAAA,KACjB;AAEJ;AAEA,SAAS,kBAAkB,EAAE,MAAM,GAAyB;AAC1D,QAAM,aAAa,SAAS,KAAK;AACjC,SACE,gBAAAF,MAACG,MAAA,EAAI,YAAY,GACf;AAAA,oBAAAJ,KAACG,OAAA,EAAK,OAAO,WAAW,OACtB,0BAAAH,KAAC,WAAQ,MAAK,QAAO,GACvB;AAAA,IACA,gBAAAC,MAACE,OAAA,EAAK,OAAO,WAAW,OAAO;AAAA;AAAA,MAAE,WAAW;AAAA,MAAY;AAAA,OAAe;AAAA,KACzE;AAEJ;AAEA,SAAS,iBAAiB,EAAE,OAAO,UAAU,GAAyC;AACpF,SACE,gBAAAH,KAACI,MAAA,EAAI,YAAY,GAAG,cAAc,GAChC,0BAAAH,MAACE,OAAA,EAAK,OAAM,UAAS,MAAI,MAAC;AAAA;AAAA,IACN;AAAA,IAAM;AAAA,IAAE;AAAA,KAC5B,GACF;AAEJ;AAEA,SAAS,mBAAmB;AAC1B,SACE,gBAAAH,KAACI,MAAA,EAAI,YAAY,GAAG,cAAc,GAChC,0BAAAJ,KAACG,OAAA,EAAK,OAAM,SAAQ,MAAI,MAAC,gCAEzB,GACF;AAEJ;AAEA,SAAS,YAAY;AAAA,EACnB;AACF,GAEG;AACD,QAAM,CAAC,OAAO,QAAQ,IAAIE,UAAS,EAAE;AAErC,QAAM,eAAe;AAAA,IACnB,CAAC,cAAsB;AACrB,UAAI,UAAU,KAAK,GAAG;AACpB,iBAAS,UAAU,KAAK,CAAC;AACzB,iBAAS,EAAE;AAAA,MACb;AAAA,IACF;AAAA,IACA,CAAC,QAAQ;AAAA,EACX;AAEA,SACE,gBAAAJ,MAACG,MAAA,EAAI,YAAY,GACf;AAAA,oBAAAJ,KAACG,OAAA,EAAK,MAAI,MAAC,OAAM,SACd,gBACH;AAAA,IACA,gBAAAH;AAAA,MAACM;AAAA,MAAA;AAAA,QACC;AAAA,QACA,UAAU;AAAA,QACV,UAAU;AAAA,QACV,YAAU;AAAA;AAAA,IACZ;AAAA,KACF;AAEJ;AAIA,SAAS,IAAI;AAAA,EACX;AAAA,EACA,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,QAAQ;AAAA,EACR,gBAAAC;AAAA,EACA,SAAS;AACX,GAAa;AACX,QAAM,EAAE,KAAK,IAAIC,QAAO;AACxB,QAAM,CAAC,WAAW,YAAY,IAAIH,UAAS,MAAM,qBAAqB,OAAO,EAAE,CAAC;AAChF,QAAM,CAAC,UAAU,WAAW,IAAIA,UAAoBE,mBAAkB,CAAC,CAAC;AACxE,QAAM,CAAC,OAAO,QAAQ,IAAIF;AAAA,IACxB,gBAAgB,YAAY;AAAA,EAC9B;AACA,QAAM,CAAC,MAAM,OAAO,IAAIA,UAAiC,WAAW;AACpE,QAAM,CAAC,aAAa,cAAc,IAAIA,UAAoC,kBAAkB;AAC5F,QAAM,CAAC,QAAQ,SAAS,IAAIA,UAAwB,aAAa;AACjE,QAAM,CAAC,gBAAgB,iBAAiB,IAAIA,UAAsB,CAAC,CAAC;AACpE,QAAM,CAAC,iBAAiB,kBAAkB,IAAIA,UAAS,CAAC;AACxD,QAAM,CAAC,kBAAkB,mBAAmB,IAAIA,UAAS,KAAK;AAC9D,QAAM,CAAC,eAAe,gBAAgB,IAAIA,UAAwB,IAAI;AACtE,QAAM,CAAC,UAAU,WAAW,IAAIA,UAAS,MAAM;AAC7C,QAAIE,mBAAkBA,gBAAe,SAAS,GAAG;AAC/C,aAAO,KAAK,IAAI,GAAGA,gBAAe,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI;AAAA,IAC3D;AACA,WAAO;AAAA,EACT,CAAC;AAED,QAAM,oBAAoB,OAAO,CAAC,CAAC,iBAAiB;AACpD,QAAM,gBAAgB,CAAC,OAAe;AACpC,QAAI,CAAC,kBAAkB,SAAS;AAC9B,oBAAc,IAAI,QAAQ,IAAI,CAAC;AAC/B,wBAAkB,UAAU;AAAA,IAC9B;AAAA,EACF;AAGA,YAAU,MAAM;AACd,QAAI,iBAAiB,UAAU,WAAW;AACxC,UAAI,gBAAgB;AAClB,sBAAc,aAAa;AAAA,MAC7B,OAAO;AACL,iBAAS,aAAa;AAAA,MACxB;AAAA,IACF;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,WAAW,OAA+B,IAAI;AACpD,QAAM,kBAAkB,OAAsB,IAAI;AAGlD,EAAAE,UAAS,CAAC,OAAO,QAAQ;AACvB,QAAI,IAAI,QAAQ,UAAU,KAAK;AAC7B,eAAS,SAAS,MAAM;AACxB,cAAQ;AACR,WAAK;AAAA,IACP;AACA,QAAI,IAAI,UAAU,UAAU,WAAW;AACrC,eAAS,SAAS,MAAM;AACxB,eAAS,UAAU;AAGnB,UAAI,gBAAgB,YAAY,MAAM;AACpC,gCAAwB,WAAW,gBAAgB,OAAO;AAC1D,cAAM,YAAY,gBAAgB;AAClC,oBAAY,CAAC,SAAS,KAAK,OAAO,CAAC,MAAM,EAAE,QAAQ,SAAS,CAAC;AAC7D,wBAAgB,UAAU;AAAA,MAC5B;AAEA,wBAAkB,CAAC,CAAC;AACpB,yBAAmB,CAAC;AACpB,uBAAiB,cAAc;AAC/B,eAAS,OAAO;AAAA,IAClB;AAAA,EACF,CAAC;AAGD,QAAM,YAAY,OAChB,iBACA,OACA,QACA,gBACA,WAAW,UACY;AAEvB,UAAM,eAA4B,MAAM,QAAQ,MAAM,IAClD,SACA,WAAW,SACT,CAAC,GAAG,IAAI,IACR,CAAC,MAAM;AACb,sBAAkB,YAAY;AAE9B,UAAM,UAAU;AAAA,MACd,gBAAgB,IAAI,CAAC,OAAO;AAAA,QAC1B,MAAM,EAAE;AAAA,QACR,OAAO,iBAAiB,EAAE,IAAI,IAAI,EAAE,OAAO;AAAA,QAC3C,SAAS,EAAE;AAAA,MACb,EAAE;AAAA,IACJ;AAEA,UAAM,MAAM,QAAQ,IAAI;AACxB,UAAM,eAAe,UAAU,KAAK,CAAC;AAErC,UAAM,aAAa,gBAAgB,gBAAgB,SAAS,CAAC,GAAG,WAAW;AAC3E,UAAM,gBAAgB,CAAC,MAAM,QAAQ,MAAM,KAAK,WAAW;AAE3D,UAAM,aAAqC,MAAM,QAAQ,MAAM,IAAI,SAAS;AAE5E,UAAM,cAAc,CAAC,WAAsB;AACzC,UAAI,eAAgB,QAAO;AAC3B,UAAI,cAAe,QAAO;AAC1B,UAAI,aAAc,QAAO;AACzB,aAAO;AAAA,IACT;AAEA,UAAM,oBAAoB,CAAC,UAAqB;AAC9C,UAAI,eAAe;AACjB,eAAO,UAAU,aAAa,OAAO,IAAI;AAAA,MAC3C;AACA,UAAI,UAAU;AACZ,YAAI,aAAc,QAAO,aAAa,OAAO,UAAU;AACvD,eAAO,kBAAkB,OAAO,SAAS,UAAU;AAAA,MACrD;AACA,UAAI,aAAc,QAAO,oBAAoB,OAAO,UAAU;AAC9D,aAAO,iBAAiB,OAAO,SAAS,UAAU;AAAA,IACpD;AAEA,UAAM,KAAK,IAAI,gBAAgB;AAC/B,aAAS,UAAU;AAEnB,UAAM,UAAoF,CAAC;AAC3F,UAAM,WAAiC,CAAC;AAExC,eAAW,SAAS,cAAc;AAChC,YAAM,aAAa,SAAS,KAAK;AACjC,eAAS;AAAA,QACP,WAAW,IAAI;AAAA,UACb,QAAQ,YAAY,KAAK;AAAA,UACzB,cAAc,kBAAkB,KAAK;AAAA,UACrC,OAAO,YAAY,KAAK;AAAA,UACxB;AAAA,UACA,QAAQ,GAAG;AAAA,QACb,CAAC,EAAE;AAAA,UACD,CAAC,UAAU;AAAE,oBAAQ,KAAK,EAAE,OAAO,QAAQ,EAAE,QAAQ,aAAa,MAAM,EAAE,CAAC;AAAA,UAAG;AAAA,UAC9E,CAAC,WAAW;AAAE,oBAAQ,KAAK,EAAE,OAAO,QAAQ,EAAE,QAAQ,YAAY,OAAO,EAAE,CAAC;AAAA,UAAG;AAAA,QACjF;AAAA,MACF;AAAA,IACF;AAEA,UAAM,QAAQ,IAAI,QAAQ;AAC1B,aAAS,UAAU;AAGnB,QAAI,GAAG,OAAO,QAAS,QAAO,CAAC;AAE/B,sBAAkB,CAAC,CAAC;AAEpB,UAAM,cAAyB,CAAC;AAEhC,eAAW,EAAE,OAAO,OAAO,KAAK,SAAS;AACvC,UAAI,OAAO,WAAW,aAAa;AACjC,cAAM,OAAO,OAAO;AACpB,cAAM,MAAe;AAAA,UACnB,MAAM;AAAA,UACN,SAAS,KAAK,SAAS,KAAK;AAAA,UAC5B;AAAA,UACA,OAAO,CAAC,CAAC,KAAK;AAAA,QAChB;AACA,oBAAY,KAAK,GAAG;AACpB,sBAAc;AAAA,UACZ;AAAA,UACA,MAAM;AAAA,UACN,SAAS,KAAK,SAAS,KAAK;AAAA,UAC5B;AAAA,UACA,YAAY,KAAK;AAAA,QACnB,CAAC;AAAA,MACH,OAAO;AACL,cAAM,WAAW,OAAO,QAAQ,WAAW;AAC3C,cAAM,MAAe;AAAA,UACnB,MAAM;AAAA,UACN,SAAS;AAAA,UACT;AAAA,UACA,OAAO;AAAA,QACT;AACA,oBAAY,KAAK,GAAG;AACpB,sBAAc;AAAA,UACZ;AAAA,UACA,MAAM;AAAA,UACN,SAAS,WAAW,QAAQ;AAAA,UAC5B;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,OAAO,aAAqB;AAC3C,UAAM,EAAE,QAAQ,QAAQ,QAAQ,IAAI,WAAW,QAAQ;AAEvD,QAAI,SAAS;AACX,aAAO,cAAc,QAAQ,MAAM,QAAQ,MAAM,IAAI,SAAS,MAAS;AAAA,IACzE;AAEA,UAAM,eAAe;AACrB,oBAAgB,UAAU;AAG1B,kBAAc,SAAS;AACvB,QAAI,iBAAiB,GAAG;AACtB,YAAM,QAAQ,OAAO,SAAS,KAAK,OAAO,MAAM,GAAG,EAAE,IAAI,QAAQ;AACjE,yBAAmB,WAAW,KAAK;AAAA,IACrC;AAGA,UAAM,UAAmB;AAAA,MACvB,MAAM;AAAA,MACN,SAAS;AAAA,MACT,OAAO;AAAA,IACT;AACA,gBAAY,CAAC,SAAS,CAAC,GAAG,MAAM,OAAO,CAAC;AACxC,kBAAc;AAAA,MACZ;AAAA,MACA,MAAM;AAAA,MACN,SAAS;AAAA,MACT,OAAO;AAAA,IACT,CAAC;AAED,UAAM,cAAc,CAAC,GAAG,UAAU,OAAO;AACzC,UAAM,cAAc,MAAM,UAAU,aAAa,cAAc,MAAM;AAGrE,QAAI,YAAY,WAAW,EAAG;AAE9B,gBAAY,CAAC,SAAS,CAAC,GAAG,MAAM,GAAG,WAAW,CAAC;AAC/C,gBAAY,eAAe,CAAC;AAC5B,oBAAgB,UAAU;AAE1B,iBAAa,SAAS;AACtB,aAAS,OAAO;AAAA,EAClB;AAEA,QAAM,gBAAgB,OAAO,QAAgB,cAAuC;AAClF,UAAM,mBAA2B,aAAa;AAC9C,wBAAoB,KAAK;AACzB,QAAI,eAAe;AACnB,oBAAgB,UAAU;AAG1B,kBAAc,SAAS;AACvB,QAAI,iBAAiB,GAAG;AACtB,YAAM,QAAQ,OAAO,SAAS,KAAK,OAAO,MAAM,GAAG,EAAE,IAAI,QAAQ;AACjE,yBAAmB,WAAW,KAAK;AAAA,IACrC;AAGA,UAAM,UAAmB;AAAA,MACvB,MAAM;AAAA,MACN,SAAS,WAAW,MAAM;AAAA,MAC1B,OAAO;AAAA,IACT;AACA,gBAAY,CAAC,SAAS,CAAC,GAAG,MAAM,OAAO,CAAC;AACxC,kBAAc;AAAA,MACZ;AAAA,MACA,MAAM;AAAA,MACN,SAAS,WAAW,MAAM;AAAA,MAC1B,OAAO;AAAA,IACT,CAAC;AAED,QAAI,cAAc,CAAC,GAAG,UAAU,OAAO;AAEvC,aAAS,OAAO,GAAG,QAAQ,OAAO,WAAW,YAAY,QAAQ;AAC/D,yBAAmB,IAAI;AAEvB,YAAM,cAAc,MAAM;AAAA,QACxB;AAAA,QACA;AAAA,QACA;AAAA,QACA,SAAS,IAAI,SAAS;AAAA,QACtB;AAAA,MACF;AAGA,UAAI,YAAY,WAAW,EAAG;AAE9B,kBAAY,CAAC,SAAS,CAAC,GAAG,MAAM,GAAG,WAAW,CAAC;AAC/C,oBAAc,CAAC,GAAG,aAAa,GAAG,WAAW;AAC7C;AAGA,YAAM,aAAa,aAAa;AAChC,YAAM,iBAAiB,WAAW,IAAI,CAAC,UAAU;AAC/C,cAAM,MAAM,YAAY,KAAK,CAAC,MAAM,EAAE,SAAS,SAAS,CAAC,EAAE,KAAK;AAChE,eAAO,KAAK,QAAQ,SAAS,gBAAgB,KAAK;AAAA,MACpD,CAAC;AAED,UAAI,eAAe,MAAM,OAAO,GAAG;AACjC,4BAAoB,IAAI;AACxB;AAAA,MACF;AAAA,IACF;AAEA,gBAAY,YAAY;AACxB,uBAAmB,CAAC;AACpB,oBAAgB,UAAU;AAC1B,iBAAa,SAAS;AACtB,aAAS,OAAO;AAAA,EAClB;AAEA,QAAM,eAAe,CAAC,UAAkB;AACtC,qBAAiB,IAAI;AAErB,QAAI,UAAU,SAAS;AACrB,cAAQ;AACR,WAAK;AACL;AAAA,IACF;AAEA,QAAI,UAAU,SAAS;AACrB;AAAA,QACE;AAAA,UACE;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF,EAAE,KAAK,IAAI;AAAA,MACb;AACA;AAAA,IACF;AAEA,QAAI,UAAU,WAAW;AACvB,eAAS,QAAQ;AACjB;AAAA,IACF;AAEA,QAAI,UAAU,QAAQ;AACpB,YAAM,QAAQ,OAAO,EAAE;AACvB,wBAAkB,UAAU;AAC5B,mBAAa,KAAK;AAClB,kBAAY,CAAC,CAAC;AACd,kBAAY,CAAC;AACb,0BAAoB,KAAK;AACzB,yBAAmB,CAAC;AACpB,uBAAiB,sBAAsB;AACvC;AAAA,IACF;AAEA,QAAI,UAAU,SAAS;AACrB,UAAI;AACF,cAAM,KAAK,iBAAiB,QAAQ;AACpC,wBAAgB,EAAE;AAClB,yBAAiB,mCAAmC;AAAA,MACtD,QAAQ;AACN,yBAAiB,8BAA8B;AAAA,MACjD;AACA;AAAA,IACF;AAEA,wBAAoB,KAAK;AACzB,aAAS,SAAS;AAClB,aAAS,KAAK;AAAA,EAChB;AAEA,SACE,gBAAAR,MAACG,MAAA,EAAI,eAAc,UACjB;AAAA,oBAAAJ,KAAC,UAAO,WAAsB;AAAA,IAE7B,SAAS,WAAW,KAAK,UAAU,WAAW,gBAAAA,KAAC,aAAU;AAAA,IAEzD,SAAS,IAAI,CAAC,KAAK,MAAM;AACxB,UAAI,IAAI,SAAS,QAAQ;AACvB,eAAO,gBAAAA,KAAC,eAAoB,SAAS,IAAI,WAAhB,CAAyB;AAAA,MACpD;AACA,UAAI,iBAAiB,IAAI,IAAI,GAAG;AAC9B,eACE,gBAAAA;AAAA,UAAC;AAAA;AAAA,YAEC,OAAO,IAAI;AAAA,YACX,SAAS,IAAI;AAAA,YACb,OAAO,IAAI;AAAA;AAAA,UAHN;AAAA,QAIP;AAAA,MAEJ;AACA,aAAO;AAAA,IACT,CAAC;AAAA,IAEA,kBAAkB,KAAK,eAAe,SAAS,KAC9C,gBAAAA,KAAC,oBAAiB,OAAO,iBAAiB,WAAW,OAAO,WAAW,YAAY;AAAA,IAGpF,eAAe,SAAS,KACvB,gBAAAA,KAACI,MAAA,EAAI,eAAc,UAAS,cAAc,GACvC,yBAAe,IAAI,CAAC,UACnB,gBAAAJ,KAAC,qBAA8B,SAAP,KAAqB,CAC9C,GACH;AAAA,IAGD,oBAAoB,gBAAAA,KAAC,oBAAiB;AAAA,IAEtC,iBACC,gBAAAA,KAACI,MAAA,EAAI,YAAY,GACf,0BAAAJ,KAACG,OAAA,EAAK,UAAQ,MAAC,QAAM,MAAE,yBAAc,GACvC;AAAA,IAGD,UAAU,YACT,gBAAAH;AAAA,MAAC;AAAA;AAAA,QACC,UAAU,UAAU;AAAA,QACpB,SAAS,MAAM;AACb,gBAAM,UAAU,WAAW;AAC3B,oBAAU,OAAO;AACjB,cAAI;AACF,oBAAQ,kBAAkB,QAAQ,MAAM,CAAC;AAAA,UAC3C,QAAQ;AAAA,UAER;AACA,yBAAe,CAAC,UAAU;AAAA,YACxB,GAAG;AAAA,YACH,QAAQ,QAAQ,OAAO;AAAA,YACvB,OAAO,QAAQ,MAAM;AAAA,YACrB,QAAQ,QAAQ,OAAO;AAAA,UACzB,EAAE;AACF,mBAAS,OAAO;AAAA,QAClB;AAAA;AAAA,IACF;AAAA,IAGD,UAAU,WAAW,gBAAAA,KAAC,eAAY,UAAU,cAAc;AAAA,KAC7D;AAEJ;AAIO,SAAS,SAAS,OAAiB;AACxC,SAAOU,QAAO,gBAAAV,KAAC,OAAK,GAAG,OAAO,CAAE;AAClC;AAEO,SAAS,uBAAuB,WAA2B;AAChE,QAAM,aAAa,YAAY,SAAS;AACxC,QAAM,WAAW,WAAW,IAAI,CAAC,OAAO;AAAA,IACtC,MAAM,EAAE;AAAA,IACR,SAAS,EAAE;AAAA,IACX,OAAO,EAAE;AAAA,EACX,EAAE;AACF,SAAO,iBAAiB,QAAQ;AAClC;AAEO,SAAS,eAAe,WAAyB;AACtD,QAAM,aAAa,YAAY,SAAS;AACxC,QAAM,WAAsB,WAAW,IAAI,CAAC,OAAO;AAAA,IACjD,MAAM,EAAE;AAAA,IACR,SAAS,EAAE;AAAA,IACX,OAAO,EAAE;AAAA,EACX,EAAE;AAEF,QAAM,EAAE,QAAQ,IAAIU;AAAA,IAClB,gBAAAT,MAACG,MAAA,EAAI,eAAc,UACjB;AAAA,sBAAAJ,KAAC,UAAO,WAAsB;AAAA,MAC7B,SAAS,IAAI,CAAC,KAAK,MAAM;AACxB,YAAI,IAAI,SAAS,QAAQ;AACvB,iBAAO,gBAAAA,KAAC,eAAoB,SAAS,IAAI,WAAhB,CAAyB;AAAA,QACpD;AACA,YAAI,iBAAiB,IAAI,IAAI,GAAG;AAC9B,iBACE,gBAAAA,KAAC,sBAA2B,OAAO,IAAI,MAAM,SAAS,IAAI,WAAjC,CAA0C;AAAA,QAEvE;AACA,eAAO;AAAA,MACT,CAAC;AAAA,MACD,gBAAAA,KAACI,MAAA,EACC,0BAAAJ,KAACG,OAAA,EAAK,UAAQ,MAAE,mBAAI,OAAO,EAAE,GAAE,GACjC;AAAA,OACF;AAAA,EACF;AAEA,UAAQ;AACV;AAEO,SAAS,gBACd,UAOM;AACN,QAAM,EAAE,QAAQ,IAAIO;AAAA,IAClB,gBAAAV,KAACI,MAAA,EAAI,eAAc,UAChB,mBAAS,WAAW,IACnB,gBAAAJ,KAACG,OAAA,EAAK,UAAQ,MAAC,iCAAmB,IAElC,SAAS,IAAI,CAAC,MACZ,gBAAAF,MAACG,MAAA,EAAe,YAAY,GAC1B;AAAA,sBAAAJ,KAACG,OAAA,EAAK,OAAM,QAAQ,YAAE,GAAG,MAAM,GAAG,CAAC,GAAE;AAAA,MACrC,gBAAAH,KAACG,OAAA,EAAM,gBAAK;AAAA,MACZ,gBAAAH,KAACG,OAAA,EAAM,YAAE,SAAS,cAAa;AAAA,MAC/B,gBAAAH,KAACG,OAAA,EAAM,gBAAK;AAAA,MACZ,gBAAAH,KAACG,OAAA,EAAK,OAAO,EAAE,WAAW,WAAW,UAAU,QAAW,UAAU,EAAE,WAAW,UAC9E,YAAE,QACL;AAAA,MACA,gBAAAH,KAACG,OAAA,EAAM,gBAAK;AAAA,MACZ,gBAAAH,KAACG,OAAA,EAAK,UAAQ,MAAE,YAAE,YAAW;AAAA,SATrB,EAAE,EAUZ,CACD,GAEL;AAAA,EACF;AAEA,UAAQ;AACV;;;AF3uBA,QAAQ,GAAG,WAAW,MAAM;AAAE,UAAQ;AAAG,UAAQ,KAAK,CAAC;AAAG,CAAC;AAC3D,QAAQ,GAAG,UAAU,MAAM;AAAE,UAAQ;AAAG,UAAQ,KAAK,CAAC;AAAG,CAAC;AAE1D,SAAS,SAAS,MAAc,YAA6B;AAC3D,MAAI;AACF,IAAAQ,UAAS,GAAG,IAAI,cAAc,EAAE,OAAO,SAAS,CAAC;AACjD,WAAO;AAAA,EACT,QAAQ;AACN,YAAQ;AAAA,MACN,MAAM,IAAI,IAAI,IAAI,iCAAiC,UAAU,EAAE;AAAA,IACjE;AACA,WAAO;AAAA,EACT;AACF;AAEA,SAAS,UAAU,MAAoC;AACrD,MAAI,WAAW;AACf,aAAW,SAAS,MAAM;AACxB,UAAM,aAAa,SAAS,KAAK;AACjC,QAAI,CAAC,SAAS,WAAW,WAAW,WAAW,UAAU,GAAG;AAC1D,iBAAW;AAAA,IACb;AAAA,EACF;AACA,MAAI,CAAC,UAAU;AACb,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;AAEA,SAAS,iBAAiB,MAAW,QAA+D;AAClG,MAAI,KAAK,QAAQ;AACf,UAAM,QAAQ,KAAK,OAAO,MAAM,GAAG,EAAE,IAAI,CAAC,MAAc,EAAE,KAAK,CAAC;AAChE,WAAO,kBAAkB,KAAK;AAAA,EAChC;AACA,SAAO,kBAAkB,OAAO,MAAM;AACxC;AAEA,SAAS,mBACP,MACA,MACA,QAC2B;AAC3B,SAAO;AAAA,IACL,QAAQ,KAAK,eAAe,OAAO,OAAO;AAAA,IAC1C,OAAO,KAAK,cAAc,OAAO,MAAM;AAAA,IACvC,QAAQ,KAAK,eAAe,OAAO,OAAO;AAAA,EAC5C;AACF;AAEA,IAAM,UAAU,IAAI,QAAQ;AAE5B,QACG,KAAK,SAAS,EACd,YAAY,kDAAkD,EAC9D,QAAQ,OAAO,EACf,OAAO,mBAAmB,yDAAyD,EACnF,OAAO,0BAA0B,qBAAqB,EACtD,OAAO,yBAAyB,oBAAoB,EACpD,OAAO,0BAA0B,qBAAqB,EACtD,SAAS,eAAe,+BAA+B,EACvD,OAAO,OAAO,aAAuB,SAAS;AAC7C,QAAM,SAAS,WAAW;AAC1B,QAAM,OAAO,iBAAiB,MAAM,MAAM;AAC1C,YAAU,IAAI;AACd,QAAM,SAAS,YAAY,KAAK,GAAG,KAAK;AAExC,QAAM,WAAW,SAAS;AAAA,IACxB,eAAe;AAAA,IACf,QAAQ;AAAA,IACR,aAAa,mBAAmB,MAAM,MAAM,MAAM;AAAA,IAClD;AAAA,EACF,CAAC;AAED,QAAM,SAAS,cAAc;AAC/B,CAAC;AAGH,QACG,QAAQ,SAAS,EACjB,YAAY,wDAAwD,EACpE,SAAS,eAAe,kBAAkB,EAC1C,OAAO,OAAO,gBAA0B;AACvC,QAAM,SAAS,WAAW;AAC1B,QAAM,aAAa,QAAQ,KAAK;AAChC,QAAM,OAAO,iBAAiB,YAAY,MAAM;AAChD,YAAU,IAAI;AACd,QAAM,SAAS,YAAY,KAAK,GAAG;AAEnC,QAAM,WAAW,SAAS;AAAA,IACxB,eAAe;AAAA,IACf,QAAQ;AAAA,IACR,aAAa,mBAAmB,MAAM,YAAY,MAAM;AAAA,IACxD;AAAA,IACA,SAAS;AAAA,EACX,CAAC;AAED,QAAM,SAAS,cAAc;AAC/B,CAAC;AAGH,QACG,QAAQ,UAAU,EAClB,YAAY,gCAAgC,EAC5C,OAAO,YAAY;AAClB,QAAM,SAAS,WAAW;AAC1B,QAAM,aAAa,QAAQ,KAAK;AAChC,QAAM,OAAO,iBAAiB,YAAY,MAAM;AAChD,YAAU,IAAI;AACd,QAAM,UAAU,qBAAqB;AAErC,MAAI,CAAC,SAAS;AACZ,YAAQ,IAAI,MAAM,IAAI,4BAA4B,CAAC;AACnD,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,aAAa,YAAY,QAAQ,EAAE;AACzC,QAAM,aAAa,WAAW,IAAI,CAAC,OAAO;AAAA,IACxC,MAAM,EAAE;AAAA,IACR,SAAS,EAAE;AAAA,IACX,OAAO,EAAE;AAAA,EACX,EAAE;AAEF,QAAM,WAAW,SAAS;AAAA,IACxB,WAAW,QAAQ;AAAA,IACnB,QAAQ;AAAA,IACR,aAAa,mBAAmB,MAAM,YAAY,MAAM;AAAA,IACxD;AAAA,IACA,gBAAgB;AAAA,EAClB,CAAC;AAED,QAAM,SAAS,cAAc;AAC/B,CAAC;AAGH,QACG,QAAQ,aAAa,EACrB,YAAY,+CAA+C,EAC3D,OAAO,OAAO,OAA2B;AACxC,QAAM,SAAS,WAAW;AAC1B,QAAM,aAAa,QAAQ,KAAK;AAChC,QAAM,OAAO,iBAAiB,YAAY,MAAM;AAChD,YAAU,IAAI;AAEd,MAAI,CAAC,IAAI;AACP,UAAM,WAAW,aAAa,EAAE;AAChC,QAAI,SAAS,WAAW,GAAG;AACzB,cAAQ,IAAI,MAAM,IAAI,qBAAqB,CAAC;AAC5C,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,YAAQ,IAAI,MAAM,KAAK,uBAAuB,CAAC;AAC/C,aAAS,QAAQ,CAAC,GAAG,MAAM;AACzB,YAAM,MAAM,MAAM,KAAK,EAAE,GAAG,MAAM,GAAG,CAAC,CAAC;AACvC,YAAM,QAAQ,EAAE,SAAS,MAAM,IAAI,YAAY;AAC/C,YAAM,OAAO,MAAM,IAAI,EAAE,UAAU;AACnC,cAAQ,IAAI,IAAI,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,KAAK,KAAK,KAAK,IAAI,EAAE;AAAA,IACpE,CAAC;AACD,YAAQ,IAAI;AAEZ,UAAM,WAAW,MAAM,OAAO,UAAe;AAC7C,UAAM,KAAK,SAAS,gBAAgB;AAAA,MAClC,OAAO,QAAQ;AAAA,MACf,QAAQ,QAAQ;AAAA,IAClB,CAAC;AAED,WAAO,IAAI,QAAc,CAAC,YAAY;AACpC,SAAG,SAAS,4BAA4B,OAAO,UAAU;AACvD,WAAG,MAAM;AACT,cAAM,MAAM,SAAS,MAAM,KAAK,GAAG,EAAE;AACrC,YAAI,MAAM,GAAG,KAAK,MAAM,KAAK,MAAM,SAAS,QAAQ;AAClD,kBAAQ,IAAI,MAAM,IAAI,qBAAqB,CAAC;AAC5C,kBAAQ;AACR,kBAAQ;AACR;AAAA,QACF;AAEA,cAAMC,WAAU,SAAS,MAAM,CAAC;AAChC,cAAMC,cAAa,YAAYD,SAAQ,EAAE;AACzC,cAAME,cAAaD,YAAW,IAAI,CAAC,OAAO;AAAA,UACxC,MAAM,EAAE;AAAA,UACR,SAAS,EAAE;AAAA,UACX,OAAO,EAAE;AAAA,QACX,EAAE;AAEF,cAAME,YAAW,SAAS;AAAA,UACxB,WAAWH,SAAQ;AAAA,UACnB,QAAQ;AAAA,UACR,aAAa,mBAAmB,MAAM,YAAY,MAAM;AAAA,UACxD;AAAA,UACA,gBAAgBE;AAAA,QAClB,CAAC;AAED,cAAMC,UAAS,cAAc;AAC7B,gBAAQ;AAAA,MACV,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAEA,QAAM,UAAU,WAAW,EAAE,KAAK,mBAAmB,EAAE;AACvD,MAAI,CAAC,SAAS;AACZ,YAAQ,IAAI,MAAM,IAAI,uBAAuB,EAAE,EAAE,CAAC;AAClD,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,aAAa,YAAY,QAAQ,EAAE;AACzC,QAAM,aAAa,WAAW,IAAI,CAAC,OAAO;AAAA,IACxC,MAAM,EAAE;AAAA,IACR,SAAS,EAAE;AAAA,IACX,OAAO,EAAE;AAAA,EACX,EAAE;AAEF,QAAM,WAAW,SAAS;AAAA,IACxB,WAAW,QAAQ;AAAA,IACnB,QAAQ;AAAA,IACR,aAAa,mBAAmB,MAAM,YAAY,MAAM;AAAA,IACxD;AAAA,IACA,gBAAgB;AAAA,EAClB,CAAC;AAED,QAAM,SAAS,cAAc;AAC/B,CAAC;AAGH,IAAM,aAAa,QAChB,QAAQ,SAAS,EACjB,YAAY,iCAAiC,EAC7C,OAAO,mBAAmB,8BAA8B,UAAU,EAAE,EACpE,OAAO,CAAC,SAAS;AAChB,QAAM,WAAW,aAAa,KAAK,KAAK;AACxC,UAAQ,IAAI,MAAM,KAAK,uBAAuB,CAAC;AAC/C,kBAAgB,QAAQ;AACxB,UAAQ,IAAI;AACZ,UAAQ;AACV,CAAC;AAEH,WACG,QAAQ,SAAS,EACjB,YAAY,kCAAkC,EAC9C,OAAO,CAAC,OAAe;AACtB,QAAM,UAAU,WAAW,EAAE,KAAK,mBAAmB,EAAE;AACvD,MAAI,CAAC,SAAS;AACZ,YAAQ,IAAI,MAAM,IAAI,uBAAuB,EAAE,EAAE,CAAC;AAClD,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,gBAAc,QAAQ,EAAE;AACxB,QAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC;AACjC,QAAM,QAAQ,QAAQ,SAAS;AAC/B,UAAQ,IAAI,MAAM,MAAM,oBAAoB,GAAG,WAAM,KAAK,EAAE,CAAC;AAC7D,UAAQ;AACV,CAAC;AAEH,WACG,QAAQ,OAAO,EACf,YAAY,qBAAqB,EACjC,OAAO,YAAY;AAClB,QAAM,WAAW,aAAa;AAC9B,MAAI,SAAS,WAAW,GAAG;AACzB,YAAQ,IAAI,MAAM,OAAO,yBAAyB,CAAC;AACnD,YAAQ;AACR;AAAA,EACF;AAEA,QAAM,WAAW,MAAM,OAAO,UAAe;AAC7C,QAAM,KAAK,SAAS,gBAAgB;AAAA,IAClC,OAAO,QAAQ;AAAA,IACf,QAAQ,QAAQ;AAAA,EAClB,CAAC;AAED,KAAG;AAAA,IACD,MAAM,OAAO,eAAe,SAAS,MAAM,qBAAqB;AAAA,IAChE,CAAC,WAAW;AACV,SAAG,MAAM;AACT,UAAI,OAAO,KAAK,EAAE,YAAY,MAAM,KAAK;AACvC,0BAAkB;AAClB,gBAAQ,IAAI,MAAM,MAAM,YAAY,SAAS,MAAM,cAAc,CAAC;AAAA,MACpE,OAAO;AACL,gBAAQ,IAAI,aAAa;AAAA,MAC3B;AACA,cAAQ;AAAA,IACV;AAAA,EACF;AACF,CAAC;AAGH,QACG,QAAQ,WAAW,EACnB,YAAY,qCAAqC,EACjD,OAAO,kBAAkB,sCAAsC,EAC/D,OAAO,CAAC,IAAY,SAAiC;AACpD,QAAM,UAAU,WAAW,EAAE,KAAK,mBAAmB,EAAE;AACvD,MAAI,CAAC,SAAS;AACZ,YAAQ,IAAI,MAAM,IAAI,uBAAuB,EAAE,EAAE,CAAC;AAClD,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,KAAK,UAAU;AACjB,YAAQ,OAAO,MAAM,uBAAuB,QAAQ,EAAE,CAAC;AAAA,EACzD,OAAO;AACL,mBAAe,QAAQ,EAAE;AAAA,EAC3B;AACA,UAAQ;AACV,CAAC;AAGH,IAAM,YAAY,QACf,QAAQ,QAAQ,EAChB,YAAY,sBAAsB,EAClC,OAAO,YAAY;AAClB,QAAM,WAAW,kBAAkB;AACnC,QAAM,SAAS,cAAc;AAC/B,CAAC;AAEH,UACG,QAAQ,MAAM,EACd,YAAY,kCAAkC,EAC9C,OAAO,YAAY;AAClB,QAAM,WAAW,kBAAkB;AACnC,QAAM,SAAS,cAAc;AAC/B,CAAC;AAEH,UACG,QAAQ,MAAM,EACd,YAAY,4BAA4B,EACxC,OAAO,MAAM;AACZ,QAAM,SAAS,WAAW;AAC1B,UAAQ,IAAI,MAAM,KAAK,qBAAqB,CAAC;AAC7C,UAAQ;AAAA,IACN,MAAM,IAAI,sBAAsB,IAAI,MAAM,MAAM,OAAO,OAAO,KAAK,IAAI,CAAC;AAAA,EAC1E;AACA,UAAQ;AAAA,IACN,MAAM,IAAI,sBAAsB,IAAI,MAAM,MAAM,OAAO,OAAO,KAAK;AAAA,EACrE;AACA,UAAQ;AAAA,IACN,MAAM,IAAI,sBAAsB,IAAI,MAAM,MAAM,OAAO,MAAM,KAAK;AAAA,EACpE;AACA,UAAQ;AAAA,IACN,MAAM,IAAI,sBAAsB,IAAI,MAAM,MAAM,OAAO,OAAO,KAAK;AAAA,EACrE;AACA,UAAQ;AAAA,IACN,MAAM,IAAI,2BAA2B,IAAI,MAAM,MAAM,OAAO,OAAO,WAAW,UAAU,CAAC;AAAA,EAC3F;AACA,UAAQ,IAAI;AACd,CAAC;AAEH,UACG,QAAQ,mBAAmB,EAC3B,YAAY,2BAA2B,EACvC,OAAO,CAAC,KAAa,UAAkB;AACtC,MAAI;AACF,mBAAe,KAAK,KAAK;AACzB,YAAQ,IAAI,MAAM,MAAM,QAAQ,GAAG,MAAM,KAAK,EAAE,CAAC;AAAA,EACnD,SAAS,GAAQ;AACf,YAAQ,IAAI,MAAM,IAAI,IAAI,EAAE,OAAO,EAAE,CAAC;AACtC,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAEH,QAAQ,WAAW;","names":["execSync","useState","render","Box","Text","useApp","useInput","TextInput","spawn","createInterface","spawn","join","join","db","db","db","jsx","jsxs","adHoc","Text","Box","useState","TextInput","showTranscript","useApp","useInput","render","execSync","session","dbMessages","transcript","instance"]}
|