feat: 适配 kimi-code 0.40.1 —— flag 清单/优先级语义/危险命令守卫

- flag 清单 9→10:新增 file_history、search_worker;secondary-model
  0.40.1 起默认开启(defaultEnabled)
- env 探测补齐为 12 项元组(10 flag + master + legacy),修正此前
  tower/subagent_fork/wait_for/auto_session_title 四项漏探
- 优先级语义跟随上游 flagService:单 flag env > [experimental] 显式值
  > master env(仅强制开)> 默认。master env 不再锁定 UI;setExperimentalFlag
  增加 explicitFalse 路径,关闭默认开/master 强开的 flag 时写字面 false
- 权限设置新增 dangerous_command_guard 开关(默认开,写 [permission]
  蛇形键;env KIMI_CODE_DANGEROUS_COMMAND_GUARD 运行时覆盖 config)
- 新增 11 个测试(注册表/写语义/守卫读写)
This commit is contained in:
KimiSwitch Dev committed 2026-09-03 10:10:52 +08:00
1 parent 6a7c8f5393
commit 86a128efea
10 files changed
+339 -47

No files matched your search

+72
View File
@@ -131,4 +131,76 @@ describe("loop_control — v1/v2 key handling", () => {
expect(s.loop_control?.max_attempts_per_step).toBe(4);
expect(s.loop_control?.max_retries_per_step).toBe(4);
});
});
// ---------------------------------------------------------------------------
// [permission] dangerous_command_guard (kimi-code 0.40.1) — absent key means
// upstream default ON; an explicit false must survive even with no rules
// ---------------------------------------------------------------------------
describe("permission.dangerous_command_guard", () => {
it("reads as undefined when the key is absent (default on)", () => {
expect(
getAgentSettings({}).permission?.dangerous_command_guard
).toBeUndefined();
expect(
getAgentSettings({ permission: { rules: [] } }).permission
?.dangerous_command_guard
).toBeUndefined();
});
it("reads an explicit true / false", () => {
expect(
getAgentSettings({ permission: { dangerous_command_guard: false } })
.permission?.dangerous_command_guard
).toBe(false);
expect(
getAgentSettings({ permission: { dangerous_command_guard: true } })
.permission?.dangerous_command_guard
).toBe(true);
});
it("writes guard=false even with no rules (section kept)", () => {
const next = setAgentSettings(
{},
{ permission: { rules: [], dangerous_command_guard: false } }
) as { permission?: Record<string, unknown> };
expect(next.permission).toEqual({ dangerous_command_guard: false });
});
it("writes guard together with rules", () => {
const rules = [{ decision: "allow" as const, pattern: "Read" }];
const next = setAgentSettings(
{},
{ permission: { rules, dangerous_command_guard: true } }
) as { permission?: Record<string, unknown> };
expect(next.permission).toEqual({
rules,
dangerous_command_guard: true,
});
});
it("a rules-only update carries the existing guard through", () => {
const raw = { permission: { dangerous_command_guard: false } };
const next = setAgentSettings(raw, {
permission: { rules: [{ decision: "deny" as const, pattern: "Bash" }] },
}) as { permission?: Record<string, unknown> };
expect(next.permission?.dangerous_command_guard).toBe(false);
expect(next.permission?.rules).toHaveLength(1);
});
it("omits an empty rules array; keeps an explicit guard on plain saves", () => {
const raw = { permission: { dangerous_command_guard: true } };
const off = setAgentSettings(raw, {
permission: { rules: [], dangerous_command_guard: false },
}) as { permission?: Record<string, unknown> };
expect(off.permission).toEqual({ dangerous_command_guard: false });
expect(off.permission).not.toHaveProperty("rules");
// An explicit true is materialized on plain saves (harmless, and it
// documents the state the UI toggle shows).
const on = setAgentSettings(raw, {}) as {
permission?: Record<string, unknown>;
};
expect(on.permission).toEqual({ dangerous_command_guard: true });
});
});