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 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
- function parseInput(input, pair) {
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
- return { target: "both", prompt: input.slice(8).trim(), discuss: true };
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
- for (const agent of pair) {
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
- useEffect(() => {
1024
- if (!existingSessionId) {
1025
- createSession(sessionId, process.cwd());
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 (isFirstRound && target === "both") {
1075
- return currentMessages[currentMessages.length - 1]?.content || "";
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, pair);
1082
- return debateRoundPrompt(agent, history, pair);
1145
+ if (isFirstRound) return debatePrompt(agent, promptPair);
1146
+ return debateRoundPrompt(agent, history, promptPair);
1083
1147
  }
1084
- if (isFirstRound && target === "both") return collaborationPrompt(agent, pair);
1085
- return discussionPrompt(agent, history, pair);
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, pair);
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
- "both",
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 consensusFlags = pair.map((agent) => {
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
- createSession(newId, process.cwd());
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.2.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) => {
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 recent sessions").option("-n, --limit <n>", "Number of sessions to show", parseInt, 20).action((opts) => {
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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tagteam",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Orchestrate AI agents (Claude, Codex, Gemini) in collaborative sessions",
5
5
  "type": "module",
6
6
  "bin": {