@x-code-cli/cli 0.1.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/dist/app.d.ts +6 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +36 -0
- package/dist/app.js.map +1 -0
- package/dist/cli.js +180674 -0
- package/dist/cli.js.map +7 -0
- package/dist/config/index.d.ts +20 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +18 -0
- package/dist/config/index.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +190 -0
- package/dist/index.js.map +1 -0
- package/dist/ui/components/App.d.ts +40 -0
- package/dist/ui/components/App.d.ts.map +1 -0
- package/dist/ui/components/App.js +196 -0
- package/dist/ui/components/App.js.map +1 -0
- package/dist/ui/components/AppHeader.d.ts +6 -0
- package/dist/ui/components/AppHeader.d.ts.map +1 -0
- package/dist/ui/components/AppHeader.js +51 -0
- package/dist/ui/components/AppHeader.js.map +1 -0
- package/dist/ui/components/ChatInput.d.ts +12 -0
- package/dist/ui/components/ChatInput.d.ts.map +1 -0
- package/dist/ui/components/ChatInput.js +107 -0
- package/dist/ui/components/ChatInput.js.map +1 -0
- package/dist/ui/components/MessageList.d.ts +7 -0
- package/dist/ui/components/MessageList.d.ts.map +1 -0
- package/dist/ui/components/MessageList.js +8 -0
- package/dist/ui/components/MessageList.js.map +1 -0
- package/dist/ui/components/Permission.d.ts +8 -0
- package/dist/ui/components/Permission.d.ts.map +1 -0
- package/dist/ui/components/Permission.js +104 -0
- package/dist/ui/components/Permission.js.map +1 -0
- package/dist/ui/components/SelectOptions.d.ts +12 -0
- package/dist/ui/components/SelectOptions.d.ts.map +1 -0
- package/dist/ui/components/SelectOptions.js +49 -0
- package/dist/ui/components/SelectOptions.js.map +1 -0
- package/dist/ui/components/ShellOutput.d.ts +6 -0
- package/dist/ui/components/ShellOutput.d.ts.map +1 -0
- package/dist/ui/components/ShellOutput.js +13 -0
- package/dist/ui/components/ShellOutput.js.map +1 -0
- package/dist/ui/components/Spinner.d.ts +6 -0
- package/dist/ui/components/Spinner.d.ts.map +1 -0
- package/dist/ui/components/Spinner.js +17 -0
- package/dist/ui/components/Spinner.js.map +1 -0
- package/dist/ui/components/StatusBar.d.ts +8 -0
- package/dist/ui/components/StatusBar.d.ts.map +1 -0
- package/dist/ui/components/StatusBar.js +8 -0
- package/dist/ui/components/StatusBar.js.map +1 -0
- package/dist/ui/components/StreamingText.d.ts +6 -0
- package/dist/ui/components/StreamingText.d.ts.map +1 -0
- package/dist/ui/components/StreamingText.js +46 -0
- package/dist/ui/components/StreamingText.js.map +1 -0
- package/dist/ui/components/ToolCall.d.ts +9 -0
- package/dist/ui/components/ToolCall.d.ts.map +1 -0
- package/dist/ui/components/ToolCall.js +29 -0
- package/dist/ui/components/ToolCall.js.map +1 -0
- package/dist/ui/hooks/use-agent.d.ts +46 -0
- package/dist/ui/hooks/use-agent.d.ts.map +1 -0
- package/dist/ui/hooks/use-agent.js +277 -0
- package/dist/ui/hooks/use-agent.js.map +1 -0
- package/dist/ui/render-markdown.d.ts +8 -0
- package/dist/ui/render-markdown.d.ts.map +1 -0
- package/dist/ui/render-markdown.js +230 -0
- package/dist/ui/render-markdown.js.map +1 -0
- package/dist/ui/theme.d.ts +13 -0
- package/dist/ui/theme.d.ts.map +1 -0
- package/dist/ui/theme.js +19 -0
- package/dist/ui/theme.js.map +1 -0
- package/package.json +28 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { AppConfig } from '@x-code/core';
|
|
2
|
+
export interface CliOptions {
|
|
3
|
+
model?: string;
|
|
4
|
+
trust: boolean;
|
|
5
|
+
print: boolean;
|
|
6
|
+
maxTurns: number;
|
|
7
|
+
prompt?: string;
|
|
8
|
+
}
|
|
9
|
+
/** Resolve all configuration from CLI args + env + config file */
|
|
10
|
+
export declare function resolveCliConfig(args: CliOptions): Promise<{
|
|
11
|
+
config: AppConfig;
|
|
12
|
+
modelId: string | null;
|
|
13
|
+
availableProviders: string[];
|
|
14
|
+
needsSetup: boolean;
|
|
15
|
+
trustMode: boolean;
|
|
16
|
+
printMode: boolean;
|
|
17
|
+
maxTurns: number;
|
|
18
|
+
}>;
|
|
19
|
+
export type { AppConfig };
|
|
20
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAE7C,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,OAAO,CAAA;IACd,KAAK,EAAE,OAAO,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,kEAAkE;AAClE,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,UAAU;;;;;;;;GActD;AAED,YAAY,EAAE,SAAS,EAAE,CAAA"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// @x-code/cli — CLI-level config helpers
|
|
2
|
+
import { getAvailableProviders, loadConfig, resolveModelId } from '@x-code/core';
|
|
3
|
+
/** Resolve all configuration from CLI args + env + config file */
|
|
4
|
+
export async function resolveCliConfig(args) {
|
|
5
|
+
const config = await loadConfig();
|
|
6
|
+
const modelId = resolveModelId(args.model, config);
|
|
7
|
+
const availableProviders = getAvailableProviders();
|
|
8
|
+
return {
|
|
9
|
+
config,
|
|
10
|
+
modelId,
|
|
11
|
+
availableProviders,
|
|
12
|
+
needsSetup: availableProviders.length === 0,
|
|
13
|
+
trustMode: args.trust,
|
|
14
|
+
printMode: args.print,
|
|
15
|
+
maxTurns: args.maxTurns,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,OAAO,EAAE,qBAAqB,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAWhF,kEAAkE;AAClE,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAAgB;IACrD,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAA;IACjC,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;IAClD,MAAM,kBAAkB,GAAG,qBAAqB,EAAE,CAAA;IAElD,OAAO;QACL,MAAM;QACN,OAAO;QACP,kBAAkB;QAClB,UAAU,EAAE,kBAAkB,CAAC,MAAM,KAAK,CAAC;QAC3C,SAAS,EAAE,IAAI,CAAC,KAAK;QACrB,SAAS,EAAE,IAAI,CAAC,KAAK;QACrB,QAAQ,EAAE,IAAI,CAAC,QAAQ;KACxB,CAAA;AACH,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
// @x-code/cli — CLI entry point
|
|
2
|
+
import yargs from 'yargs';
|
|
3
|
+
import { hideBin } from 'yargs/helpers';
|
|
4
|
+
import fs from 'node:fs';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { PROVIDER_DETECTION_ORDER, PROVIDER_KEY_URLS, VERSION, createModelRegistry, getAvailableProviders, getEnvVarName, loadConfig, resolveModelId, } from '@x-code/core';
|
|
7
|
+
import { getCleanupFn, printExitSummary, startApp } from './app.js';
|
|
8
|
+
const MIN_NODE_VERSION = [20, 19, 0];
|
|
9
|
+
function checkNodeVersion() {
|
|
10
|
+
const [major, minor, patch] = process.versions.node.split('.').map(Number);
|
|
11
|
+
const [reqMajor, reqMinor, reqPatch] = MIN_NODE_VERSION;
|
|
12
|
+
if (major < reqMajor ||
|
|
13
|
+
(major === reqMajor && minor < reqMinor) ||
|
|
14
|
+
(major === reqMajor && minor === reqMinor && patch < reqPatch)) {
|
|
15
|
+
console.error(`Error: X-Code CLI requires Node.js >= ${MIN_NODE_VERSION.join('.')}, but you are running ${process.versions.node}.\n` +
|
|
16
|
+
'Please upgrade Node.js: https://nodejs.org/');
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
async function main() {
|
|
21
|
+
checkNodeVersion();
|
|
22
|
+
loadEnvFile();
|
|
23
|
+
// Parse CLI arguments
|
|
24
|
+
const argv = await yargs(hideBin(process.argv))
|
|
25
|
+
.scriptName('x-code')
|
|
26
|
+
.usage('$0 [options] [prompt]')
|
|
27
|
+
.option('model', {
|
|
28
|
+
alias: 'm',
|
|
29
|
+
type: 'string',
|
|
30
|
+
describe: 'Model to use (e.g. sonnet, deepseek, openai:gpt-4.1)',
|
|
31
|
+
})
|
|
32
|
+
.option('trust', {
|
|
33
|
+
alias: 't',
|
|
34
|
+
type: 'boolean',
|
|
35
|
+
default: false,
|
|
36
|
+
describe: 'Trust mode: skip write operation confirmations',
|
|
37
|
+
})
|
|
38
|
+
.option('print', {
|
|
39
|
+
alias: 'p',
|
|
40
|
+
type: 'boolean',
|
|
41
|
+
default: false,
|
|
42
|
+
describe: 'Non-interactive mode: output result and exit',
|
|
43
|
+
})
|
|
44
|
+
.option('max-turns', {
|
|
45
|
+
type: 'number',
|
|
46
|
+
default: 100,
|
|
47
|
+
describe: 'Maximum agent loop turns',
|
|
48
|
+
})
|
|
49
|
+
.version(VERSION)
|
|
50
|
+
.alias('v', 'version')
|
|
51
|
+
.help()
|
|
52
|
+
.alias('h', 'help')
|
|
53
|
+
.parse();
|
|
54
|
+
const prompt = argv._.join(' ') || undefined;
|
|
55
|
+
// Check for stdin pipe input
|
|
56
|
+
let stdinContent = '';
|
|
57
|
+
if (!process.stdin.isTTY) {
|
|
58
|
+
stdinContent = await readStdin();
|
|
59
|
+
}
|
|
60
|
+
// Load config (for model preference only; API keys come from env vars)
|
|
61
|
+
const config = await loadConfig();
|
|
62
|
+
const availableProviders = getAvailableProviders();
|
|
63
|
+
// If no providers configured, show helpful message and exit
|
|
64
|
+
if (availableProviders.length === 0) {
|
|
65
|
+
printNoApiKeyMessage();
|
|
66
|
+
process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
// Resolve model
|
|
69
|
+
const modelId = resolveModelId(argv.model, config);
|
|
70
|
+
if (!modelId) {
|
|
71
|
+
// User specified a model whose provider has no key
|
|
72
|
+
const requested = argv.model;
|
|
73
|
+
if (requested) {
|
|
74
|
+
const provider = requested.split(':')[0];
|
|
75
|
+
const envVar = getEnvVarName(provider) ?? `${provider.toUpperCase()}_API_KEY`;
|
|
76
|
+
console.error(`Error: ${envVar} is not set. Please set this environment variable to use ${requested}.`);
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
printNoApiKeyMessage();
|
|
80
|
+
}
|
|
81
|
+
process.exit(1);
|
|
82
|
+
}
|
|
83
|
+
// Create registry and get model
|
|
84
|
+
const registry = createModelRegistry();
|
|
85
|
+
const model = registry.languageModel(modelId);
|
|
86
|
+
const options = {
|
|
87
|
+
modelId,
|
|
88
|
+
trustMode: argv.trust,
|
|
89
|
+
printMode: argv.print,
|
|
90
|
+
maxTurns: argv['max-turns'] ?? 100,
|
|
91
|
+
};
|
|
92
|
+
// Combine prompt with stdin
|
|
93
|
+
const fullPrompt = [stdinContent, prompt].filter(Boolean).join('\n\n');
|
|
94
|
+
// Start the app
|
|
95
|
+
const waitUntilExit = startApp(model, options, fullPrompt || undefined);
|
|
96
|
+
await waitUntilExit();
|
|
97
|
+
// Print session usage summary after Ink unmounts
|
|
98
|
+
printExitSummary();
|
|
99
|
+
}
|
|
100
|
+
/** Load .env file from cwd (walk up to find it, like dotenv convention) */
|
|
101
|
+
function loadEnvFile() {
|
|
102
|
+
let dir = process.cwd();
|
|
103
|
+
while (true) {
|
|
104
|
+
const envPath = path.join(dir, '.env');
|
|
105
|
+
if (fs.existsSync(envPath)) {
|
|
106
|
+
try {
|
|
107
|
+
process.loadEnvFile(envPath);
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
// Ignore parse errors
|
|
111
|
+
}
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
const parent = path.dirname(dir);
|
|
115
|
+
if (parent === dir)
|
|
116
|
+
break; // reached root
|
|
117
|
+
dir = parent;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
function printNoApiKeyMessage() {
|
|
121
|
+
const isWindows = process.platform === 'win32';
|
|
122
|
+
console.error('Error: No API key found.\n');
|
|
123
|
+
console.error('Option 1: Create a .env file in your project root:\n');
|
|
124
|
+
console.error(' cp .env.example .env');
|
|
125
|
+
console.error(' # Edit .env and fill in your API key\n');
|
|
126
|
+
console.error('Option 2: Set an environment variable:\n');
|
|
127
|
+
for (const { envKey } of PROVIDER_DETECTION_ORDER) {
|
|
128
|
+
const provider = envKey
|
|
129
|
+
.replace(/_API_KEY$/, '')
|
|
130
|
+
.replace('GOOGLE_GENERATIVE_AI', 'google')
|
|
131
|
+
.replace('MOONSHOT', 'moonshotai')
|
|
132
|
+
.toLowerCase();
|
|
133
|
+
const url = PROVIDER_KEY_URLS[provider] ?? '';
|
|
134
|
+
console.error(` ${envKey.padEnd(32)} ${url}`);
|
|
135
|
+
}
|
|
136
|
+
console.error(`\n OPENAI_COMPATIBLE_API_KEY (custom OpenAI-compatible endpoint)`);
|
|
137
|
+
if (isWindows) {
|
|
138
|
+
console.error('\nExample (PowerShell):');
|
|
139
|
+
console.error(' $env:ANTHROPIC_API_KEY="sk-ant-..."');
|
|
140
|
+
console.error(' xc');
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
console.error('\nExample:');
|
|
144
|
+
console.error(' export ANTHROPIC_API_KEY=sk-ant-...');
|
|
145
|
+
console.error(' xc');
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
function readStdin() {
|
|
149
|
+
return new Promise((resolve) => {
|
|
150
|
+
let data = '';
|
|
151
|
+
process.stdin.setEncoding('utf-8');
|
|
152
|
+
process.stdin.on('data', (chunk) => {
|
|
153
|
+
data += chunk;
|
|
154
|
+
});
|
|
155
|
+
process.stdin.on('end', () => {
|
|
156
|
+
resolve(data);
|
|
157
|
+
});
|
|
158
|
+
// Timeout for stdin — don't hang forever
|
|
159
|
+
setTimeout(() => resolve(data), 1000);
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
// Handle Ctrl+C gracefully — save session before exit
|
|
163
|
+
let sigintCount = 0;
|
|
164
|
+
process.on('SIGINT', () => {
|
|
165
|
+
sigintCount++;
|
|
166
|
+
if (sigintCount >= 2) {
|
|
167
|
+
// Force exit on second Ctrl+C
|
|
168
|
+
process.exit(1);
|
|
169
|
+
}
|
|
170
|
+
const cleanup = getCleanupFn();
|
|
171
|
+
if (cleanup) {
|
|
172
|
+
cleanup()
|
|
173
|
+
.catch(() => {
|
|
174
|
+
// Don't crash on cleanup failure
|
|
175
|
+
})
|
|
176
|
+
.finally(() => {
|
|
177
|
+
printExitSummary();
|
|
178
|
+
process.exit(0);
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
printExitSummary();
|
|
183
|
+
process.exit(0);
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
main().catch((err) => {
|
|
187
|
+
console.error('Fatal error:', err);
|
|
188
|
+
process.exit(1);
|
|
189
|
+
});
|
|
190
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { AgentOptions, LanguageModel } from '@x-code/core';
|
|
2
|
+
interface AppProps {
|
|
3
|
+
model: LanguageModel;
|
|
4
|
+
options: AgentOptions;
|
|
5
|
+
initialPrompt?: string;
|
|
6
|
+
onCleanupReady?: (fn: () => Promise<void>) => void;
|
|
7
|
+
onUsageUpdate?: (usage: import('@x-code/core').TokenUsage, modelId: string) => void;
|
|
8
|
+
}
|
|
9
|
+
/** Slash commands — used for both help text and tab completion */
|
|
10
|
+
export declare const SLASH_COMMANDS: readonly [{
|
|
11
|
+
readonly name: "/help";
|
|
12
|
+
readonly description: "Show this help message";
|
|
13
|
+
}, {
|
|
14
|
+
readonly name: "/model";
|
|
15
|
+
readonly description: "Switch model or list available models";
|
|
16
|
+
}, {
|
|
17
|
+
readonly name: "/usage";
|
|
18
|
+
readonly description: "Show token usage and cost";
|
|
19
|
+
}, {
|
|
20
|
+
readonly name: "/clear";
|
|
21
|
+
readonly description: "Clear conversation history";
|
|
22
|
+
}, {
|
|
23
|
+
readonly name: "/compact";
|
|
24
|
+
readonly description: "Manually compress context";
|
|
25
|
+
}, {
|
|
26
|
+
readonly name: "/init";
|
|
27
|
+
readonly description: "Initialize project knowledge";
|
|
28
|
+
}, {
|
|
29
|
+
readonly name: "/session save";
|
|
30
|
+
readonly description: "Save current session";
|
|
31
|
+
}, {
|
|
32
|
+
readonly name: "/plan";
|
|
33
|
+
readonly description: "Enter plan mode";
|
|
34
|
+
}, {
|
|
35
|
+
readonly name: "/exit";
|
|
36
|
+
readonly description: "Exit (saves session)";
|
|
37
|
+
}];
|
|
38
|
+
export declare function App({ model, options, initialPrompt, onCleanupReady, onUsageUpdate }: AppProps): import("react/jsx-runtime").JSX.Element;
|
|
39
|
+
export {};
|
|
40
|
+
//# sourceMappingURL=App.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../../src/ui/components/App.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAa/D,UAAU,QAAQ;IAChB,KAAK,EAAE,aAAa,CAAA;IACpB,OAAO,EAAE,YAAY,CAAA;IACrB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,cAAc,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,CAAA;IAClD,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,cAAc,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;CACpF;AAED,kEAAkE;AAClE,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;EAUjB,CAAA;AAQV,wBAAgB,GAAG,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,aAAa,EAAE,EAAE,QAAQ,2CAmR7F"}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
// @x-code/cli — Root App component
|
|
3
|
+
import { useEffect } from 'react';
|
|
4
|
+
import { Box, Text, useApp, useInput } from 'ink';
|
|
5
|
+
import { MODEL_ALIASES, VERSION, createModelRegistry, initProject, loadConfig, resolveModelId } from '@x-code/core';
|
|
6
|
+
import { useAgent } from '../hooks/use-agent.js';
|
|
7
|
+
import { ACCENT, ERROR, WARNING } from '../theme.js';
|
|
8
|
+
import { ChatInput } from './ChatInput.js';
|
|
9
|
+
import { MessageList } from './MessageList.js';
|
|
10
|
+
import { Permission } from './Permission.js';
|
|
11
|
+
import { SelectOptions } from './SelectOptions.js';
|
|
12
|
+
import { ShellOutput } from './ShellOutput.js';
|
|
13
|
+
import { Spinner } from './Spinner.js';
|
|
14
|
+
import { StreamingText } from './StreamingText.js';
|
|
15
|
+
import { ToolCall } from './ToolCall.js';
|
|
16
|
+
/** Slash commands — used for both help text and tab completion */
|
|
17
|
+
export const SLASH_COMMANDS = [
|
|
18
|
+
{ name: '/help', description: 'Show this help message' },
|
|
19
|
+
{ name: '/model', description: 'Switch model or list available models' },
|
|
20
|
+
{ name: '/usage', description: 'Show token usage and cost' },
|
|
21
|
+
{ name: '/clear', description: 'Clear conversation history' },
|
|
22
|
+
{ name: '/compact', description: 'Manually compress context' },
|
|
23
|
+
{ name: '/init', description: 'Initialize project knowledge' },
|
|
24
|
+
{ name: '/session save', description: 'Save current session' },
|
|
25
|
+
{ name: '/plan', description: 'Enter plan mode' },
|
|
26
|
+
{ name: '/exit', description: 'Exit (saves session)' },
|
|
27
|
+
];
|
|
28
|
+
const HELP_TEXT = `X-Code CLI v${VERSION}\n\n` +
|
|
29
|
+
SLASH_COMMANDS.map((c) => ` ${c.name.padEnd(16)} ${c.description}`).join('\n') +
|
|
30
|
+
`\n\nModel aliases: ${Object.keys(MODEL_ALIASES).join(', ')}` +
|
|
31
|
+
`\nKeyboard: Ctrl+C to abort current operation`;
|
|
32
|
+
export function App({ model, options, initialPrompt, onCleanupReady, onUsageUpdate }) {
|
|
33
|
+
const { exit } = useApp();
|
|
34
|
+
const { state, submit, resolvePermission, resolveQuestion, cleanup, clear, compact, switchModel, saveCurrentSession, dismissSession, addInfoMessage, addUserMessage, } = useAgent(model, options);
|
|
35
|
+
// Register cleanup function for graceful exit (SIGINT)
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
onCleanupReady?.(cleanup);
|
|
38
|
+
}, [cleanup]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
39
|
+
// Sync usage to the global ref so exit handler can print it
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
onUsageUpdate?.(state.usage, options.modelId);
|
|
42
|
+
}, [state.usage, options.modelId]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
43
|
+
// Handle initial prompt
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
if (initialPrompt) {
|
|
46
|
+
submit(initialPrompt);
|
|
47
|
+
}
|
|
48
|
+
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
|
49
|
+
// Handle print mode — exit after first response
|
|
50
|
+
useEffect(() => {
|
|
51
|
+
if (options.printMode && !state.isLoading && state.messages.length > 1) {
|
|
52
|
+
cleanup().then(() => exit());
|
|
53
|
+
}
|
|
54
|
+
}, [state.isLoading, state.messages.length, options.printMode]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
55
|
+
// Handle session continuation Y/N
|
|
56
|
+
useInput((input) => {
|
|
57
|
+
if (!state.latestSession)
|
|
58
|
+
return;
|
|
59
|
+
if (input.toLowerCase() === 'y') {
|
|
60
|
+
const session = state.latestSession;
|
|
61
|
+
dismissSession();
|
|
62
|
+
const pendingList = session.pendingWork.map((w) => `- ${w}`).join('\n');
|
|
63
|
+
submit(`Continue from previous session "${session.title}".\nPending work:\n${pendingList}\n\nPlease continue where we left off.`);
|
|
64
|
+
}
|
|
65
|
+
else if (input.toLowerCase() === 'n' || input === '\r') {
|
|
66
|
+
dismissSession();
|
|
67
|
+
}
|
|
68
|
+
}, {
|
|
69
|
+
isActive: !!state.latestSession && !state.isLoading && !state.pendingPermission && !state.pendingQuestion,
|
|
70
|
+
});
|
|
71
|
+
/** Echo a slash command to the message history (so the user can see what they typed) */
|
|
72
|
+
function echoCommand(text) {
|
|
73
|
+
addUserMessage(text);
|
|
74
|
+
}
|
|
75
|
+
/** Handle user input (including slash commands) */
|
|
76
|
+
async function handleSubmit(text) {
|
|
77
|
+
// Slash commands
|
|
78
|
+
if (text.startsWith('/')) {
|
|
79
|
+
const parts = text.slice(1).trim().split(/\s+/);
|
|
80
|
+
const command = parts[0].toLowerCase();
|
|
81
|
+
const arg = parts.slice(1).join(' ');
|
|
82
|
+
switch (command) {
|
|
83
|
+
case 'help':
|
|
84
|
+
echoCommand(text);
|
|
85
|
+
addInfoMessage(HELP_TEXT);
|
|
86
|
+
return;
|
|
87
|
+
case 'model':
|
|
88
|
+
echoCommand(text);
|
|
89
|
+
await handleModelSwitch(arg);
|
|
90
|
+
return;
|
|
91
|
+
case 'usage':
|
|
92
|
+
echoCommand(text);
|
|
93
|
+
handleUsage();
|
|
94
|
+
return;
|
|
95
|
+
case 'clear':
|
|
96
|
+
clear();
|
|
97
|
+
addInfoMessage('Conversation cleared.');
|
|
98
|
+
return;
|
|
99
|
+
case 'compact':
|
|
100
|
+
echoCommand(text);
|
|
101
|
+
await handleCompact();
|
|
102
|
+
return;
|
|
103
|
+
case 'init':
|
|
104
|
+
echoCommand(text);
|
|
105
|
+
await handleInit();
|
|
106
|
+
return;
|
|
107
|
+
case 'session':
|
|
108
|
+
echoCommand(text);
|
|
109
|
+
if (arg.toLowerCase() === 'save') {
|
|
110
|
+
await handleSessionSave();
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
addInfoMessage('Unknown session command. Use `/session save`.');
|
|
114
|
+
}
|
|
115
|
+
return;
|
|
116
|
+
case 'plan':
|
|
117
|
+
await submit('Please enter plan mode to explore the codebase and design an implementation plan before making changes.');
|
|
118
|
+
return;
|
|
119
|
+
case 'exit':
|
|
120
|
+
await cleanup();
|
|
121
|
+
exit();
|
|
122
|
+
return;
|
|
123
|
+
default:
|
|
124
|
+
echoCommand(text);
|
|
125
|
+
addInfoMessage(`Unknown command: /${command}. Type /help for available commands.`);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
await submit(text);
|
|
130
|
+
}
|
|
131
|
+
async function handleModelSwitch(arg) {
|
|
132
|
+
if (!arg) {
|
|
133
|
+
// List available models
|
|
134
|
+
const _config = await loadConfig();
|
|
135
|
+
const aliases = Object.entries(MODEL_ALIASES)
|
|
136
|
+
.map(([alias, id]) => ` ${alias} → ${id}`)
|
|
137
|
+
.join('\n');
|
|
138
|
+
addInfoMessage(`Current model: ${options.modelId}\n\nAvailable aliases:\n${aliases}`);
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
try {
|
|
142
|
+
const config = await loadConfig();
|
|
143
|
+
const newModelId = resolveModelId(arg, config);
|
|
144
|
+
if (!newModelId) {
|
|
145
|
+
addInfoMessage(`Could not resolve model: ${arg}`);
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
const registry = createModelRegistry();
|
|
149
|
+
const newModel = registry.languageModel(newModelId);
|
|
150
|
+
switchModel(newModelId, newModel);
|
|
151
|
+
addInfoMessage(`Model switched to: ${newModelId}`);
|
|
152
|
+
}
|
|
153
|
+
catch (err) {
|
|
154
|
+
addInfoMessage(`Failed to switch model: ${err instanceof Error ? err.message : String(err)}`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
function handleUsage() {
|
|
158
|
+
const { usage } = state;
|
|
159
|
+
const symbol = usage.costCurrency === 'CNY' ? '¥' : '$';
|
|
160
|
+
const costStr = usage.estimatedCost > 0 ? `${symbol}${usage.estimatedCost.toFixed(4)}` : 'N/A';
|
|
161
|
+
addInfoMessage(`Token Usage\n` +
|
|
162
|
+
` Input: ${usage.inputTokens.toLocaleString()} tokens\n` +
|
|
163
|
+
` Output: ${usage.outputTokens.toLocaleString()} tokens\n` +
|
|
164
|
+
` Total: ${usage.totalTokens.toLocaleString()} tokens\n` +
|
|
165
|
+
` Cost: ${costStr}\n` +
|
|
166
|
+
` Model: ${options.modelId}`);
|
|
167
|
+
}
|
|
168
|
+
async function handleCompact() {
|
|
169
|
+
addInfoMessage('Compressing context...');
|
|
170
|
+
await compact();
|
|
171
|
+
addInfoMessage('Context compressed.');
|
|
172
|
+
}
|
|
173
|
+
async function handleInit() {
|
|
174
|
+
addInfoMessage('Analyzing project structure...');
|
|
175
|
+
try {
|
|
176
|
+
const result = await initProject();
|
|
177
|
+
const factLines = result.detectedFacts.map((f) => ` - ${f}`).join('\n');
|
|
178
|
+
const fileLines = result.createdFiles.map((f) => ` - ${f}`).join('\n');
|
|
179
|
+
addInfoMessage(`**Project initialized**\n\nDetected:\n${factLines}\n\nCreated:\n${fileLines || ' (no new files)'}`);
|
|
180
|
+
}
|
|
181
|
+
catch (err) {
|
|
182
|
+
addInfoMessage(`Init failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
async function handleSessionSave() {
|
|
186
|
+
const saved = await saveCurrentSession();
|
|
187
|
+
if (saved) {
|
|
188
|
+
addInfoMessage('Session saved.');
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
addInfoMessage('No active session to save.');
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return (_jsxs(Box, { flexDirection: "column", padding: 1, children: [state.latestSession && !state.isLoading && (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: ACCENT, paddingX: 1, marginBottom: 1, children: [_jsxs(Text, { color: ACCENT, bold: true, children: ["Previous session: \"", state.latestSession.title, "\" (", state.latestSession.status, ")"] }), state.latestSession.pendingWork.length > 0 && (_jsxs(Box, { flexDirection: "column", marginLeft: 2, children: [_jsx(Text, { dimColor: true, children: "Pending work:" }), state.latestSession.pendingWork.map((w, i) => (_jsxs(Text, { dimColor: true, children: ["- ", w] }, i)))] })), _jsx(Text, { color: WARNING, children: "Continue previous session? (y/n)" })] })), _jsx(MessageList, { messages: state.messages }), state.streamingText && _jsx(StreamingText, { text: state.streamingText }), state.currentToolCall && !state.pendingPermission && (_jsx(ToolCall, { toolName: state.currentToolCall.toolName, input: state.currentToolCall.input, status: "running" })), state.shellOutput && _jsx(ShellOutput, { output: state.shellOutput }), state.pendingPermission && (_jsx(Permission, { toolName: state.pendingPermission.toolName, input: state.pendingPermission.input, onResolve: resolvePermission })), state.pendingQuestion && (_jsx(SelectOptions, { question: state.pendingQuestion.question, options: state.pendingQuestion.options, onSelect: resolveQuestion })), state.isLoading && !state.streamingText && !state.currentToolCall && _jsx(Spinner, {}), state.error && _jsxs(Text, { color: ERROR, children: ["Error: ", state.error] }), !state.latestSession && (_jsx(ChatInput, { onSubmit: handleSubmit, disabled: state.isLoading || !!state.pendingPermission || !!state.pendingQuestion, commands: SLASH_COMMANDS }))] }));
|
|
195
|
+
}
|
|
196
|
+
//# sourceMappingURL=App.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"App.js","sourceRoot":"","sources":["../../../src/ui/components/App.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AppHeader.d.ts","sourceRoot":"","sources":["../../../src/ui/components/AppHeader.tsx"],"names":[],"mappings":"AA8BA;;;GAGG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAyBjD"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// @x-code/cli — Startup header banner
|
|
2
|
+
//
|
|
3
|
+
// printHeader() writes the banner directly to stdout BEFORE Ink starts.
|
|
4
|
+
// This avoids the Ink <Static> re-render bug where the header would
|
|
5
|
+
// appear multiple times as the dynamic area changes height.
|
|
6
|
+
import { Chalk } from 'chalk';
|
|
7
|
+
import { VERSION } from '@x-code/core';
|
|
8
|
+
import { ACCENT } from '../theme.js';
|
|
9
|
+
const c = new Chalk({ level: 3 });
|
|
10
|
+
// ── ASCII logos for different terminal widths ──
|
|
11
|
+
const LOGO_WIDE = `
|
|
12
|
+
██╗ ██╗ ██████╗ ██████╗ ██████╗ ███████╗
|
|
13
|
+
╚██╗██╔╝ ██╔════╝██╔═══██╗██╔══██╗██╔════╝
|
|
14
|
+
╚███╔╝ █████╗██║ ██║ ██║██║ ██║█████╗
|
|
15
|
+
██╔██╗ ╚════╝██║ ██║ ██║██║ ██║██╔══╝
|
|
16
|
+
██╔╝ ██╗ ╚██████╗╚██████╔╝██████╔╝███████╗
|
|
17
|
+
╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝`;
|
|
18
|
+
const LOGO_COMPACT = `
|
|
19
|
+
╔═╗ ╔═╗╔═╗╔╦╗╔═╗
|
|
20
|
+
╔╩╦╝ ───── ║ ║ ║ ║║║╣
|
|
21
|
+
╩ ╚═ ╚═╝╚═╝═╩╝╚═╝`;
|
|
22
|
+
const LOGO_TINY = ' X-Code';
|
|
23
|
+
/**
|
|
24
|
+
* Print the startup header banner directly to stdout.
|
|
25
|
+
* Call this ONCE before Ink's render() so it is never re-drawn.
|
|
26
|
+
*/
|
|
27
|
+
export function printHeader(modelId) {
|
|
28
|
+
const cols = process.stdout.columns ?? 80;
|
|
29
|
+
// Pick logo based on terminal width
|
|
30
|
+
let logo;
|
|
31
|
+
if (cols >= 52) {
|
|
32
|
+
logo = LOGO_WIDE;
|
|
33
|
+
}
|
|
34
|
+
else if (cols >= 30) {
|
|
35
|
+
logo = LOGO_COMPACT;
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
logo = LOGO_TINY;
|
|
39
|
+
}
|
|
40
|
+
// Extract provider and model from "provider:model-name"
|
|
41
|
+
const [provider, ...modelParts] = modelId.split(':');
|
|
42
|
+
const modelName = modelParts.join(':') || modelId;
|
|
43
|
+
const lines = [
|
|
44
|
+
c.hex(ACCENT).bold(logo),
|
|
45
|
+
` ${c.dim(`v${VERSION}`)} ${c.dim('│')} ${c.hex(ACCENT)(provider)} ${c.dim('/')} ${c.hex(ACCENT).bold(modelName)}`,
|
|
46
|
+
` ${c.dim('Type /help for commands, Ctrl+C to abort')}`,
|
|
47
|
+
'', // blank line after header
|
|
48
|
+
];
|
|
49
|
+
process.stdout.write(lines.join('\n') + '\n');
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=AppHeader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AppHeader.js","sourceRoot":"","sources":["../../../src/ui/components/AppHeader.tsx"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,EAAE;AACF,wEAAwE;AACxE,oEAAoE;AACpE,4DAA4D;AAC5D,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAA;AAE7B,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAEtC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEpC,MAAM,CAAC,GAAG,IAAI,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAA;AAEjC,kDAAkD;AAElD,MAAM,SAAS,GAAG;;;;;;kDAMgC,CAAA;AAElD,MAAM,YAAY,GAAG;;;0BAGK,CAAA;AAE1B,MAAM,SAAS,GAAG,UAAU,CAAA;AAE5B;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,OAAe;IACzC,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAA;IAEzC,oCAAoC;IACpC,IAAI,IAAY,CAAA;IAChB,IAAI,IAAI,IAAI,EAAE,EAAE,CAAC;QACf,IAAI,GAAG,SAAS,CAAA;IAClB,CAAC;SAAM,IAAI,IAAI,IAAI,EAAE,EAAE,CAAC;QACtB,IAAI,GAAG,YAAY,CAAA;IACrB,CAAC;SAAM,CAAC;QACN,IAAI,GAAG,SAAS,CAAA;IAClB,CAAC;IAED,wDAAwD;IACxD,MAAM,CAAC,QAAQ,EAAE,GAAG,UAAU,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IACpD,MAAM,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,OAAO,CAAA;IAEjD,MAAM,KAAK,GAAG;QACZ,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QACxB,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE;QAClH,IAAI,CAAC,CAAC,GAAG,CAAC,0CAA0C,CAAC,EAAE;QACvD,EAAE,EAAE,0BAA0B;KAC/B,CAAA;IAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAA;AAC/C,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface SlashCommand {
|
|
2
|
+
name: string;
|
|
3
|
+
description: string;
|
|
4
|
+
}
|
|
5
|
+
interface ChatInputProps {
|
|
6
|
+
onSubmit: (text: string) => void;
|
|
7
|
+
disabled?: boolean;
|
|
8
|
+
commands?: readonly SlashCommand[];
|
|
9
|
+
}
|
|
10
|
+
export declare function ChatInput({ onSubmit, disabled, commands }: ChatInputProps): import("react/jsx-runtime").JSX.Element | null;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=ChatInput.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatInput.d.ts","sourceRoot":"","sources":["../../../src/ui/components/ChatInput.tsx"],"names":[],"mappings":"AAeA,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,UAAU,cAAc;IACtB,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAChC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,QAAQ,CAAC,EAAE,SAAS,YAAY,EAAE,CAAA;CACnC;AAED,wBAAgB,SAAS,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAa,EAAE,EAAE,cAAc,kDAgI9E"}
|