mirror of
https://github.com/MoonshotAI/kimi-code.git
synced 2026-07-09 17:29:12 +00:00
Revert "fix: fail early when Git Bash is missing (#430)"
This reverts commit be0da5ff39.
This commit is contained in:
parent
be0da5ff39
commit
028cbc4ec4
10 changed files with 24 additions and 117 deletions
|
|
@ -1,7 +0,0 @@
|
|||
---
|
||||
"@moonshot-ai/agent-core": patch
|
||||
"@moonshot-ai/kimi-code-sdk": patch
|
||||
"@moonshot-ai/kimi-code": patch
|
||||
---
|
||||
|
||||
Fail early when Git Bash is missing on Windows before starting CLI sessions.
|
||||
|
|
@ -110,7 +110,6 @@ export async function runPrompt(
|
|||
removeTerminationCleanup = installPromptTerminationCleanup(promptProcess, cleanupPromptRun);
|
||||
|
||||
try {
|
||||
await harness.checkRuntimeEnvironment();
|
||||
await harness.ensureConfigFile();
|
||||
const config = await harness.getConfig();
|
||||
const { session, resumed, restorePermission, telemetryModel, goalModel } =
|
||||
|
|
|
|||
|
|
@ -34,6 +34,21 @@ export async function runShell(
|
|||
runOptions: { readonly migrateOnly?: boolean } = {},
|
||||
): Promise<void> {
|
||||
const startedAt = Date.now();
|
||||
const configStartedAt = startedAt;
|
||||
let tuiConfig: TuiConfig;
|
||||
let configWarning: string | undefined;
|
||||
try {
|
||||
tuiConfig = await loadTuiConfig();
|
||||
} catch (error) {
|
||||
if (!(error instanceof TuiConfigParseError)) throw error;
|
||||
tuiConfig = error.fallback;
|
||||
configWarning = error.message;
|
||||
}
|
||||
|
||||
// Resolve `theme = "auto"` against the live terminal once, before pi-tui
|
||||
// grabs stdin. Explicit `dark` / `light` skip detection.
|
||||
const resolvedTheme = tuiConfig.theme === 'auto' ? await detectTerminalTheme() : tuiConfig.theme;
|
||||
|
||||
const workDir = process.cwd();
|
||||
const telemetryBootstrap = createCliTelemetryBootstrap();
|
||||
const telemetryClient: TelemetryClient = {
|
||||
|
|
@ -63,23 +78,6 @@ export async function runShell(
|
|||
platform: `${process.platform}/${process.arch}`,
|
||||
workDir,
|
||||
});
|
||||
await harness.checkRuntimeEnvironment();
|
||||
|
||||
const configStartedAt = Date.now();
|
||||
let tuiConfig: TuiConfig;
|
||||
let configWarning: string | undefined;
|
||||
try {
|
||||
tuiConfig = await loadTuiConfig();
|
||||
} catch (error) {
|
||||
if (!(error instanceof TuiConfigParseError)) throw error;
|
||||
tuiConfig = error.fallback;
|
||||
configWarning = error.message;
|
||||
}
|
||||
|
||||
// Resolve `theme = "auto"` against the live terminal once, before pi-tui
|
||||
// grabs stdin. Explicit `dark` / `light` skip detection.
|
||||
const resolvedTheme = tuiConfig.theme === 'auto' ? await detectTerminalTheme() : tuiConfig.theme;
|
||||
|
||||
await harness.ensureConfigFile();
|
||||
const migrationPlan = await detectPendingMigration({
|
||||
sourceHome: join(homedir(), '.kimi'),
|
||||
|
|
|
|||
|
|
@ -112,7 +112,6 @@ const mocks = vi.hoisted(() => {
|
|||
mainEvent,
|
||||
experimentalFeatures: [{ id: 'goal_command', enabled: true }],
|
||||
sessions: [] as Array<{ readonly id: string; readonly workDir: string }>,
|
||||
harnessCheckRuntimeEnvironment: vi.fn(async () => undefined),
|
||||
};
|
||||
});
|
||||
|
||||
|
|
@ -123,7 +122,6 @@ vi.mock('@moonshot-ai/kimi-code-sdk', async (importOriginal) => {
|
|||
createKimiHarness: () => ({
|
||||
homeDir: '/tmp/kimi-goal-home',
|
||||
auth: { getCachedAccessToken: vi.fn() },
|
||||
checkRuntimeEnvironment: mocks.harnessCheckRuntimeEnvironment,
|
||||
ensureConfigFile: vi.fn(),
|
||||
getConfig: vi.fn(async () => ({ providers: {}, defaultModel: 'k2', telemetry: true })),
|
||||
getExperimentalFeatures: vi.fn(async () => mocks.experimentalFeatures),
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@ const mocks = vi.hoisted(() => {
|
|||
agentEvent,
|
||||
mainEvent,
|
||||
kimiHarnessConstructor: vi.fn(),
|
||||
harnessCheckRuntimeEnvironment: vi.fn(async () => undefined),
|
||||
harnessEnsureConfigFile: vi.fn(),
|
||||
harnessGetConfig: vi.fn(
|
||||
async (): Promise<{ providers: {}; defaultModel?: string; telemetry: boolean }> => ({
|
||||
|
|
@ -90,7 +89,6 @@ vi.mock('@moonshot-ai/kimi-code-sdk', async (importOriginal) => {
|
|||
return {
|
||||
homeDir,
|
||||
auth: { getCachedAccessToken: mocks.harnessGetCachedAccessToken },
|
||||
checkRuntimeEnvironment: mocks.harnessCheckRuntimeEnvironment,
|
||||
ensureConfigFile: mocks.harnessEnsureConfigFile,
|
||||
getConfig: mocks.harnessGetConfig,
|
||||
getExperimentalFeatures: mocks.harnessGetExperimentalFeatures,
|
||||
|
|
@ -189,7 +187,6 @@ describe('runPrompt', () => {
|
|||
mocks.resolveKimiHome.mockImplementation(
|
||||
(homeDir?: string) => homeDir ?? '/tmp/kimi-code-test-home',
|
||||
);
|
||||
mocks.harnessCheckRuntimeEnvironment.mockResolvedValue(undefined);
|
||||
mocks.harnessCreatesDeviceIdOnConstruction = false;
|
||||
});
|
||||
|
||||
|
|
@ -202,10 +199,6 @@ describe('runPrompt', () => {
|
|||
expect(mocks.kimiHarnessConstructor).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ skillDirs: ['/skills'], uiMode: 'print' }),
|
||||
);
|
||||
expect(mocks.harnessCheckRuntimeEnvironment).toHaveBeenCalledOnce();
|
||||
expect(mocks.harnessCheckRuntimeEnvironment.mock.invocationCallOrder[0]).toBeLessThan(
|
||||
mocks.harnessEnsureConfigFile.mock.invocationCallOrder[0]!,
|
||||
);
|
||||
expect(mocks.harnessCreateSession).toHaveBeenCalledWith({
|
||||
workDir: process.cwd(),
|
||||
model: 'k2',
|
||||
|
|
@ -221,23 +214,6 @@ describe('runPrompt', () => {
|
|||
expect(mocks.harnessClose).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('stops prompt startup when runtime environment check fails', async () => {
|
||||
const stdout = writer();
|
||||
const stderr = writer();
|
||||
mocks.harnessCheckRuntimeEnvironment.mockRejectedValueOnce(new Error('Git Bash missing'));
|
||||
|
||||
await expect(runPrompt(opts(), '1.2.3-test', { stdout, stderr })).rejects.toThrow(
|
||||
'Git Bash missing',
|
||||
);
|
||||
|
||||
expect(mocks.harnessCheckRuntimeEnvironment).toHaveBeenCalledOnce();
|
||||
expect(mocks.harnessEnsureConfigFile).not.toHaveBeenCalled();
|
||||
expect(mocks.harnessGetConfig).not.toHaveBeenCalled();
|
||||
expect(mocks.harnessCreateSession).not.toHaveBeenCalled();
|
||||
expect(mocks.session.prompt).not.toHaveBeenCalled();
|
||||
expect(mocks.harnessClose).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
it('uses the CLI model override when creating a fresh prompt session', async () => {
|
||||
await runPrompt(opts({ model: 'kimi-code/k2.5' }), '1.2.3-test', {
|
||||
stdout: { write: vi.fn(() => true) },
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ const mocks = vi.hoisted(() => {
|
|||
loadTuiConfig: vi.fn(),
|
||||
detectTerminalTheme: vi.fn(),
|
||||
kimiHarnessConstructor: vi.fn(),
|
||||
harnessCheckRuntimeEnvironment: vi.fn(async () => undefined),
|
||||
harnessEnsureConfigFile: vi.fn(),
|
||||
harnessGetConfig: vi.fn(async () => ({
|
||||
providers: {},
|
||||
|
|
@ -82,7 +81,6 @@ vi.mock('@moonshot-ai/kimi-code-sdk', async (importOriginal) => {
|
|||
getCachedAccessToken: mocks.harnessGetCachedAccessToken,
|
||||
},
|
||||
ensureConfigFile: mocks.harnessEnsureConfigFile,
|
||||
checkRuntimeEnvironment: mocks.harnessCheckRuntimeEnvironment,
|
||||
getConfig: mocks.harnessGetConfig,
|
||||
close: mocks.harnessClose,
|
||||
track: mocks.harnessTrack,
|
||||
|
|
@ -151,7 +149,6 @@ describe('runShell', () => {
|
|||
defaultModel: 'k2',
|
||||
telemetry: true,
|
||||
});
|
||||
mocks.harnessCheckRuntimeEnvironment.mockResolvedValue(undefined);
|
||||
mocks.tuiGetStartupMcpMs.mockResolvedValue(0);
|
||||
mocks.tuiGetCurrentSessionId.mockReturnValue('');
|
||||
mocks.tuiHasSessionContent.mockReturnValue(false);
|
||||
|
|
@ -194,10 +191,6 @@ describe('runShell', () => {
|
|||
}),
|
||||
}),
|
||||
);
|
||||
expect(mocks.harnessCheckRuntimeEnvironment).toHaveBeenCalledOnce();
|
||||
expect(mocks.harnessCheckRuntimeEnvironment.mock.invocationCallOrder[0]).toBeLessThan(
|
||||
mocks.harnessEnsureConfigFile.mock.invocationCallOrder[0]!,
|
||||
);
|
||||
expect(mocks.harnessEnsureConfigFile).toHaveBeenCalledOnce();
|
||||
expect(mocks.harnessEnsureConfigFile.mock.invocationCallOrder[0]).toBeLessThan(
|
||||
mocks.harnessGetConfig.mock.invocationCallOrder[0]!,
|
||||
|
|
@ -251,38 +244,6 @@ describe('runShell', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('stops startup when runtime environment check fails', async () => {
|
||||
mocks.loadTuiConfig.mockResolvedValue({
|
||||
theme: 'dark',
|
||||
editorCommand: null,
|
||||
notifications: { enabled: true, condition: 'unfocused' },
|
||||
});
|
||||
mocks.harnessCheckRuntimeEnvironment.mockRejectedValueOnce(new Error('Git Bash missing'));
|
||||
|
||||
await expect(
|
||||
runShell(
|
||||
{
|
||||
session: undefined,
|
||||
continue: false,
|
||||
yolo: false,
|
||||
auto: false,
|
||||
plan: false,
|
||||
model: undefined,
|
||||
outputFormat: undefined,
|
||||
prompt: undefined,
|
||||
skillsDirs: [],
|
||||
},
|
||||
'1.2.3-test',
|
||||
),
|
||||
).rejects.toThrow('Git Bash missing');
|
||||
|
||||
expect(mocks.harnessCheckRuntimeEnvironment).toHaveBeenCalledOnce();
|
||||
expect(mocks.harnessEnsureConfigFile).not.toHaveBeenCalled();
|
||||
expect(mocks.harnessGetConfig).not.toHaveBeenCalled();
|
||||
expect(mocks.kimiTuiConstructor).not.toHaveBeenCalled();
|
||||
expect(mocks.tuiStart).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('tracks first launch when device id creation reports first launch', async () => {
|
||||
mocks.loadTuiConfig.mockResolvedValue({
|
||||
theme: 'dark',
|
||||
|
|
|
|||
|
|
@ -357,7 +357,6 @@ type SessionAPIWithId = WithSessionId<SessionAPI>;
|
|||
|
||||
export interface CoreAPI extends SessionAPIWithId {
|
||||
getCoreInfo: (payload: EmptyPayload) => CoreInfo;
|
||||
checkRuntimeEnvironment: (payload: EmptyPayload) => void;
|
||||
getExperimentalFeatures: (payload: EmptyPayload) => readonly ExperimentalFeatureState[];
|
||||
getKimiConfig: (payload: GetKimiConfigPayload) => KimiConfig;
|
||||
setKimiConfig: (payload: SetKimiConfigPayload) => KimiConfig;
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ export class KimiCore implements PromisableMethods<CoreAPI> {
|
|||
readonly sessions = new Map<string, Session>();
|
||||
readonly telemetry: TelemetryClient;
|
||||
|
||||
private kaos: Promise<Kaos> | undefined;
|
||||
private kaos: Promise<Kaos>;
|
||||
private runtime: ToolServices | undefined;
|
||||
private config: KimiConfig;
|
||||
private readonly runtimeOverride: ToolServices | undefined;
|
||||
|
|
@ -148,6 +148,12 @@ export class KimiCore implements PromisableMethods<CoreAPI> {
|
|||
homeDir: this.homeDir,
|
||||
configPath: options.configPath,
|
||||
});
|
||||
this.kaos = LocalKaos.create().catch((error: unknown) => {
|
||||
if (error instanceof KaosShellNotFoundError) {
|
||||
throw new KimiError(ErrorCodes.SHELL_GIT_BASH_NOT_FOUND, error.message);
|
||||
}
|
||||
throw error;
|
||||
});
|
||||
this.runtimeOverride = options.runtime;
|
||||
this.runtime = options.runtime;
|
||||
this.kimiRequestHeaders = options.kimiRequestHeaders;
|
||||
|
|
@ -176,10 +182,6 @@ export class KimiCore implements PromisableMethods<CoreAPI> {
|
|||
this.sdk = rpcClient(this);
|
||||
}
|
||||
|
||||
async checkRuntimeEnvironment(_: EmptyPayload): Promise<void> {
|
||||
await this.getKaos();
|
||||
}
|
||||
|
||||
async createSession(input: CreateSessionPayload): Promise<SessionSummary> {
|
||||
const options = input;
|
||||
const workDir = requiredWorkDir('createSession', options.workDir);
|
||||
|
|
@ -209,7 +211,7 @@ export class KimiCore implements PromisableMethods<CoreAPI> {
|
|||
// ctor block throws, `session.close()` releases the sink (and mcp).
|
||||
const runtime = await this.resolveRuntime(config);
|
||||
const session = new Session({
|
||||
kaos: (await this.getKaos()).withCwd(workDir),
|
||||
kaos: (await this.kaos).withCwd(workDir),
|
||||
toolServices: runtime,
|
||||
config,
|
||||
id,
|
||||
|
|
@ -297,7 +299,7 @@ export class KimiCore implements PromisableMethods<CoreAPI> {
|
|||
const mcpConfig = this.mergePluginMcpConfig(withCallerMcp);
|
||||
const runtime = await this.resolveRuntime(config);
|
||||
const session = new Session({
|
||||
kaos: (await this.getKaos()).withCwd(summary.workDir),
|
||||
kaos: (await this.kaos).withCwd(summary.workDir),
|
||||
toolServices: runtime,
|
||||
config,
|
||||
id: summary.id,
|
||||
|
|
@ -735,16 +737,6 @@ export class KimiCore implements PromisableMethods<CoreAPI> {
|
|||
return runtime;
|
||||
}
|
||||
|
||||
private getKaos(): Promise<Kaos> {
|
||||
this.kaos ??= LocalKaos.create().catch((error: unknown) => {
|
||||
if (error instanceof KaosShellNotFoundError) {
|
||||
throw new KimiError(ErrorCodes.SHELL_GIT_BASH_NOT_FOUND, error.message);
|
||||
}
|
||||
throw error;
|
||||
});
|
||||
return this.kaos;
|
||||
}
|
||||
|
||||
private resolveSessionSkillConfig(config: KimiConfig): SessionSkillConfig {
|
||||
const explicitDirs = this.skillDirs.length > 0 ? this.skillDirs : undefined;
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -210,10 +210,6 @@ export class KimiHarness {
|
|||
await this.ensureConfigFileImpl();
|
||||
}
|
||||
|
||||
async checkRuntimeEnvironment(): Promise<void> {
|
||||
await this.rpc.checkRuntimeEnvironment();
|
||||
}
|
||||
|
||||
async setConfig(patch: KimiConfigPatch): Promise<KimiConfig> {
|
||||
return this.rpc.setConfig(patch);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,11 +99,6 @@ export abstract class SDKRpcClientBase {
|
|||
|
||||
protected abstract getRpc(): Promise<ResolvedCoreAPI>;
|
||||
|
||||
async checkRuntimeEnvironment(): Promise<void> {
|
||||
const rpc = await this.getRpc();
|
||||
return rpc.checkRuntimeEnvironment({});
|
||||
}
|
||||
|
||||
async createSession(input: CreateSessionOptions): Promise<SessionSummary> {
|
||||
const rpc = await this.getRpc();
|
||||
const { planMode, ...coreInput } = input;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue