-
Notifications
You must be signed in to change notification settings - Fork 8
feat(web-ui): add template editor to claude config panel #167
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
7f61020
e0da110
91618c4
58ed566
22a1d14
d3a4ab3
15dcd88
9789805
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -264,6 +264,43 @@ export function createClaudeConfigMethods(options = {}) { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| claudeLocalBridgeConfigured() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return this.claudeLocalBridgeCandidateProviders().some(p => p.hasKey); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| async applyClaudeLocalBridge() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| this.currentClaudeConfig = 'claude-local'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| try { localStorage.setItem('currentClaudeConfig', 'claude-local'); } catch (_) {} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| this.refreshClaudeModelContext(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const candidates = this.claudeLocalBridgeCandidateProviders(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (candidates.length === 0) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return this.showMessage('请先添加并配置至少一个 Claude 提供商', 'error'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const res = await api('claude-local-bridge-toggle', { enable: true }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (res.error) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| this.showMessage(res.error || '启用本地负载均衡失败', 'error'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| this.showMessage('Claude 本地负载均衡已启用', 'success'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } catch (e) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| this.showMessage('启用本地负载均衡失败', 'error'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+269
to
+288
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Switching to If validation or Proposed fix async applyClaudeLocalBridge() {
- this.currentClaudeConfig = 'claude-local';
- try { localStorage.setItem('currentClaudeConfig', 'claude-local'); } catch (_) {}
- this.refreshClaudeModelContext();
-
const candidates = this.claudeLocalBridgeCandidateProviders();
if (candidates.length === 0) {
return this.showMessage('请先添加并配置至少一个 Claude 提供商', 'error');
}
try {
const res = await api('claude-local-bridge-toggle', { enable: true });
if (res.error) {
this.showMessage(res.error || '启用本地负载均衡失败', 'error');
return;
}
+ this.currentClaudeConfig = 'claude-local';
+ try { localStorage.setItem('currentClaudeConfig', 'claude-local'); } catch (_) {}
+ this.refreshClaudeModelContext();
this.showMessage('Claude 本地负载均衡已启用', 'success');
} catch (e) {
this.showMessage('启用本地负载均衡失败', 'error');
}
},📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| async openClaudeConfigTemplateEditor() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const res = await api('get-claude-settings-raw'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (res.error) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| this.showMessage(res.error, 'error'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| this.configTemplateContent = res.content || '{}'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| this.configTemplateContext = 'claude'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| this.showConfigTemplateModal = true; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } catch (e) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| this.showMessage('加载 Claude settings 失败', 'error'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -558,6 +558,7 @@ export function createCodexConfigMethods(options = {}) { | |
| template = `${template.trimEnd()}\n\n${appendBlock}\n`; | ||
| } | ||
| this.configTemplateContent = template; | ||
| this.configTemplateContext = 'codex'; | ||
| this.showConfigTemplateModal = true; | ||
| } catch (e) { | ||
| this.showMessage('加载模板失败', 'error'); | ||
|
|
@@ -807,9 +808,16 @@ export function createCodexConfigMethods(options = {}) { | |
| const performApply = async () => { | ||
| this.configTemplateApplying = true; | ||
| try { | ||
| const res = await api('apply-config-template', { | ||
| template: this.configTemplateContent | ||
| }); | ||
| let res; | ||
| if (this.configTemplateContext === 'claude') { | ||
| res = await api('apply-claude-settings-raw', { | ||
| content: this.configTemplateContent | ||
| }); | ||
| } else { | ||
| res = await api('apply-config-template', { | ||
| template: this.configTemplateContent | ||
| }); | ||
| } | ||
|
Comment on lines
+811
to
+820
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Claude apply path is context-aware, but confirmation preview gating is not. At Line 812 you route apply correctly, but Suggested frontend-safe fix (bypass codex diff gate for Claude context) async applyConfigTemplate() {
if (this.configTemplateApplying) {
return;
}
if (!this.configTemplateContent || !this.configTemplateContent.trim()) {
this.showMessage('模板不能为空', 'error');
return;
}
+ const isClaudeTemplate = this.configTemplateContext === 'claude';
// Default to two-step confirmation when the setting is unset.
// (The normalize helper lives in session-actions; keep a safe fallback here.)
- const shouldUseTwoStepConfirm = normalizeConfigTemplateDiffConfirmEnabled(this.configTemplateDiffConfirmEnabled);
+ const shouldUseTwoStepConfirm = !isClaudeTemplate
+ && normalizeConfigTemplateDiffConfirmEnabled(this.configTemplateDiffConfirmEnabled);
const performApply = async () => {
this.configTemplateApplying = true;
try {
let res;
if (this.configTemplateContext === 'claude') {
res = await api('apply-claude-settings-raw', {
content: this.configTemplateContent
});
} else {
res = await api('apply-config-template', {
template: this.configTemplateContent
});
}🤖 Prompt for AI Agents |
||
| if (res.error) { | ||
| this.showMessage(res.error, 'error'); | ||
| return; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Local-bridge URL detection is too strict and misses valid forms.
The current check only matches
/bridge/claude-local/. URLs without trailing slash (e.g.,/bridge/claude-local) won’t match.Proposed fix
🤖 Prompt for AI Agents