swagmanager-mcp 3.1.0 → 4.7.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/bin/swagmanager-mcp.js +190 -23
- package/dist/cli/app.d.ts +16 -1
- package/dist/cli/app.js +10 -1
- package/dist/cli/chat/ChatApp.d.ts +4 -2
- package/dist/cli/chat/ChatApp.js +493 -47
- package/dist/cli/chat/ChatInput.d.ts +3 -3
- package/dist/cli/chat/ChatInput.js +26 -11
- package/dist/cli/chat/MarkdownText.d.ts +1 -2
- package/dist/cli/chat/MarkdownText.js +3 -15
- package/dist/cli/chat/MessageList.d.ts +10 -11
- package/dist/cli/chat/MessageList.js +15 -9
- package/dist/cli/chat/StreamingText.d.ts +5 -5
- package/dist/cli/chat/StreamingText.js +8 -20
- package/dist/cli/chat/SubagentPanel.d.ts +45 -0
- package/dist/cli/chat/SubagentPanel.js +109 -0
- package/dist/cli/chat/TeamPanel.d.ts +21 -0
- package/dist/cli/chat/TeamPanel.js +41 -0
- package/dist/cli/chat/ToolIndicator.d.ts +6 -1
- package/dist/cli/chat/ToolIndicator.js +286 -95
- package/dist/cli/commands/config-cmd.d.ts +10 -0
- package/dist/cli/commands/config-cmd.js +103 -0
- package/dist/cli/commands/doctor.d.ts +14 -0
- package/dist/cli/commands/doctor.js +172 -0
- package/dist/cli/commands/mcp.d.ts +12 -0
- package/dist/cli/commands/mcp.js +162 -0
- package/dist/cli/print-mode.d.ts +31 -0
- package/dist/cli/print-mode.js +191 -0
- package/dist/cli/services/agent-definitions.d.ts +25 -0
- package/dist/cli/services/agent-definitions.js +91 -0
- package/dist/cli/services/agent-events.d.ts +174 -0
- package/dist/cli/services/agent-events.js +175 -0
- package/dist/cli/services/agent-loop.d.ts +38 -2
- package/dist/cli/services/agent-loop.js +524 -128
- package/dist/cli/services/background-processes.d.ts +125 -0
- package/dist/cli/services/background-processes.js +316 -0
- package/dist/cli/services/debug-log.d.ts +10 -0
- package/dist/cli/services/debug-log.js +52 -0
- package/dist/cli/services/file-history.d.ts +21 -0
- package/dist/cli/services/file-history.js +83 -0
- package/dist/cli/services/format-server-response.d.ts +18 -0
- package/dist/cli/services/format-server-response.js +1113 -0
- package/dist/cli/services/hooks.d.ts +56 -0
- package/dist/cli/services/hooks.js +205 -0
- package/dist/cli/services/interactive-tools.d.ts +125 -0
- package/dist/cli/services/interactive-tools.js +260 -0
- package/dist/cli/services/local-tools.d.ts +18 -7
- package/dist/cli/services/local-tools.js +1521 -111
- package/dist/cli/services/loop-detector.d.ts +36 -0
- package/dist/cli/services/loop-detector.js +80 -0
- package/dist/cli/services/lsp-manager.d.ts +18 -0
- package/dist/cli/services/lsp-manager.js +717 -0
- package/dist/cli/services/ripgrep.d.ts +28 -0
- package/dist/cli/services/ripgrep.js +138 -0
- package/dist/cli/services/sandbox.d.ts +29 -0
- package/dist/cli/services/sandbox.js +97 -0
- package/dist/cli/services/server-tools.d.ts +20 -7
- package/dist/cli/services/server-tools.js +85 -312
- package/dist/cli/services/slash-commands.d.ts +50 -0
- package/dist/cli/services/slash-commands.js +284 -0
- package/dist/cli/services/subagent-worker.d.ts +19 -0
- package/dist/cli/services/subagent-worker.js +41 -0
- package/dist/cli/services/subagent.d.ts +47 -0
- package/dist/cli/services/subagent.js +852 -0
- package/dist/cli/services/team-lead.d.ts +72 -0
- package/dist/cli/services/team-lead.js +505 -0
- package/dist/cli/services/team-state.d.ts +76 -0
- package/dist/cli/services/team-state.js +398 -0
- package/dist/cli/services/teammate.d.ts +31 -0
- package/dist/cli/services/teammate.js +806 -0
- package/dist/cli/services/telemetry.d.ts +15 -1
- package/dist/cli/services/telemetry.js +81 -20
- package/dist/cli/shared/markdown.d.ts +7 -1
- package/dist/cli/shared/markdown.js +376 -27
- package/dist/index.d.ts +7 -5
- package/dist/index.js +45 -30
- package/dist/services/tool-registry.js +1 -5
- package/dist/tools/executor.d.ts +2 -0
- package/dist/tools/executor.js +1400 -222
- package/package.json +6 -1
- package/src/cli/services/builtin-skills/commit.md +19 -0
- package/src/cli/services/builtin-skills/review-pr.md +21 -0
- package/src/cli/services/builtin-skills/review.md +18 -0
package/bin/swagmanager-mcp.js
CHANGED
|
@@ -4,21 +4,75 @@
|
|
|
4
4
|
* whale code — local-first AI agent CLI
|
|
5
5
|
*
|
|
6
6
|
* Usage:
|
|
7
|
-
* whale
|
|
8
|
-
* whale
|
|
9
|
-
* whale
|
|
10
|
-
* whale
|
|
11
|
-
* whale
|
|
12
|
-
*
|
|
7
|
+
* whale Start interactive chat
|
|
8
|
+
* whale -p "prompt" Non-interactive (print) mode
|
|
9
|
+
* whale login Log in with SwagManager credentials
|
|
10
|
+
* whale logout Clear saved session
|
|
11
|
+
* whale status Show connection status
|
|
12
|
+
* whale mcp list|add|remove Manage MCP servers
|
|
13
|
+
* whale doctor Run diagnostics
|
|
14
|
+
* whale config [key] [value] View/set configuration
|
|
15
|
+
* whale help Show this help
|
|
16
|
+
* (non-TTY stdin) MCP stdio server for Claude Code / Cursor
|
|
13
17
|
*/
|
|
14
18
|
|
|
15
19
|
import { fileURLToPath } from "url";
|
|
16
20
|
import { dirname, join } from "path";
|
|
21
|
+
import { parseArgs } from "util";
|
|
17
22
|
|
|
18
23
|
const __filename = fileURLToPath(import.meta.url);
|
|
19
24
|
const __dirname = dirname(__filename);
|
|
25
|
+
const distDir = join(__dirname, "..", "dist");
|
|
20
26
|
|
|
21
|
-
|
|
27
|
+
// ── Parse CLI flags ──
|
|
28
|
+
let parsed;
|
|
29
|
+
try {
|
|
30
|
+
parsed = parseArgs({
|
|
31
|
+
allowPositionals: true,
|
|
32
|
+
strict: false,
|
|
33
|
+
options: {
|
|
34
|
+
// Print / headless mode
|
|
35
|
+
print: { type: "boolean", short: "p" },
|
|
36
|
+
"output-format": { type: "string" },
|
|
37
|
+
// Model & mode
|
|
38
|
+
model: { type: "string", short: "m" },
|
|
39
|
+
"permission-mode": { type: "string" },
|
|
40
|
+
// Session
|
|
41
|
+
resume: { type: "string", short: "r" },
|
|
42
|
+
continue: { type: "boolean", short: "c" },
|
|
43
|
+
"session-id": { type: "string" },
|
|
44
|
+
"no-session-persistence": { type: "boolean" },
|
|
45
|
+
// Limits
|
|
46
|
+
"max-turns": { type: "string" },
|
|
47
|
+
"max-budget-usd": { type: "string" },
|
|
48
|
+
effort: { type: "string" },
|
|
49
|
+
// Tool filtering
|
|
50
|
+
"allowed-tools": { type: "string" },
|
|
51
|
+
"disallowed-tools": { type: "string" },
|
|
52
|
+
// Fallback
|
|
53
|
+
"fallback-model": { type: "string" },
|
|
54
|
+
// Debug / verbose
|
|
55
|
+
debug: { type: "boolean" },
|
|
56
|
+
verbose: { type: "boolean", short: "v" },
|
|
57
|
+
// Standard
|
|
58
|
+
help: { type: "boolean", short: "h" },
|
|
59
|
+
version: { type: "boolean" },
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
} catch (err) {
|
|
63
|
+
console.error(`Error: ${err.message}`);
|
|
64
|
+
console.error("Run 'whale help' for usage.");
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const { values: flags, positionals } = parsed;
|
|
69
|
+
|
|
70
|
+
// First positional is the subcommand (unless --print is used)
|
|
71
|
+
const subcommand = positionals[0];
|
|
72
|
+
// If --print, remaining positionals form the message
|
|
73
|
+
const printMessage = flags.print
|
|
74
|
+
? positionals.join(" ")
|
|
75
|
+
: undefined;
|
|
22
76
|
|
|
23
77
|
// ── Help ──
|
|
24
78
|
function showHelp() {
|
|
@@ -31,18 +85,43 @@ function showHelp() {
|
|
|
31
85
|
console.log();
|
|
32
86
|
console.log(` ${g}╭──────────────────────────────────────────╮${r}`);
|
|
33
87
|
console.log(` ${g}│${r} ${g}│${r}`);
|
|
34
|
-
console.log(` ${g}│${r} ${c}${B}◆ whale code${r} ${d}
|
|
88
|
+
console.log(` ${g}│${r} ${c}${B}◆ whale code${r} ${d}v4.7.0${r} ${g}│${r}`);
|
|
35
89
|
console.log(` ${g}│${r} ${d}local-first AI agent CLI${r} ${g}│${r}`);
|
|
36
90
|
console.log(` ${g}│${r} ${g}│${r}`);
|
|
37
91
|
console.log(` ${g}╰──────────────────────────────────────────╯${r}`);
|
|
38
92
|
console.log();
|
|
39
93
|
console.log(` ${B}Commands:${r}`);
|
|
40
|
-
console.log(` whale${d}
|
|
41
|
-
console.log(` whale login${d}
|
|
42
|
-
console.log(` whale logout${d}
|
|
43
|
-
console.log(` whale stores${d}
|
|
44
|
-
console.log(` whale status${d}
|
|
45
|
-
console.log(` whale setup${d}
|
|
94
|
+
console.log(` whale${d} Start chatting (default)${r}`);
|
|
95
|
+
console.log(` whale login${d} Log in to SwagManager${r}`);
|
|
96
|
+
console.log(` whale logout${d} Clear session${r}`);
|
|
97
|
+
console.log(` whale stores${d} Switch active store${r}`);
|
|
98
|
+
console.log(` whale status${d} Connection & tools${r}`);
|
|
99
|
+
console.log(` whale setup${d} Install MCP to IDEs${r}`);
|
|
100
|
+
console.log(` whale mcp${d} Manage MCP servers${r}`);
|
|
101
|
+
console.log(` whale doctor${d} Run diagnostics${r}`);
|
|
102
|
+
console.log(` whale config${d} View/set configuration${r}`);
|
|
103
|
+
console.log();
|
|
104
|
+
console.log(` ${B}Print Mode (non-interactive):${r}`);
|
|
105
|
+
console.log(` whale -p "prompt"${d} Run single prompt, output to stdout${r}`);
|
|
106
|
+
console.log(` echo "prompt" | whale -p${d} Read prompt from stdin${r}`);
|
|
107
|
+
console.log();
|
|
108
|
+
console.log(` ${B}Flags:${r}`);
|
|
109
|
+
console.log(` -p, --print${d} Non-interactive mode${r}`);
|
|
110
|
+
console.log(` --output-format <fmt>${d} text|json|stream-json (default: text)${r}`);
|
|
111
|
+
console.log(` -m, --model <name>${d} sonnet|opus|haiku${r}`);
|
|
112
|
+
console.log(` --permission-mode <mode>${d} default|plan|yolo${r}`);
|
|
113
|
+
console.log(` -r, --resume <id>${d} Resume session by ID${r}`);
|
|
114
|
+
console.log(` -c, --continue${d} Continue most recent session${r}`);
|
|
115
|
+
console.log(` --session-id <id>${d} Custom session UUID${r}`);
|
|
116
|
+
console.log(` --no-session-persistence${d} Ephemeral session${r}`);
|
|
117
|
+
console.log(` --max-turns <n>${d} Limit agent turns${r}`);
|
|
118
|
+
console.log(` --max-budget-usd <n>${d} Cost cap in USD${r}`);
|
|
119
|
+
console.log(` --effort <level>${d} low|medium|high${r}`);
|
|
120
|
+
console.log(` --allowed-tools <list>${d} Comma-separated tool whitelist${r}`);
|
|
121
|
+
console.log(` --disallowed-tools <list>${d} Comma-separated tool blacklist${r}`);
|
|
122
|
+
console.log(` --fallback-model <name>${d} Auto-fallback on overload${r}`);
|
|
123
|
+
console.log(` --debug${d} Debug logging to stderr${r}`);
|
|
124
|
+
console.log(` -v, --verbose${d} Extra output${r}`);
|
|
46
125
|
console.log();
|
|
47
126
|
console.log(` ${B}In chat:${r}`);
|
|
48
127
|
console.log(` ${d}Type ${r}/${d} to open command menu${r}`);
|
|
@@ -50,7 +129,77 @@ function showHelp() {
|
|
|
50
129
|
console.log();
|
|
51
130
|
}
|
|
52
131
|
|
|
53
|
-
//
|
|
132
|
+
// Build options object from flags
|
|
133
|
+
function buildOptions() {
|
|
134
|
+
return {
|
|
135
|
+
model: flags.model,
|
|
136
|
+
permissionMode: flags["permission-mode"],
|
|
137
|
+
resumeSessionId: flags.resume,
|
|
138
|
+
continueLastSession: flags.continue,
|
|
139
|
+
sessionId: flags["session-id"],
|
|
140
|
+
noSessionPersistence: flags["no-session-persistence"],
|
|
141
|
+
maxTurns: flags["max-turns"] ? parseInt(flags["max-turns"], 10) : undefined,
|
|
142
|
+
maxBudgetUsd: flags["max-budget-usd"] ? parseFloat(flags["max-budget-usd"]) : undefined,
|
|
143
|
+
effort: flags.effort,
|
|
144
|
+
allowedTools: flags["allowed-tools"]?.split(",").map(s => s.trim()),
|
|
145
|
+
disallowedTools: flags["disallowed-tools"]?.split(",").map(s => s.trim()),
|
|
146
|
+
fallbackModel: flags["fallback-model"],
|
|
147
|
+
debug: flags.debug,
|
|
148
|
+
verbose: flags.verbose,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// ── Version ──
|
|
153
|
+
if (flags.version) {
|
|
154
|
+
// Read version from package.json
|
|
155
|
+
try {
|
|
156
|
+
const { readFileSync } = await import("fs");
|
|
157
|
+
const pkg = JSON.parse(readFileSync(join(__dirname, "..", "package.json"), "utf-8"));
|
|
158
|
+
console.log(pkg.version);
|
|
159
|
+
} catch {
|
|
160
|
+
console.log("4.7.0");
|
|
161
|
+
}
|
|
162
|
+
process.exit(0);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// ── Help ──
|
|
166
|
+
if (flags.help && !subcommand) {
|
|
167
|
+
showHelp();
|
|
168
|
+
process.exit(0);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// ── Print mode ──
|
|
172
|
+
if (flags.print) {
|
|
173
|
+
const { runPrintMode } = await import(join(distDir, "cli", "print-mode.js"));
|
|
174
|
+
const options = buildOptions();
|
|
175
|
+
|
|
176
|
+
// Read stdin if available (non-TTY)
|
|
177
|
+
let stdinContent = "";
|
|
178
|
+
if (!process.stdin.isTTY) {
|
|
179
|
+
const chunks = [];
|
|
180
|
+
for await (const chunk of process.stdin) {
|
|
181
|
+
chunks.push(chunk);
|
|
182
|
+
}
|
|
183
|
+
stdinContent = Buffer.concat(chunks).toString("utf-8").trim();
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Combine stdin + positional message
|
|
187
|
+
const message = [stdinContent, printMessage].filter(Boolean).join("\n\n");
|
|
188
|
+
if (!message) {
|
|
189
|
+
console.error("Error: --print requires a message. Provide as argument or via stdin.");
|
|
190
|
+
process.exit(1);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const exitCode = await runPrintMode({
|
|
194
|
+
message,
|
|
195
|
+
outputFormat: flags["output-format"] || "text",
|
|
196
|
+
...options,
|
|
197
|
+
});
|
|
198
|
+
process.exit(exitCode);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// ── Route subcommands ──
|
|
202
|
+
const command = subcommand;
|
|
54
203
|
switch (command) {
|
|
55
204
|
case "help":
|
|
56
205
|
case "--help":
|
|
@@ -63,13 +212,13 @@ switch (command) {
|
|
|
63
212
|
console.error("Error: whale login requires an interactive terminal.");
|
|
64
213
|
process.exit(1);
|
|
65
214
|
}
|
|
66
|
-
const { renderLogin } = await import(join(
|
|
215
|
+
const { renderLogin } = await import(join(distDir, "cli", "app.js"));
|
|
67
216
|
await renderLogin();
|
|
68
217
|
break;
|
|
69
218
|
}
|
|
70
219
|
|
|
71
220
|
case "logout": {
|
|
72
|
-
const { renderLogout } = await import(join(
|
|
221
|
+
const { renderLogout } = await import(join(distDir, "cli", "app.js"));
|
|
73
222
|
await renderLogout();
|
|
74
223
|
break;
|
|
75
224
|
}
|
|
@@ -77,20 +226,20 @@ switch (command) {
|
|
|
77
226
|
case "chat":
|
|
78
227
|
case undefined: {
|
|
79
228
|
if (process.stdin.isTTY) {
|
|
80
|
-
const { renderChat } = await import(join(
|
|
81
|
-
await renderChat();
|
|
229
|
+
const { renderChat } = await import(join(distDir, "cli", "app.js"));
|
|
230
|
+
await renderChat(buildOptions());
|
|
82
231
|
} else if (command === "chat") {
|
|
83
232
|
console.error("Error: whale chat requires an interactive terminal.");
|
|
84
233
|
process.exit(1);
|
|
85
234
|
} else {
|
|
86
235
|
// Non-TTY, no command → MCP stdio server
|
|
87
|
-
await import(join(
|
|
236
|
+
await import(join(distDir, "index.js"));
|
|
88
237
|
}
|
|
89
238
|
break;
|
|
90
239
|
}
|
|
91
240
|
|
|
92
241
|
case "status": {
|
|
93
|
-
const { renderStatus } = await import(join(
|
|
242
|
+
const { renderStatus } = await import(join(distDir, "cli", "app.js"));
|
|
94
243
|
await renderStatus();
|
|
95
244
|
break;
|
|
96
245
|
}
|
|
@@ -100,7 +249,7 @@ switch (command) {
|
|
|
100
249
|
console.error("Error: whale setup requires an interactive terminal.");
|
|
101
250
|
process.exit(1);
|
|
102
251
|
}
|
|
103
|
-
const { renderSetup } = await import(join(
|
|
252
|
+
const { renderSetup } = await import(join(distDir, "cli", "app.js"));
|
|
104
253
|
await renderSetup();
|
|
105
254
|
break;
|
|
106
255
|
}
|
|
@@ -111,11 +260,29 @@ switch (command) {
|
|
|
111
260
|
console.error("Error: whale stores requires an interactive terminal.");
|
|
112
261
|
process.exit(1);
|
|
113
262
|
}
|
|
114
|
-
const { renderStores } = await import(join(
|
|
263
|
+
const { renderStores } = await import(join(distDir, "cli", "app.js"));
|
|
115
264
|
await renderStores();
|
|
116
265
|
break;
|
|
117
266
|
}
|
|
118
267
|
|
|
268
|
+
case "mcp": {
|
|
269
|
+
const { runMcpCommand } = await import(join(distDir, "cli", "commands", "mcp.js"));
|
|
270
|
+
await runMcpCommand(positionals.slice(1));
|
|
271
|
+
break;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
case "doctor": {
|
|
275
|
+
const { runDoctor } = await import(join(distDir, "cli", "commands", "doctor.js"));
|
|
276
|
+
await runDoctor();
|
|
277
|
+
break;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
case "config": {
|
|
281
|
+
const { runConfigCommand } = await import(join(distDir, "cli", "commands", "config-cmd.js"));
|
|
282
|
+
await runConfigCommand(positionals.slice(1), flags);
|
|
283
|
+
break;
|
|
284
|
+
}
|
|
285
|
+
|
|
119
286
|
default:
|
|
120
287
|
console.error(`Unknown command: ${command}`);
|
|
121
288
|
console.error(`Run 'whale help' for usage.`);
|
package/dist/cli/app.d.ts
CHANGED
|
@@ -3,9 +3,24 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Dynamic imports for each mode — keeps MCP server path clean.
|
|
5
5
|
*/
|
|
6
|
+
export interface ChatOptions {
|
|
7
|
+
model?: string;
|
|
8
|
+
permissionMode?: string;
|
|
9
|
+
resumeSessionId?: string;
|
|
10
|
+
continueLastSession?: boolean;
|
|
11
|
+
sessionId?: string;
|
|
12
|
+
maxTurns?: number;
|
|
13
|
+
maxBudgetUsd?: number;
|
|
14
|
+
effort?: string;
|
|
15
|
+
allowedTools?: string[];
|
|
16
|
+
disallowedTools?: string[];
|
|
17
|
+
fallbackModel?: string;
|
|
18
|
+
debug?: boolean;
|
|
19
|
+
verbose?: boolean;
|
|
20
|
+
}
|
|
6
21
|
export declare function renderLogin(): Promise<void>;
|
|
7
22
|
export declare function renderLogout(): Promise<void>;
|
|
8
|
-
export declare function renderChat(): Promise<void>;
|
|
23
|
+
export declare function renderChat(options?: ChatOptions): Promise<void>;
|
|
9
24
|
export declare function renderSetup(): Promise<void>;
|
|
10
25
|
export declare function renderStatus(): Promise<void>;
|
|
11
26
|
export declare function renderStores(): Promise<void>;
|
package/dist/cli/app.js
CHANGED
|
@@ -15,9 +15,18 @@ export async function renderLogout() {
|
|
|
15
15
|
console.log("Logged out. Tokens cleared.");
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
|
-
export async function renderChat() {
|
|
18
|
+
export async function renderChat(options) {
|
|
19
19
|
const { matrixIntro } = await import("./shared/MatrixIntro.js");
|
|
20
20
|
await matrixIntro();
|
|
21
|
+
// Apply options before starting chat
|
|
22
|
+
if (options?.model || options?.permissionMode) {
|
|
23
|
+
const agentLoop = await import("./services/agent-loop.js");
|
|
24
|
+
if (options.model)
|
|
25
|
+
agentLoop.setModel(options.model);
|
|
26
|
+
if (options.permissionMode) {
|
|
27
|
+
agentLoop.setPermissionMode(options.permissionMode);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
21
30
|
const { ChatApp } = await import("./chat/ChatApp.js");
|
|
22
31
|
const { waitUntilExit } = render(_jsx(ChatApp, {}));
|
|
23
32
|
await waitUntilExit();
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ChatApp — whale code CLI
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Uses Ink's <Static> for completed messages — written to stdout once,
|
|
5
|
+
* never re-rendered. Only the active area (streaming, tools, input)
|
|
6
|
+
* is managed by Ink's render loop. This prevents scroll bounce when
|
|
7
|
+
* content exceeds the terminal height.
|
|
6
8
|
*/
|
|
7
9
|
export declare function ChatApp(): import("react/jsx-runtime").JSX.Element;
|