generated from nhcarrigan/template
feat: implement CLI v2.1.81 features and global CLAUDE.md editor
- #248: add output_style field to System init message (forward-compat) - #245: add fast_mode_state field to Result message (forward-compat) - #246: add model_usage field to Result message with per-model logging - #247: add total_cost_usd field to Result message (authoritative cost) - #237: add bare_mode config option (passes --bare flag to Claude Code) - #239: add show_clear_context_on_plan_accept config option (settings JSON) - #244: add custom_model_option config option (ANTHROPIC_CUSTOM_MODEL_OPTION env) - #262: add global CLAUDE.md editor to config sidebar (get/save_global_claude_md commands) - fix: wire disable_cron and disable_skill_shell_execution into all start_claude invocations - fix: wire all new config fields into all start_claude invocations
This commit is contained in:
@@ -67,11 +67,16 @@ async function changeDirectory(path: string): Promise<void> {
|
||||
use_worktree: config.use_worktree ?? false,
|
||||
disable_1m_context: config.disable_1m_context ?? false,
|
||||
max_output_tokens: config.max_output_tokens ?? null,
|
||||
disable_cron: config.disable_cron ?? false,
|
||||
disable_skill_shell_execution: config.disable_skill_shell_execution ?? false,
|
||||
include_git_instructions: config.include_git_instructions ?? true,
|
||||
enable_claudeai_mcp_servers: config.enable_claudeai_mcp_servers ?? true,
|
||||
auto_memory_directory: config.auto_memory_directory || null,
|
||||
model_overrides: config.model_overrides || null,
|
||||
session_name: null,
|
||||
bare_mode: config.bare_mode ?? false,
|
||||
show_clear_context_on_plan_accept: config.show_clear_context_on_plan_accept ?? true,
|
||||
custom_model_option: config.custom_model_option || null,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -149,11 +154,16 @@ async function startNewConversation(): Promise<void> {
|
||||
use_worktree: config.use_worktree ?? false,
|
||||
disable_1m_context: config.disable_1m_context ?? false,
|
||||
max_output_tokens: config.max_output_tokens ?? null,
|
||||
disable_cron: config.disable_cron ?? false,
|
||||
disable_skill_shell_execution: config.disable_skill_shell_execution ?? false,
|
||||
include_git_instructions: config.include_git_instructions ?? true,
|
||||
enable_claudeai_mcp_servers: config.enable_claudeai_mcp_servers ?? true,
|
||||
auto_memory_directory: config.auto_memory_directory || null,
|
||||
model_overrides: config.model_overrides || null,
|
||||
session_name: null,
|
||||
bare_mode: config.bare_mode ?? false,
|
||||
show_clear_context_on_plan_accept: config.show_clear_context_on_plan_accept ?? true,
|
||||
custom_model_option: config.custom_model_option || null,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -64,6 +64,9 @@
|
||||
auto_memory_directory: null,
|
||||
model_overrides: null,
|
||||
disable_skill_shell_execution: false,
|
||||
bare_mode: false,
|
||||
show_clear_context_on_plan_accept: true,
|
||||
custom_model_option: null,
|
||||
max_output_tokens: null,
|
||||
trusted_workspaces: [],
|
||||
background_image_path: null,
|
||||
@@ -86,6 +89,9 @@
|
||||
let customUiFontStatus: string | null = $state(null);
|
||||
let modelOverridesJson = $state("");
|
||||
let modelOverridesError: string | null = $state(null);
|
||||
let globalClaudeMd = $state("");
|
||||
let globalClaudeMdSaving = $state(false);
|
||||
let globalClaudeMdSaveStatus: string | null = $state(null);
|
||||
|
||||
interface AuthStatus {
|
||||
is_logged_in: boolean;
|
||||
@@ -123,6 +129,9 @@
|
||||
if (open && authStatus === null) {
|
||||
void refreshAuthStatus();
|
||||
}
|
||||
if (open) {
|
||||
void loadGlobalClaudeMd();
|
||||
}
|
||||
});
|
||||
|
||||
configStore.saveError.subscribe((error) => {
|
||||
@@ -198,6 +207,30 @@
|
||||
}
|
||||
}
|
||||
|
||||
async function loadGlobalClaudeMd() {
|
||||
try {
|
||||
globalClaudeMd = await invoke<string>("get_global_claude_md");
|
||||
} catch (error) {
|
||||
console.error("Failed to load global CLAUDE.md:", error);
|
||||
}
|
||||
}
|
||||
|
||||
async function saveGlobalClaudeMd() {
|
||||
globalClaudeMdSaving = true;
|
||||
globalClaudeMdSaveStatus = null;
|
||||
try {
|
||||
await invoke("save_global_claude_md", { content: globalClaudeMd });
|
||||
globalClaudeMdSaveStatus = "Saved!";
|
||||
setTimeout(() => {
|
||||
globalClaudeMdSaveStatus = null;
|
||||
}, 2000);
|
||||
} catch (error) {
|
||||
globalClaudeMdSaveStatus = `Error: ${error}`;
|
||||
} finally {
|
||||
globalClaudeMdSaving = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function handleSave() {
|
||||
isSaving = true;
|
||||
saveError = null;
|
||||
@@ -679,6 +712,59 @@
|
||||
defaults.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Bare Mode -->
|
||||
<div class="mb-4">
|
||||
<label class="flex items-center gap-3 cursor-pointer">
|
||||
<input
|
||||
type="checkbox"
|
||||
bind:checked={config.bare_mode}
|
||||
class="w-4 h-4 rounded border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--accent-primary)] focus:ring-[var(--accent-primary)]"
|
||||
/>
|
||||
<span class="text-sm text-[var(--text-primary)]">Bare mode</span>
|
||||
</label>
|
||||
<p class="text-xs text-[var(--text-tertiary)] mt-1 ml-7">
|
||||
Passes <code class="font-mono">--bare</code> to suppress UI chrome — useful for scripted
|
||||
headless <code class="font-mono">-p</code> calls (requires Claude Code v2.1.81+)
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Show Clear Context on Plan Accept -->
|
||||
<div class="mb-4">
|
||||
<label class="flex items-center gap-3 cursor-pointer">
|
||||
<input
|
||||
type="checkbox"
|
||||
bind:checked={config.show_clear_context_on_plan_accept}
|
||||
class="w-4 h-4 rounded border-[var(--border-color)] bg-[var(--bg-primary)] text-[var(--accent-primary)] focus:ring-[var(--accent-primary)]"
|
||||
/>
|
||||
<span class="text-sm text-[var(--text-primary)]"
|
||||
>Show clear context prompt on plan accept</span
|
||||
>
|
||||
</label>
|
||||
<p class="text-xs text-[var(--text-tertiary)] mt-1 ml-7">
|
||||
When enabled, prompts to clear context when accepting a plan. Passes
|
||||
<code class="font-mono">showClearContextOnPlanAccept: false</code> in
|
||||
<code class="font-mono">--settings</code> when disabled (requires Claude Code v2.1.81+)
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Custom Model Option -->
|
||||
<div class="mb-4">
|
||||
<label for="custom-model-option" class="block text-sm text-[var(--text-primary)] mb-1">
|
||||
Custom model option <span class="text-[var(--text-tertiary)]">(optional)</span>
|
||||
</label>
|
||||
<input
|
||||
id="custom-model-option"
|
||||
type="text"
|
||||
placeholder="Leave blank to use default"
|
||||
bind:value={config.custom_model_option}
|
||||
class="w-full px-3 py-2 text-sm bg-[var(--bg-primary)] border border-[var(--border-color)] rounded text-[var(--text-primary)] placeholder-[var(--text-tertiary)] focus:outline-none focus:border-[var(--accent-primary)]"
|
||||
/>
|
||||
<p class="text-xs text-[var(--text-tertiary)] mt-1">
|
||||
Sets <code class="font-mono">ANTHROPIC_CUSTOM_MODEL_OPTION</code> environment variable for custom
|
||||
model providers (requires Claude Code v2.1.81+)
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Greeting Section -->
|
||||
@@ -719,6 +805,47 @@
|
||||
{/if}
|
||||
</section>
|
||||
|
||||
<!-- Global Instructions Section -->
|
||||
<section class="mb-6">
|
||||
<h3 class="text-sm font-medium text-[var(--accent-primary)] uppercase tracking-wider mb-3">
|
||||
Global Instructions
|
||||
</h3>
|
||||
<div class="mb-2">
|
||||
<label for="global-claude-md" class="block text-sm text-[var(--text-secondary)] mb-1">
|
||||
~/.claude/CLAUDE.md
|
||||
</label>
|
||||
<textarea
|
||||
id="global-claude-md"
|
||||
bind:value={globalClaudeMd}
|
||||
rows="12"
|
||||
placeholder="Add persistent instructions for all Claude Code sessions..."
|
||||
class="w-full px-3 py-2 bg-[var(--bg-primary)] border border-[var(--border-color)] rounded-lg text-[var(--text-primary)] font-mono text-sm focus:outline-none focus:border-[var(--accent-primary)] resize-y"
|
||||
></textarea>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<button
|
||||
onclick={saveGlobalClaudeMd}
|
||||
disabled={globalClaudeMdSaving}
|
||||
class="px-3 py-1.5 text-sm bg-[var(--accent-primary)] text-white rounded hover:opacity-90 disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
>
|
||||
{globalClaudeMdSaving ? "Saving..." : "Save"}
|
||||
</button>
|
||||
{#if globalClaudeMdSaveStatus}
|
||||
<span
|
||||
class="text-xs {globalClaudeMdSaveStatus.startsWith('Error')
|
||||
? 'text-red-500'
|
||||
: 'text-green-500'}"
|
||||
>
|
||||
{globalClaudeMdSaveStatus}
|
||||
</span>
|
||||
{/if}
|
||||
</div>
|
||||
<p class="text-xs text-[var(--text-tertiary)] mt-2">
|
||||
Persistent instructions applied to all Claude Code sessions. Changes take effect on the next
|
||||
session start.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<!-- MCP Servers Section -->
|
||||
<section class="mb-6">
|
||||
<h3 class="text-sm font-medium text-[var(--accent-primary)] uppercase tracking-wider mb-3">
|
||||
|
||||
@@ -68,11 +68,16 @@
|
||||
allowed_tools: grantedToolsList,
|
||||
use_worktree: config.use_worktree ?? false,
|
||||
disable_1m_context: config.disable_1m_context ?? false,
|
||||
disable_cron: config.disable_cron ?? false,
|
||||
disable_skill_shell_execution: config.disable_skill_shell_execution ?? false,
|
||||
include_git_instructions: config.include_git_instructions ?? true,
|
||||
enable_claudeai_mcp_servers: config.enable_claudeai_mcp_servers ?? true,
|
||||
auto_memory_directory: config.auto_memory_directory || null,
|
||||
model_overrides: config.model_overrides || null,
|
||||
session_name: null,
|
||||
bare_mode: config.bare_mode ?? false,
|
||||
show_clear_context_on_plan_accept: config.show_clear_context_on_plan_accept ?? true,
|
||||
custom_model_option: config.custom_model_option || null,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -402,11 +402,16 @@ User: ${formattedMessage}`;
|
||||
allowed_tools: allAllowedTools,
|
||||
use_worktree: config.use_worktree ?? false,
|
||||
disable_1m_context: config.disable_1m_context ?? false,
|
||||
disable_cron: config.disable_cron ?? false,
|
||||
disable_skill_shell_execution: config.disable_skill_shell_execution ?? false,
|
||||
include_git_instructions: config.include_git_instructions ?? true,
|
||||
enable_claudeai_mcp_servers: config.enable_claudeai_mcp_servers ?? true,
|
||||
auto_memory_directory: config.auto_memory_directory || null,
|
||||
model_overrides: config.model_overrides || null,
|
||||
session_name: null,
|
||||
bare_mode: config.bare_mode ?? false,
|
||||
show_clear_context_on_plan_accept: config.show_clear_context_on_plan_accept ?? true,
|
||||
custom_model_option: config.custom_model_option || null,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -89,11 +89,16 @@
|
||||
allowed_tools: [...new Set([...newGrantedTools, ...config.auto_granted_tools])],
|
||||
use_worktree: config.use_worktree ?? false,
|
||||
disable_1m_context: config.disable_1m_context ?? false,
|
||||
disable_cron: config.disable_cron ?? false,
|
||||
disable_skill_shell_execution: config.disable_skill_shell_execution ?? false,
|
||||
include_git_instructions: config.include_git_instructions ?? true,
|
||||
enable_claudeai_mcp_servers: config.enable_claudeai_mcp_servers ?? true,
|
||||
auto_memory_directory: config.auto_memory_directory || null,
|
||||
model_overrides: config.model_overrides || null,
|
||||
session_name: null,
|
||||
bare_mode: config.bare_mode ?? false,
|
||||
show_clear_context_on_plan_accept: config.show_clear_context_on_plan_accept ?? true,
|
||||
custom_model_option: config.custom_model_option || null,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -94,6 +94,9 @@
|
||||
auto_memory_directory: null,
|
||||
model_overrides: null,
|
||||
disable_skill_shell_execution: false,
|
||||
bare_mode: false,
|
||||
show_clear_context_on_plan_accept: true,
|
||||
custom_model_option: null,
|
||||
});
|
||||
|
||||
let streamerModeActive = $state(false);
|
||||
@@ -175,11 +178,17 @@
|
||||
use_worktree: currentConfig.use_worktree ?? false,
|
||||
disable_1m_context: currentConfig.disable_1m_context ?? false,
|
||||
max_output_tokens: currentConfig.max_output_tokens ?? null,
|
||||
disable_cron: currentConfig.disable_cron ?? false,
|
||||
disable_skill_shell_execution: currentConfig.disable_skill_shell_execution ?? false,
|
||||
include_git_instructions: currentConfig.include_git_instructions ?? true,
|
||||
enable_claudeai_mcp_servers: currentConfig.enable_claudeai_mcp_servers ?? true,
|
||||
auto_memory_directory: currentConfig.auto_memory_directory || null,
|
||||
model_overrides: currentConfig.model_overrides || null,
|
||||
session_name: activeConversationForName?.name || null,
|
||||
bare_mode: currentConfig.bare_mode ?? false,
|
||||
show_clear_context_on_plan_accept:
|
||||
currentConfig.show_clear_context_on_plan_accept ?? true,
|
||||
custom_model_option: currentConfig.custom_model_option || null,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -337,11 +346,17 @@
|
||||
use_worktree: currentConfig.use_worktree ?? false,
|
||||
disable_1m_context: currentConfig.disable_1m_context ?? false,
|
||||
max_output_tokens: currentConfig.max_output_tokens ?? null,
|
||||
disable_cron: currentConfig.disable_cron ?? false,
|
||||
disable_skill_shell_execution: currentConfig.disable_skill_shell_execution ?? false,
|
||||
include_git_instructions: currentConfig.include_git_instructions ?? true,
|
||||
enable_claudeai_mcp_servers: currentConfig.enable_claudeai_mcp_servers ?? true,
|
||||
auto_memory_directory: currentConfig.auto_memory_directory || null,
|
||||
model_overrides: currentConfig.model_overrides || null,
|
||||
session_name: null,
|
||||
bare_mode: currentConfig.bare_mode ?? false,
|
||||
show_clear_context_on_plan_accept:
|
||||
currentConfig.show_clear_context_on_plan_accept ?? true,
|
||||
custom_model_option: currentConfig.custom_model_option || null,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -218,11 +218,16 @@
|
||||
use_worktree: cfg.use_worktree ?? false,
|
||||
disable_1m_context: cfg.disable_1m_context ?? false,
|
||||
max_output_tokens: cfg.max_output_tokens ?? null,
|
||||
disable_cron: cfg.disable_cron ?? false,
|
||||
disable_skill_shell_execution: cfg.disable_skill_shell_execution ?? false,
|
||||
include_git_instructions: cfg.include_git_instructions ?? true,
|
||||
enable_claudeai_mcp_servers: cfg.enable_claudeai_mcp_servers ?? true,
|
||||
auto_memory_directory: cfg.auto_memory_directory || null,
|
||||
model_overrides: cfg.model_overrides || null,
|
||||
session_name: null,
|
||||
bare_mode: cfg.bare_mode ?? false,
|
||||
show_clear_context_on_plan_accept: cfg.show_clear_context_on_plan_accept ?? true,
|
||||
custom_model_option: cfg.custom_model_option || null,
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
|
||||
@@ -108,11 +108,16 @@
|
||||
allowed_tools: grantedToolsList,
|
||||
use_worktree: config.use_worktree ?? false,
|
||||
disable_1m_context: config.disable_1m_context ?? false,
|
||||
disable_cron: config.disable_cron ?? false,
|
||||
disable_skill_shell_execution: config.disable_skill_shell_execution ?? false,
|
||||
include_git_instructions: config.include_git_instructions ?? true,
|
||||
enable_claudeai_mcp_servers: config.enable_claudeai_mcp_servers ?? true,
|
||||
auto_memory_directory: config.auto_memory_directory || null,
|
||||
model_overrides: config.model_overrides || null,
|
||||
session_name: null,
|
||||
bare_mode: config.bare_mode ?? false,
|
||||
show_clear_context_on_plan_accept: config.show_clear_context_on_plan_accept ?? true,
|
||||
custom_model_option: config.custom_model_option || null,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -226,6 +226,9 @@ describe("config store", () => {
|
||||
auto_memory_directory: null,
|
||||
model_overrides: null,
|
||||
disable_skill_shell_execution: false,
|
||||
bare_mode: false,
|
||||
show_clear_context_on_plan_accept: true,
|
||||
custom_model_option: null,
|
||||
};
|
||||
|
||||
expect(config.model).toBe("claude-sonnet-4");
|
||||
@@ -291,6 +294,9 @@ describe("config store", () => {
|
||||
auto_memory_directory: null,
|
||||
model_overrides: null,
|
||||
disable_skill_shell_execution: false,
|
||||
bare_mode: false,
|
||||
show_clear_context_on_plan_accept: true,
|
||||
custom_model_option: null,
|
||||
};
|
||||
|
||||
expect(config.model).toBeNull();
|
||||
@@ -911,6 +917,9 @@ describe("config store", () => {
|
||||
auto_memory_directory: null,
|
||||
model_overrides: null,
|
||||
disable_skill_shell_execution: false,
|
||||
bare_mode: false,
|
||||
show_clear_context_on_plan_accept: true,
|
||||
custom_model_option: null,
|
||||
};
|
||||
|
||||
const mockInvokeImpl = vi.mocked(invoke);
|
||||
|
||||
@@ -93,6 +93,12 @@ export interface HikariConfig {
|
||||
model_overrides: Record<string, string> | null;
|
||||
// Prevents skill scripts from executing shell commands (Claude Code v2.1.91+)
|
||||
disable_skill_shell_execution: boolean;
|
||||
// Bare mode — suppress UI chrome for scripted headless -p calls (v2.1.81+)
|
||||
bare_mode: boolean;
|
||||
// Show clear context dialog when accepting a plan (v2.1.81+)
|
||||
show_clear_context_on_plan_accept: boolean;
|
||||
// Custom model option env var (v2.1.81+)
|
||||
custom_model_option: string | null;
|
||||
}
|
||||
|
||||
const defaultConfig: HikariConfig = {
|
||||
@@ -152,6 +158,9 @@ const defaultConfig: HikariConfig = {
|
||||
auto_memory_directory: null,
|
||||
model_overrides: null,
|
||||
disable_skill_shell_execution: false,
|
||||
bare_mode: false,
|
||||
show_clear_context_on_plan_accept: true,
|
||||
custom_model_option: null,
|
||||
};
|
||||
|
||||
function createConfigStore() {
|
||||
|
||||
Reference in New Issue
Block a user