Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion packages/codingcode/src/agent/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,10 @@ export const AgentLayer = Layer.effect(AgentService, Effect.gen(function* () {
})
: [];

const allResults = [...approvedResults, ...deniedResults];
const resultsById = new Map<string, any>();
for (const r of approvedResults) resultsById.set(r.id, r);
for (const r of deniedResults) resultsById.set(r.id, r);
const allResults = toolCalls.map((tc) => resultsById.get(tc.id));

let todoPrinted = false;
for (const r of allResults) {
Expand Down
6 changes: 2 additions & 4 deletions packages/codingcode/src/client/contracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,7 @@ export interface SettingsClient {
getAgentConfig(): Promise<{ maxSteps: number; maxStopContinuations: number }>;
setCompactionModel(compactionModel: string): Promise<{ compactionModel: string }>;
getMcpStatus(input: { cwd: string }): Promise<McpStatus[]>;
setMcpDisabled(body: { name: string; disabled: boolean; cwd: string }): Promise<void>;
resetMcpDisabled(body: { name: string; cwd: string }): Promise<void>;
setMcpEnabled(body: { name: string; enabled: boolean; cwd: string }): Promise<void>;
createMcpServer(input: { cwd: string; server: McpServerConfig }): Promise<void>;
updateMcpServer(input: { cwd: string; name: string; server: McpServerConfig }): Promise<void>;
deleteMcpServer(input: { cwd: string; name: string }): Promise<void>;
Expand All @@ -143,8 +142,7 @@ export interface SettingsClient {
createHook(input: { cwd: string; hook: UserHookConfig }): Promise<void>;
updateHook(input: { cwd: string; name: string; hook: UserHookConfig }): Promise<void>;
deleteHook(input: { cwd: string; name: string }): Promise<void>;
setHookDisabled(input: { cwd: string; name: string; disabled: boolean }): Promise<void>;
resetHookDisabled(body: { name: string; cwd: string }): Promise<void>;
setHookEnabled(input: { cwd: string; name: string; enabled: boolean }): Promise<void>;
getGlobalPermissionMode(input: { sessionId: string; cwd: string }): Promise<PermissionMode>;
setGlobalPermissionMode(input: {
sessionId: string;
Expand Down
26 changes: 6 additions & 20 deletions packages/codingcode/src/client/http/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,19 +42,12 @@ export function createHttpSettingsClient(
return apiGet<McpStatus[]>(`/api/settings/mcp${qsCwd(cwd)}`);
},

async setMcpDisabled({ name, disabled, cwd }) {
await apiPost(`/api/settings/mcp/${encodeURIComponent(name)}/disabled${qsCwd(cwd)}`, {
disabled,
async setMcpEnabled({ name, enabled, cwd }) {
await apiPost(`/api/settings/mcp/${encodeURIComponent(name)}/enabled${qsCwd(cwd)}`, {
enabled,
});
},

async resetMcpDisabled({ name, cwd }) {
await apiPost(
`/api/settings/mcp/${encodeURIComponent(name)}/disabled/reset${qsCwd(cwd)}`,
{}
);
},

async createMcpServer({ cwd, server }) {
await apiPost(`/api/settings/mcp${qsCwd(cwd)}`, server);
},
Expand Down Expand Up @@ -87,19 +80,12 @@ export function createHttpSettingsClient(
await apiDelete(`/api/settings/hooks/${encodeURIComponent(name)}${qsCwd(cwd)}`);
},

async setHookDisabled({ cwd, name, disabled }) {
await apiPost(`/api/settings/hooks/${encodeURIComponent(name)}/disabled${qsCwd(cwd)}`, {
disabled,
async setHookEnabled({ cwd, name, enabled }) {
await apiPost(`/api/settings/hooks/${encodeURIComponent(name)}/enabled${qsCwd(cwd)}`, {
enabled,
});
},

async resetHookDisabled({ name, cwd }) {
await apiPost(
`/api/settings/hooks/${encodeURIComponent(name)}/disabled/reset${qsCwd(cwd)}`,
{}
);
},

async getGlobalPermissionMode(input: {
sessionId: string;
cwd: string;
Expand Down
3 changes: 2 additions & 1 deletion packages/codingcode/src/contracts/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,6 @@ export interface UserHookConfig {
args?: string[];
env?: Record<string, string>;
priority?: number;
enabled: boolean;
/** 开关:false 表示禁用。缺省(undefined)等同启用 */
enabled?: boolean;
}
5 changes: 4 additions & 1 deletion packages/codingcode/src/contracts/mcp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import type { AgentError } from '../core/error.js';

export interface McpServerConfig {
name: string;
/** 开关:false 表示禁用。缺省(undefined)等同启用 */
enabled?: boolean;
/** stdio: executable command */
command?: string;
/** stdio: command arguments */
Expand All @@ -22,7 +24,6 @@ export interface McpServerConfig {
export interface McpStatus {
name: string;
connected: boolean;
disabled: boolean;
toolCount: number;
transport: 'stdio' | 'http';
reconnectAttempts: number;
Expand All @@ -35,5 +36,7 @@ export interface McpToolSpec {
name: string;
description: string;
inputSchema: Record<string, unknown>;
/** MCP 注解 readOnlyHint;缺省 false(fail-closed) */
readOnlyHint: boolean;
execute(args: Record<string, unknown>): Effect.Effect<string, AgentError>;
}
2 changes: 2 additions & 0 deletions packages/codingcode/src/contracts/tool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ export type ToolResult = { readonly id: string; readonly name: string } & ToolOu

export interface ToolRunner {
readonly name: string;
/** 是否可与同批其它工具并发执行;「未声明」已由装配处收敛,故此处必填 */
readonly concurrencySafe: boolean;
parse(args: unknown): unknown;
execute(args: unknown, ctx?: ToolExecCtx): Effect.Effect<string, AgentError>;
}
Expand Down
75 changes: 28 additions & 47 deletions packages/codingcode/src/direct/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,18 @@ import {
writeMcpConfig,
loadGlobalMcpConfig,
writeGlobalMcpConfig,
getGlobalMcpDisabledState,
setGlobalMcpDisabledState,
setProjectMcpDisabledState,
resetProjectMcpDisabledState,
setGlobalMcpServerEnabled,
setProjectMcpServerEnabled,
} from '../mcp/config.js';
import {
loadHookConfigs,
writeHookConfigs,
loadGlobalHookConfigs,
writeGlobalHookConfigs,
resolveHookConfigs,
setGlobalHookDisabledState,
setProjectHookDisabledState,
resetProjectHookDisabledState,
setGlobalHookEnabled,
setProjectHookEnabled,
} from '../hooks/config.js';
import { setHookRuntimeEnabled } from '../hooks/executor.js';
import { getMemoryConfig } from '../memory/config.js';
import { MemoryService } from '../memory/port.js';
import { AlreadyExistsError, NotFoundError } from '../contracts/error.js';
Expand Down Expand Up @@ -99,7 +95,11 @@ function hooksList(
cwd: string
): Array<UserHookConfig & { source: 'global' | 'project'; hasProjectOverride?: boolean }> {
if (isGlobalCwd(cwd)) {
return loadGlobalHookConfigs().map((h) => ({ ...h, source: 'global' as const }));
return loadGlobalHookConfigs().map((h) => ({
...h,
enabled: h.enabled !== false,
source: 'global' as const,
}));
}
const globalHooks = loadGlobalHookConfigs();
const projectHooks = loadHookConfigs(cwd);
Expand All @@ -112,6 +112,7 @@ function hooksList(
const hasProjectOverride = isFromProject && isFromGlobal;
return {
...h,
enabled: h.enabled !== false,
source: (isFromProject ? 'project' : 'global') as 'global' | 'project',
hasProjectOverride,
};
Expand Down Expand Up @@ -173,14 +174,12 @@ function hooksDelete(cwd: string, name: string): void {
);
}

function hooksSetDisabled(cwd: string, name: string, disabled: boolean): void {
setHookRuntimeEnabled(name, !disabled);
const hooks = loadHookConfigs(cwd);
const hook = hooks.find((h) => h.name === name);
if (hook) {
hook.enabled = !disabled;
writeHookConfigs(cwd, hooks);
function hooksSetEnabled(cwd: string, name: string, enabled: boolean): void {
if (isGlobalCwd(cwd)) {
setGlobalHookEnabled(name, enabled);
return;
}
setProjectHookEnabled(resolveCwd(cwd), name, enabled);
}

export function createDirectSettingsClient(rt: AppRuntime): SettingsClient {
Expand Down Expand Up @@ -236,7 +235,7 @@ export function createDirectSettingsClient(rt: AppRuntime): SettingsClient {
return loadGlobalMcpConfig().map((s) => ({
...runtimeByName.get(s.name),
name: s.name,
disabled: getGlobalMcpDisabledState(s.name),
enabled: s.enabled !== false,
source: 'global' as const,
})) as McpStatus[];
}
Expand All @@ -245,7 +244,11 @@ export function createDirectSettingsClient(rt: AppRuntime): SettingsClient {
const globalNames = new Set(globalServers.map((s) => s.name));
const seen = new Set<string>();
const result: Array<
McpStatus & { source: 'global' | 'project'; hasProjectOverride?: boolean }
McpStatus & {
enabled: boolean;
source: 'global' | 'project';
hasProjectOverride?: boolean;
}
> = [];
for (const s of projectServers) {
seen.add(s.name);
Expand All @@ -261,7 +264,7 @@ export function createDirectSettingsClient(rt: AppRuntime): SettingsClient {
toolCount: 0,
}),
name: s.name,
disabled: r?.disabled ?? false,
enabled: s.enabled !== false,
source: 'project',
hasProjectOverride: isFromGlobal,
});
Expand All @@ -279,32 +282,19 @@ export function createDirectSettingsClient(rt: AppRuntime): SettingsClient {
toolCount: 0,
}),
name: s.name,
disabled: r?.disabled ?? false,
enabled: s.enabled !== false,
source: 'global',
});
}
return result as McpStatus[];
},

async setMcpDisabled({ name, disabled, cwd }) {
const projectCwd = resolveCwd(cwd);
async setMcpEnabled({ name, enabled, cwd }) {
if (isGlobalCwd(cwd)) {
setGlobalMcpDisabledState(name, disabled);
setGlobalMcpServerEnabled(name, enabled);
} else {
setProjectMcpDisabledState(projectCwd, name, disabled);
setProjectMcpServerEnabled(resolveCwd(cwd), name, enabled);
}
await rt.runPromise(
Effect.gen(function* () {
const mcp = yield* McpService;
return yield* disabled
? mcp.disable(projectCwd, name)
: mcp.enable(projectCwd, name);
})
);
},

async resetMcpDisabled({ name, cwd }) {
resetProjectMcpDisabledState(cwd, name);
},

async createMcpServer({ cwd, server }) {
Expand Down Expand Up @@ -344,17 +334,8 @@ export function createDirectSettingsClient(rt: AppRuntime): SettingsClient {
hooksDelete(cwd, name);
},

async setHookDisabled({ cwd, name, disabled }) {
if (isGlobalCwd(cwd)) {
setGlobalHookDisabledState(name, disabled);
} else {
setProjectHookDisabledState(cwd, name, disabled);
}
hooksSetDisabled(cwd, name, disabled);
},

async resetHookDisabled({ name, cwd }) {
resetProjectHookDisabledState(cwd, name);
async setHookEnabled({ cwd, name, enabled }) {
hooksSetEnabled(cwd, name, enabled);
},

async getGlobalPermissionMode(input: {
Expand Down
Loading
Loading