codexmate 0.0.47 → 0.0.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/README.zh.md +2 -0
- package/cli/agents-files.js +97 -28
- package/cli.js +59 -3
- package/package.json +1 -1
- package/web-ui/app.js +28 -1
- package/web-ui/logic.agents-diff.mjs +6 -0
- package/web-ui/modules/app.methods.agents.mjs +82 -16
- package/web-ui/modules/app.methods.codex-config.mjs +7 -3
- package/web-ui/modules/app.methods.startup-claude.mjs +3 -3
- package/web-ui/modules/i18n/locales/en.mjs +17 -6
- package/web-ui/modules/i18n/locales/ja.mjs +17 -6
- package/web-ui/modules/i18n/locales/vi.mjs +16 -2
- package/web-ui/modules/i18n/locales/zh-tw.mjs +17 -6
- package/web-ui/modules/i18n/locales/zh.mjs +17 -6
- package/web-ui/partials/index/layout-header.html +5 -5
- package/web-ui/partials/index/modal-config-template-agents.html +3 -3
- package/web-ui/partials/index/panel-prompts.html +24 -2
- package/web-ui/res/web-ui-render.precompiled.js +48 -12
- package/web-ui/styles/modals-core.css +33 -0
- package/web-ui/styles/titles-cards.css +2 -2
package/README.md
CHANGED
|
@@ -58,6 +58,7 @@ Unlike simple wrappers, Codex Mate acts as a **Local Agent Bridge**:
|
|
|
58
58
|
- **Claude Provider Bridge**: Connect Claude Code to OpenAI Chat Completions-compatible providers and Ollama through the built-in local Claude-compatible proxy.
|
|
59
59
|
- **OpenCode Provider Control**: Manage OpenCode provider/model selection with a CodexMate-owned provider store under `~/.codexmate`, projecting only the active provider into native OpenCode config to avoid polluting or deleting user-owned settings.
|
|
60
60
|
- **Skills Marketplace**: A local-first market to share and import skills between different agent apps.
|
|
61
|
+
- **Prompt File Editor**: Unified editor for global and project-level `CLAUDE.md` and `AGENTS.md` with auto-detection of project paths.
|
|
61
62
|
- **Task Orchestrator**: Plan and execute complex tasks with dependency tracking.
|
|
62
63
|
|
|
63
64
|
---
|
|
@@ -76,6 +77,7 @@ Unlike simple wrappers, Codex Mate acts as a **Local Agent Bridge**:
|
|
|
76
77
|
| **Claude Provider Bridge** | ✅ | Connect Claude Code to OpenAI Chat Completions-compatible providers and Ollama via the built-in Claude-compatible proxy |
|
|
77
78
|
| **OpenCode Provider Store** | ✅ | Keep multiple OpenCode providers in `~/.codexmate` while projecting only the selected provider to native OpenCode config |
|
|
78
79
|
| **Prompt Templates** | ✅ | Reusable prompt plugins with variables |
|
|
80
|
+
| **Prompt File Editor** | ✅ | Edit global and project-level CLAUDE.md / AGENTS.md with auto-detect and path switching |
|
|
79
81
|
| **MCP Integration** | ✅ | Expose local tools and resources via MCP stdio |
|
|
80
82
|
| **Auto Update** | ✅ | Quick update CLI via `codexmate update` |
|
|
81
83
|
|
package/README.zh.md
CHANGED
|
@@ -58,6 +58,7 @@
|
|
|
58
58
|
- **Claude Provider 桥接**:通过内建本地 Claude 兼容代理,让 Claude Code 接入 OpenAI Chat Completions 兼容 provider 与 Ollama。
|
|
59
59
|
- **OpenCode Provider 控制**:在 `~/.codexmate` 下维护 CodexMate 自有的 OpenCode 多 provider 存储,只将当前选中的 provider 投影到 OpenCode 原生配置,避免污染或误删用户已有配置。
|
|
60
60
|
- **Skills 市场**:本地优先的市场,支持在不同的智能体应用之间共享和导入 Skills。
|
|
61
|
+
- **提示词文件编辑器**:统一编辑全局和项目级 `CLAUDE.md` 与 `AGENTS.md`,支持项目路径自动检测。
|
|
61
62
|
- **任务编排器**:支持带有依赖跟踪的复杂任务规划与执行。
|
|
62
63
|
|
|
63
64
|
---
|
|
@@ -76,6 +77,7 @@
|
|
|
76
77
|
| **Claude Provider 桥接** | ✅ | 通过内建 Claude 兼容代理,让 Claude Code 接入 OpenAI Chat Completions 兼容 provider 与 Ollama |
|
|
77
78
|
| **OpenCode Provider 存储** | ✅ | 在 `~/.codexmate` 中保留多个 OpenCode provider,只将当前选中的 provider 投影到 OpenCode 原生配置 |
|
|
78
79
|
| **提示词模板** | ✅ | 支持变量的可复用提示词插件 |
|
|
80
|
+
| **提示词文件编辑器** | ✅ | 编辑全局和项目级 CLAUDE.md / AGENTS.md,支持自动检测与路径切换 |
|
|
79
81
|
| **MCP 集成** | ✅ | 通过 MCP stdio 暴露本地工具与资源 |
|
|
80
82
|
| **自动更新** | ✅ | 通过 `codexmate update` 快速更新 CLI |
|
|
81
83
|
|
package/cli/agents-files.js
CHANGED
|
@@ -53,57 +53,119 @@ function createAgentsFileController(deps = {}) {
|
|
|
53
53
|
return { ok: true, dirPath };
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
function
|
|
57
|
-
|
|
56
|
+
function detectProjectClaudeMdDir(baseDir) {
|
|
57
|
+
if (typeof baseDir !== 'string' || !baseDir.trim()) {
|
|
58
|
+
return { error: 'project path is required' };
|
|
59
|
+
}
|
|
60
|
+
const root = baseDir.trim();
|
|
61
|
+
const rootPath = path.join(root, CLAUDE_MD_FILE_NAME);
|
|
62
|
+
const dotDirPath = path.join(root, '.claude', CLAUDE_MD_FILE_NAME);
|
|
63
|
+
try {
|
|
64
|
+
if (fs.statSync(rootPath).isFile()) {
|
|
65
|
+
return { path: rootPath, source: 'root', dir: root };
|
|
66
|
+
}
|
|
67
|
+
} catch (_) {}
|
|
68
|
+
try {
|
|
69
|
+
if (fs.statSync(dotDirPath).isFile()) {
|
|
70
|
+
return { path: dotDirPath, source: 'dotdir', dir: path.join(root, '.claude') };
|
|
71
|
+
}
|
|
72
|
+
} catch (_) {}
|
|
73
|
+
return { path: rootPath, source: 'root', dir: root };
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function validateClaudeMdBaseDir(filePath) {
|
|
77
|
+
const dirPath = path.dirname(filePath);
|
|
78
|
+
try {
|
|
79
|
+
const stat = fs.statSync(dirPath);
|
|
80
|
+
if (!stat.isDirectory()) {
|
|
81
|
+
return { error: 'project directory is not a directory: ' + dirPath };
|
|
82
|
+
}
|
|
83
|
+
} catch (e) {
|
|
84
|
+
return { error: 'project directory does not exist: ' + dirPath };
|
|
85
|
+
}
|
|
86
|
+
return { ok: true, dirPath };
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function resolveClaudeMdFilePath(params = {}) {
|
|
90
|
+
const baseDir = typeof params.baseDir === 'string' && params.baseDir.trim()
|
|
91
|
+
? params.baseDir.trim()
|
|
92
|
+
: '';
|
|
93
|
+
if (!baseDir) {
|
|
94
|
+
return { filePath: path.join(CLAUDE_DIR, CLAUDE_MD_FILE_NAME), isProject: false };
|
|
95
|
+
}
|
|
96
|
+
var detected = detectProjectClaudeMdDir(baseDir);
|
|
97
|
+
if (detected.error) {
|
|
98
|
+
return { filePath: path.join(CLAUDE_DIR, CLAUDE_MD_FILE_NAME), isProject: false, detectionError: detected.error };
|
|
99
|
+
}
|
|
100
|
+
return { filePath: detected.path, isProject: true, detectionSource: detected.source, projectPath: baseDir };
|
|
58
101
|
}
|
|
59
102
|
|
|
60
103
|
function readClaudeMdFile(params = {}) {
|
|
61
|
-
|
|
62
|
-
|
|
104
|
+
var resolved = resolveClaudeMdFilePath(params);
|
|
105
|
+
var filePath = resolved.filePath;
|
|
106
|
+
var lineEndingFallback = os.EOL === '\r\n' ? '\r\n' : '\n';
|
|
107
|
+
var base = {
|
|
108
|
+
path: filePath,
|
|
109
|
+
lineEnding: lineEndingFallback
|
|
110
|
+
};
|
|
111
|
+
if (resolved.isProject) {
|
|
112
|
+
base.detectionSource = resolved.detectionSource;
|
|
113
|
+
base.projectPath = resolved.projectPath;
|
|
114
|
+
}
|
|
115
|
+
if (resolved.detectionError) {
|
|
116
|
+
base.detectionError = resolved.detectionError;
|
|
117
|
+
}
|
|
118
|
+
if (resolved.isProject) {
|
|
119
|
+
var dirCheck = validateClaudeMdBaseDir(filePath);
|
|
120
|
+
if (dirCheck.error) {
|
|
121
|
+
return { error: dirCheck.error };
|
|
122
|
+
}
|
|
123
|
+
}
|
|
63
124
|
if (!fs.existsSync(filePath)) {
|
|
64
|
-
return {
|
|
65
|
-
exists: false,
|
|
66
|
-
path: filePath,
|
|
67
|
-
content: '',
|
|
68
|
-
lineEnding: lineEndingFallback
|
|
69
|
-
};
|
|
125
|
+
return Object.assign({ exists: false, content: '' }, base);
|
|
70
126
|
}
|
|
71
127
|
if (params.metaOnly) {
|
|
72
|
-
return {
|
|
73
|
-
exists: true,
|
|
74
|
-
path: filePath,
|
|
75
|
-
content: '',
|
|
76
|
-
lineEnding: lineEndingFallback
|
|
77
|
-
};
|
|
128
|
+
return Object.assign({ exists: true, content: '' }, base);
|
|
78
129
|
}
|
|
79
130
|
try {
|
|
80
|
-
|
|
81
|
-
|
|
131
|
+
var raw = fs.readFileSync(filePath, 'utf-8');
|
|
132
|
+
var result = {
|
|
82
133
|
exists: true,
|
|
83
134
|
path: filePath,
|
|
84
135
|
content: stripUtf8Bom(raw),
|
|
85
136
|
lineEnding: detectLineEnding(raw)
|
|
86
137
|
};
|
|
138
|
+
if (resolved.isProject) {
|
|
139
|
+
result.detectionSource = resolved.detectionSource;
|
|
140
|
+
result.projectPath = resolved.projectPath;
|
|
141
|
+
}
|
|
142
|
+
return result;
|
|
87
143
|
} catch (e) {
|
|
88
|
-
return { error:
|
|
144
|
+
return { error: 'read CLAUDE.md failed: ' + e.message };
|
|
89
145
|
}
|
|
90
146
|
}
|
|
91
147
|
|
|
92
148
|
function applyClaudeMdFile(params = {}) {
|
|
93
|
-
|
|
94
|
-
|
|
149
|
+
var resolved = resolveClaudeMdFilePath(params);
|
|
150
|
+
var filePath = resolved.filePath;
|
|
151
|
+
var content = typeof params.content === 'string' ? params.content : '';
|
|
95
152
|
if (content.length > 2 * 1024 * 1024) {
|
|
96
|
-
return { error: '
|
|
153
|
+
return { error: 'content too large (max 2MB)' };
|
|
97
154
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
155
|
+
var lineEnding = params.lineEnding === '\r\n' ? '\r\n' : '\n';
|
|
156
|
+
var normalized = normalizeLineEnding(content, lineEnding);
|
|
157
|
+
var finalContent = ensureUtf8Bom(normalized);
|
|
101
158
|
try {
|
|
102
|
-
ensureDir(
|
|
159
|
+
ensureDir(path.dirname(filePath));
|
|
103
160
|
fs.writeFileSync(filePath, finalContent, 'utf-8');
|
|
104
|
-
|
|
161
|
+
var result = { success: true, path: filePath };
|
|
162
|
+
if (resolved.isProject) {
|
|
163
|
+
result.projectPath = resolved.projectPath;
|
|
164
|
+
result.detectionSource = resolved.detectionSource;
|
|
165
|
+
}
|
|
166
|
+
return result;
|
|
105
167
|
} catch (e) {
|
|
106
|
-
return { error:
|
|
168
|
+
return { error: 'write CLAUDE.md failed: ' + e.message };
|
|
107
169
|
}
|
|
108
170
|
}
|
|
109
171
|
|
|
@@ -181,6 +243,11 @@ function createAgentsFileController(deps = {}) {
|
|
|
181
243
|
let readResult;
|
|
182
244
|
if (context === 'claude-md') {
|
|
183
245
|
readResult = readClaudeMdFile({ metaOnly });
|
|
246
|
+
} else if (context === 'claude-project') {
|
|
247
|
+
if (!params.baseDir || !String(params.baseDir).trim()) {
|
|
248
|
+
return { error: 'project path is required for claude-project context' };
|
|
249
|
+
}
|
|
250
|
+
readResult = readClaudeMdFile({ ...params, metaOnly });
|
|
184
251
|
} else if (context === 'openclaw') {
|
|
185
252
|
readResult = readOpenclawAgentsFile({ metaOnly });
|
|
186
253
|
} else if (context === 'openclaw-workspace') {
|
|
@@ -215,6 +282,8 @@ function createAgentsFileController(deps = {}) {
|
|
|
215
282
|
return {
|
|
216
283
|
resolveAgentsFilePath,
|
|
217
284
|
validateAgentsBaseDir,
|
|
285
|
+
detectProjectClaudeMdDir,
|
|
286
|
+
validateClaudeMdBaseDir,
|
|
218
287
|
resolveClaudeMdFilePath,
|
|
219
288
|
readClaudeMdFile,
|
|
220
289
|
applyClaudeMdFile,
|
package/cli.js
CHANGED
|
@@ -1828,6 +1828,8 @@ async function fetchProviderModels(providerName, overrides = {}) {
|
|
|
1828
1828
|
const {
|
|
1829
1829
|
resolveAgentsFilePath,
|
|
1830
1830
|
validateAgentsBaseDir,
|
|
1831
|
+
detectProjectClaudeMdDir,
|
|
1832
|
+
validateClaudeMdBaseDir,
|
|
1831
1833
|
resolveClaudeMdFilePath,
|
|
1832
1834
|
readClaudeMdFile,
|
|
1833
1835
|
applyClaudeMdFile,
|
|
@@ -2319,6 +2321,42 @@ function buildConfigTemplateDiff(params = {}) {
|
|
|
2319
2321
|
};
|
|
2320
2322
|
}
|
|
2321
2323
|
|
|
2324
|
+
function buildClaudeSettingsDiff(params = {}) {
|
|
2325
|
+
const content = typeof params.content === 'string' ? params.content : '';
|
|
2326
|
+
if (!content.trim()) {
|
|
2327
|
+
return { error: 'JSON 内容不能为空' };
|
|
2328
|
+
}
|
|
2329
|
+
if (content.length > 1024 * 1024) {
|
|
2330
|
+
return { error: '内容过大(最大 1MB)' };
|
|
2331
|
+
}
|
|
2332
|
+
let parsed;
|
|
2333
|
+
try {
|
|
2334
|
+
parsed = JSON.parse(content);
|
|
2335
|
+
} catch (e) {
|
|
2336
|
+
return { error: `JSON 解析失败: ${e.message}` };
|
|
2337
|
+
}
|
|
2338
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
2339
|
+
return { error: 'JSON 内容必须是一个对象' };
|
|
2340
|
+
}
|
|
2341
|
+
let beforeText = '';
|
|
2342
|
+
if (fs.existsSync(CLAUDE_SETTINGS_FILE)) {
|
|
2343
|
+
try {
|
|
2344
|
+
beforeText = fs.readFileSync(CLAUDE_SETTINGS_FILE, 'utf-8');
|
|
2345
|
+
} catch (e) {
|
|
2346
|
+
return { error: `读取 settings.json 失败: ${e.message}` };
|
|
2347
|
+
}
|
|
2348
|
+
}
|
|
2349
|
+
const afterText = JSON.stringify(parsed, null, 2) + '\n';
|
|
2350
|
+
const diff = buildLineDiff(beforeText, afterText);
|
|
2351
|
+
const hasChanges = (diff.stats.added || 0) + (diff.stats.removed || 0) > 0;
|
|
2352
|
+
return {
|
|
2353
|
+
diff: {
|
|
2354
|
+
...diff,
|
|
2355
|
+
hasChanges
|
|
2356
|
+
}
|
|
2357
|
+
};
|
|
2358
|
+
}
|
|
2359
|
+
|
|
2322
2360
|
function addProviderToConfig(params = {}) {
|
|
2323
2361
|
const name = typeof params.name === 'string' ? params.name.trim() : '';
|
|
2324
2362
|
const url = typeof params.url === 'string' ? params.url.trim() : '';
|
|
@@ -9528,6 +9566,12 @@ async function applyToClaudeSettings(config = {}) {
|
|
|
9528
9566
|
};
|
|
9529
9567
|
delete nextEnv.ANTHROPIC_AUTH_TOKEN;
|
|
9530
9568
|
delete nextEnv.CLAUDE_CODE_USE_KEY;
|
|
9569
|
+
const subModels = {
|
|
9570
|
+
ANTHROPIC_DEFAULT_HAIKU_MODEL: model,
|
|
9571
|
+
ANTHROPIC_DEFAULT_SONNET_MODEL: model,
|
|
9572
|
+
ANTHROPIC_DEFAULT_OPUS_MODEL: model
|
|
9573
|
+
};
|
|
9574
|
+
Object.assign(nextEnv, subModels);
|
|
9531
9575
|
|
|
9532
9576
|
const nextSettings = {
|
|
9533
9577
|
...currentSettings,
|
|
@@ -9546,7 +9590,10 @@ async function applyToClaudeSettings(config = {}) {
|
|
|
9546
9590
|
updatedKeys: [
|
|
9547
9591
|
'env.ANTHROPIC_API_KEY',
|
|
9548
9592
|
'env.ANTHROPIC_BASE_URL',
|
|
9549
|
-
'env.ANTHROPIC_MODEL'
|
|
9593
|
+
'env.ANTHROPIC_MODEL',
|
|
9594
|
+
'env.ANTHROPIC_DEFAULT_HAIKU_MODEL',
|
|
9595
|
+
'env.ANTHROPIC_DEFAULT_SONNET_MODEL',
|
|
9596
|
+
'env.ANTHROPIC_DEFAULT_OPUS_MODEL'
|
|
9550
9597
|
]
|
|
9551
9598
|
};
|
|
9552
9599
|
if (proxyResult) {
|
|
@@ -11831,10 +11878,16 @@ function createWebServer({ htmlPath, assetsDir, webDir, host, port, openBrowser
|
|
|
11831
11878
|
case 'apply-claude-md-file':
|
|
11832
11879
|
result = applyClaudeMdFile(params || {});
|
|
11833
11880
|
if (result && !result.error) {
|
|
11834
|
-
const
|
|
11835
|
-
|
|
11881
|
+
const mdBaseDir = params && params.baseDir ? String(params.baseDir).trim() : '';
|
|
11882
|
+
const mdTarget = mdBaseDir
|
|
11883
|
+
? path.join(mdBaseDir, 'CLAUDE.md')
|
|
11884
|
+
: ((params && params.targetPath) ? String(params.targetPath) : 'CLAUDE.md');
|
|
11885
|
+
notifyWebhook('claude-md-edit', 'CLAUDE.md modified: ' + mdTarget, { targetPath: mdTarget, projectPath: mdBaseDir }).catch(function () { });
|
|
11836
11886
|
}
|
|
11837
11887
|
break;
|
|
11888
|
+
case 'detect-project-claude-md':
|
|
11889
|
+
result = detectProjectClaudeMdDir((params && params.baseDir) || '');
|
|
11890
|
+
break;
|
|
11838
11891
|
case 'preview-agents-diff':
|
|
11839
11892
|
result = buildAgentsDiff(params || {});
|
|
11840
11893
|
break;
|
|
@@ -11910,6 +11963,9 @@ function createWebServer({ htmlPath, assetsDir, webDir, host, port, openBrowser
|
|
|
11910
11963
|
case 'get-claude-settings-raw':
|
|
11911
11964
|
result = readClaudeSettingsRaw();
|
|
11912
11965
|
break;
|
|
11966
|
+
case 'preview-claude-settings-diff':
|
|
11967
|
+
result = buildClaudeSettingsDiff(params || {});
|
|
11968
|
+
break;
|
|
11913
11969
|
case 'apply-claude-settings-raw':
|
|
11914
11970
|
result = applyClaudeSettingsRaw(params || {});
|
|
11915
11971
|
break;
|
package/package.json
CHANGED
package/web-ui/app.js
CHANGED
|
@@ -74,6 +74,9 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
74
74
|
showConfigTemplateModal: false,
|
|
75
75
|
showAgentsModal: false,
|
|
76
76
|
promptsSubTab: 'codex',
|
|
77
|
+
projectClaudeMdPath: '',
|
|
78
|
+
projectPathOptions: [],
|
|
79
|
+
projectPathOptionsLoading: false,
|
|
77
80
|
showSkillsModal: false,
|
|
78
81
|
showHealthCheckModal: false,
|
|
79
82
|
showCodexBridgePoolModal: false,
|
|
@@ -574,6 +577,18 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
574
577
|
this.sessionTrashEnabled = this.normalizeSessionTrashEnabled(localStorage.getItem('codexmateSessionTrashEnabled'));
|
|
575
578
|
this.sessionTrashRetentionDays = this.normalizeSessionTrashRetentionDays(localStorage.getItem('codexmateSessionTrashRetentionDays'));
|
|
576
579
|
this.configTemplateDiffConfirmEnabled = loadConfigTemplateDiffConfirmEnabledFromStorage(localStorage);
|
|
580
|
+
try {
|
|
581
|
+
var savedProjectPath = localStorage.getItem('codexmate_project_claude_md_path');
|
|
582
|
+
if (savedProjectPath) {
|
|
583
|
+
this.projectClaudeMdPath = savedProjectPath;
|
|
584
|
+
}
|
|
585
|
+
} catch (_) {}
|
|
586
|
+
try {
|
|
587
|
+
var savedSubTab = localStorage.getItem('codexmate_prompts_sub_tab');
|
|
588
|
+
if (savedSubTab === 'codex' || savedSubTab === 'claude-project') {
|
|
589
|
+
this.promptsSubTab = savedSubTab;
|
|
590
|
+
}
|
|
591
|
+
} catch (_) {}
|
|
577
592
|
window.addEventListener('resize', this.onWindowResize);
|
|
578
593
|
window.addEventListener('keydown', this.handleGlobalKeydown);
|
|
579
594
|
window.addEventListener('beforeunload', this.handleBeforeUnload);
|
|
@@ -740,10 +755,22 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
740
755
|
this.loadPromptsContent();
|
|
741
756
|
}
|
|
742
757
|
},
|
|
743
|
-
promptsSubTab() {
|
|
758
|
+
promptsSubTab(newVal) {
|
|
759
|
+
try {
|
|
760
|
+
localStorage.setItem('codexmate_prompts_sub_tab', newVal);
|
|
761
|
+
} catch (_) {}
|
|
744
762
|
if (this.mainTab === 'prompts' && typeof this.loadPromptsContent === 'function') {
|
|
745
763
|
this.loadPromptsContent();
|
|
746
764
|
}
|
|
765
|
+
},
|
|
766
|
+
projectClaudeMdPath(newPath) {
|
|
767
|
+
try {
|
|
768
|
+
if (newPath) {
|
|
769
|
+
localStorage.setItem('codexmate_project_claude_md_path', newPath);
|
|
770
|
+
} else {
|
|
771
|
+
localStorage.removeItem('codexmate_project_claude_md_path');
|
|
772
|
+
}
|
|
773
|
+
} catch (_) {}
|
|
747
774
|
}
|
|
748
775
|
},
|
|
749
776
|
|
|
@@ -336,6 +336,12 @@ export function buildAgentsDiffPreviewRequest(options = {}) {
|
|
|
336
336
|
params.fileName = fileName;
|
|
337
337
|
}
|
|
338
338
|
}
|
|
339
|
+
if (context === 'claude-project') {
|
|
340
|
+
const baseDir = typeof options.baseDir === 'string' ? options.baseDir.trim() : '';
|
|
341
|
+
if (baseDir) {
|
|
342
|
+
params.baseDir = baseDir;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
339
345
|
|
|
340
346
|
const maxRequestBytes = Number.isFinite(options.maxRequestBytes)
|
|
341
347
|
? Math.max(1024, Math.floor(options.maxRequestBytes))
|
|
@@ -37,11 +37,16 @@ export function createAgentsMethods(options = {}) {
|
|
|
37
37
|
|
|
38
38
|
return {
|
|
39
39
|
async openClaudeMdEditor() {
|
|
40
|
-
this.setAgentsModalContext('claude-
|
|
40
|
+
this.setAgentsModalContext('claude-project');
|
|
41
41
|
const requestToken = issueLatestRequestToken(this, '_agentsOpenRequestToken');
|
|
42
42
|
this.agentsLoading = true;
|
|
43
43
|
try {
|
|
44
|
-
const
|
|
44
|
+
const rpcParams = {};
|
|
45
|
+
var projectPath = (this.projectClaudeMdPath || '').trim();
|
|
46
|
+
if (projectPath) {
|
|
47
|
+
rpcParams.baseDir = projectPath;
|
|
48
|
+
}
|
|
49
|
+
const res = await api('get-claude-md-file', rpcParams);
|
|
45
50
|
if (!isLatestRequestToken(this, '_agentsOpenRequestToken', requestToken)) {
|
|
46
51
|
return;
|
|
47
52
|
}
|
|
@@ -182,11 +187,18 @@ export function createAgentsMethods(options = {}) {
|
|
|
182
187
|
setAgentsModalContext(context, options = {}) {
|
|
183
188
|
const t = typeof this.t === 'function' ? this.t : null;
|
|
184
189
|
const tr = (key, fallback, params = null) => (t ? t(key, params) : fallback);
|
|
185
|
-
if (context === 'claude-
|
|
186
|
-
this.
|
|
190
|
+
if (context === 'claude-project') {
|
|
191
|
+
var projectPath = (options.projectPath || this.projectClaudeMdPath || '').trim();
|
|
192
|
+
this.agentsContext = 'claude-project';
|
|
187
193
|
this.agentsWorkspaceFileName = '';
|
|
188
|
-
this.
|
|
189
|
-
|
|
194
|
+
this.projectClaudeMdPath = projectPath;
|
|
195
|
+
if (projectPath) {
|
|
196
|
+
this.agentsModalTitle = tr('modal.agents.title.claudeProject', 'Project CLAUDE.md: ' + projectPath, { path: projectPath });
|
|
197
|
+
this.agentsModalHint = tr('modal.agents.hint.claudeProject', 'Saved content will be written to CLAUDE.md in: ' + projectPath, { path: projectPath });
|
|
198
|
+
} else {
|
|
199
|
+
this.agentsModalTitle = tr('modal.agents.title.claudeProjectGlobal', 'Global CLAUDE.md');
|
|
200
|
+
this.agentsModalHint = tr('modal.agents.hint.claudeProjectGlobal', 'Saved content will be written to ~/.claude/CLAUDE.md.');
|
|
201
|
+
}
|
|
190
202
|
return;
|
|
191
203
|
}
|
|
192
204
|
if (context === 'openclaw-workspace') {
|
|
@@ -420,6 +432,41 @@ export function createAgentsMethods(options = {}) {
|
|
|
420
432
|
this.resetAgentsDiffState();
|
|
421
433
|
}
|
|
422
434
|
},
|
|
435
|
+
selectProjectClaudeMdPath(pathValue) {
|
|
436
|
+
this.projectClaudeMdPath = (pathValue || '').trim();
|
|
437
|
+
if (this.promptsSubTab === 'claude-project' && this.mainTab === 'prompts') {
|
|
438
|
+
this.loadPromptsContent();
|
|
439
|
+
}
|
|
440
|
+
},
|
|
441
|
+
setProjectClaudeMdPathManual(pathValue) {
|
|
442
|
+
var trimmed = (pathValue || '').trim();
|
|
443
|
+
if (trimmed === (this.projectClaudeMdPath || '').trim()) {
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
446
|
+
this.projectClaudeMdPath = trimmed;
|
|
447
|
+
if (this.promptsSubTab === 'claude-project' && this.mainTab === 'prompts') {
|
|
448
|
+
this.loadPromptsContent();
|
|
449
|
+
}
|
|
450
|
+
},
|
|
451
|
+
async loadProjectPathOptions() {
|
|
452
|
+
if (this.projectPathOptionsLoading) {
|
|
453
|
+
return;
|
|
454
|
+
}
|
|
455
|
+
this.projectPathOptionsLoading = true;
|
|
456
|
+
try {
|
|
457
|
+
const res = await api('list-session-paths', { source: 'claude', limit: 100 });
|
|
458
|
+
if (res && Array.isArray(res.paths)) {
|
|
459
|
+
this.projectPathOptions = res.paths
|
|
460
|
+
.map(function (p) { return (p && p.cwd) || p || ''; })
|
|
461
|
+
.filter(Boolean)
|
|
462
|
+
.filter(function (v, i, a) { return a.indexOf(v) === i; });
|
|
463
|
+
}
|
|
464
|
+
} catch (_) {
|
|
465
|
+
// silent
|
|
466
|
+
} finally {
|
|
467
|
+
this.projectPathOptionsLoading = false;
|
|
468
|
+
}
|
|
469
|
+
},
|
|
423
470
|
async pasteAgentsContent() {
|
|
424
471
|
if (this.agentsLoading || this.agentsSaving || this.agentsDiffVisible) {
|
|
425
472
|
return;
|
|
@@ -444,10 +491,11 @@ export function createAgentsMethods(options = {}) {
|
|
|
444
491
|
const fileName = context === 'openclaw-workspace'
|
|
445
492
|
? (this.agentsWorkspaceFileName || '')
|
|
446
493
|
: '';
|
|
494
|
+
const projectPath = context === 'claude-project' ? (this.projectClaudeMdPath || '') : '';
|
|
447
495
|
const lineEnding = this.agentsLineEnding || '\n';
|
|
448
496
|
const content = typeof this.agentsContent === 'string' ? this.agentsContent : '';
|
|
449
497
|
const original = typeof this.agentsOriginalContent === 'string' ? this.agentsOriginalContent : '';
|
|
450
|
-
return `${context}::${fileName}::${lineEnding}::${content.length}::${content}::${original.length}::${original}`;
|
|
498
|
+
return `${context}::${fileName}::${projectPath}::${lineEnding}::${content.length}::${content}::${original.length}::${original}`;
|
|
451
499
|
},
|
|
452
500
|
async prepareAgentsDiff() {
|
|
453
501
|
const requestFingerprint = this.buildAgentsDiffFingerprint();
|
|
@@ -504,7 +552,8 @@ export function createAgentsMethods(options = {}) {
|
|
|
504
552
|
content: this.agentsContent,
|
|
505
553
|
lineEnding: this.agentsLineEnding,
|
|
506
554
|
context: this.agentsContext,
|
|
507
|
-
fileName: this.agentsWorkspaceFileName
|
|
555
|
+
fileName: this.agentsWorkspaceFileName,
|
|
556
|
+
baseDir: this.agentsContext === 'claude-project' ? this.projectClaudeMdPath : undefined
|
|
508
557
|
});
|
|
509
558
|
if (previewRequest.exceedsBodyLimit) {
|
|
510
559
|
applyPreviewState(buildAgentsDiffPreview({
|
|
@@ -621,8 +670,12 @@ export function createAgentsMethods(options = {}) {
|
|
|
621
670
|
content: this.agentsContent,
|
|
622
671
|
lineEnding: this.agentsLineEnding
|
|
623
672
|
};
|
|
624
|
-
if (this.agentsContext === 'claude-
|
|
673
|
+
if (this.agentsContext === 'claude-project') {
|
|
625
674
|
action = 'apply-claude-md-file';
|
|
675
|
+
const projectPath = (this.projectClaudeMdPath || '').trim();
|
|
676
|
+
if (projectPath) {
|
|
677
|
+
params.baseDir = projectPath;
|
|
678
|
+
}
|
|
626
679
|
} else if (this.agentsContext === 'openclaw') {
|
|
627
680
|
action = 'apply-openclaw-agents-file';
|
|
628
681
|
} else if (this.agentsContext === 'openclaw-workspace') {
|
|
@@ -636,8 +689,8 @@ export function createAgentsMethods(options = {}) {
|
|
|
636
689
|
}
|
|
637
690
|
const successLabel = this.agentsContext === 'openclaw-workspace'
|
|
638
691
|
? this.t('toast.agents.saved.workspace', { name: this.agentsWorkspaceFileName || '' }).replace(/:\s*$/, '')
|
|
639
|
-
: (this.agentsContext === 'claude-
|
|
640
|
-
? this.t('toast.agents.saved.
|
|
692
|
+
: (this.agentsContext === 'claude-project'
|
|
693
|
+
? this.t('toast.agents.saved.claudeProject')
|
|
641
694
|
: (this.agentsContext === 'openclaw' ? this.t('toast.agents.saved.openclaw') : this.t('toast.agents.saved.agents')));
|
|
642
695
|
this.showMessage(successLabel, 'success');
|
|
643
696
|
if (this.mainTab === 'prompts') {
|
|
@@ -653,7 +706,10 @@ export function createAgentsMethods(options = {}) {
|
|
|
653
706
|
},
|
|
654
707
|
|
|
655
708
|
switchPromptsSubTab(subTab) {
|
|
656
|
-
const normalized = subTab === 'claude-
|
|
709
|
+
const normalized = subTab === 'claude-project' ? 'claude-project' : 'codex';
|
|
710
|
+
if (normalized === 'claude-project' && !this.projectPathOptions.length && !this.projectPathOptionsLoading) {
|
|
711
|
+
this.loadProjectPathOptions();
|
|
712
|
+
}
|
|
657
713
|
if (this.promptsSubTab === normalized) {
|
|
658
714
|
this.loadPromptsContent();
|
|
659
715
|
return;
|
|
@@ -666,9 +722,19 @@ export function createAgentsMethods(options = {}) {
|
|
|
666
722
|
this.agentsLoading = true;
|
|
667
723
|
this.resetAgentsDiffState();
|
|
668
724
|
try {
|
|
669
|
-
const
|
|
670
|
-
|
|
671
|
-
const
|
|
725
|
+
const subTab = this.promptsSubTab;
|
|
726
|
+
let action;
|
|
727
|
+
const rpcParams = {};
|
|
728
|
+
if (subTab === 'claude-project') {
|
|
729
|
+
action = 'get-claude-md-file';
|
|
730
|
+
const projectPath = (this.projectClaudeMdPath || '').trim();
|
|
731
|
+
if (projectPath) {
|
|
732
|
+
rpcParams.baseDir = projectPath;
|
|
733
|
+
}
|
|
734
|
+
} else {
|
|
735
|
+
action = 'get-agents-file';
|
|
736
|
+
}
|
|
737
|
+
const res = await api(action, rpcParams);
|
|
672
738
|
if (!isLatestRequestToken(this, '_agentsOpenRequestToken', requestToken)) {
|
|
673
739
|
return;
|
|
674
740
|
}
|
|
@@ -681,7 +747,7 @@ export function createAgentsMethods(options = {}) {
|
|
|
681
747
|
this.agentsPath = res.path || '';
|
|
682
748
|
this.agentsExists = !!res.exists;
|
|
683
749
|
this.agentsLineEnding = res.lineEnding === '\r\n' ? '\r\n' : '\n';
|
|
684
|
-
this.agentsContext =
|
|
750
|
+
this.agentsContext = subTab === 'claude-project' ? 'claude-project' : 'codex';
|
|
685
751
|
} catch (e) {
|
|
686
752
|
if (!isLatestRequestToken(this, '_agentsOpenRequestToken', requestToken)) {
|
|
687
753
|
return;
|
|
@@ -750,9 +750,13 @@ export function createCodexConfigMethods(options = {}) {
|
|
|
750
750
|
&& this._configTemplateDiffPreviewRequestToken === requestToken
|
|
751
751
|
&& this.buildConfigTemplateDiffFingerprint() === requestFingerprint
|
|
752
752
|
);
|
|
753
|
-
const res =
|
|
754
|
-
|
|
755
|
-
|
|
753
|
+
const res = this.configTemplateContext === 'claude'
|
|
754
|
+
? await api('preview-claude-settings-diff', {
|
|
755
|
+
content: this.configTemplateContent
|
|
756
|
+
})
|
|
757
|
+
: await api('preview-config-template-diff', {
|
|
758
|
+
template: this.configTemplateContent
|
|
759
|
+
});
|
|
756
760
|
if (!shouldApply()) {
|
|
757
761
|
return;
|
|
758
762
|
}
|
|
@@ -145,9 +145,9 @@ export function createStartupClaudeMethods(options = {}) {
|
|
|
145
145
|
this.maybeShowStarPrompt();
|
|
146
146
|
return true;
|
|
147
147
|
} catch (e) {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
148
|
+
if (e && e.message !== 'timeout') {
|
|
149
|
+
this.initError = '连接失败: ' + (e.message || '');
|
|
150
|
+
}
|
|
151
151
|
return false;
|
|
152
152
|
} finally {
|
|
153
153
|
if (!preserveLoading) {
|
|
@@ -220,7 +220,11 @@ const en = Object.freeze({
|
|
|
220
220
|
'subtitle.settings': 'Manage downloads, directories, and trash.',
|
|
221
221
|
'subtitle.prompts': 'Edit AGENTS.md and CLAUDE.md.',
|
|
222
222
|
'prompts.subTab.codex': 'AGENTS.md (Codex)',
|
|
223
|
-
'prompts.subTab.
|
|
223
|
+
'prompts.subTab.project': 'CLAUDE.md',
|
|
224
|
+
'prompts.project.pathLabel': 'Project path (optional)',
|
|
225
|
+
'prompts.project.selectPlaceholder': '-- Global (~/.claude/CLAUDE.md) --',
|
|
226
|
+
'prompts.project.manualPlaceholder': 'Or enter a project root path...',
|
|
227
|
+
'prompts.project.detected': 'Editing CLAUDE.md in: {path}',
|
|
224
228
|
'dashboard.doctor.title': 'Doctor',
|
|
225
229
|
'dashboard.doctor.runChecks': 'Run checks',
|
|
226
230
|
'dashboard.doctor.checking': 'Checking...',
|
|
@@ -401,7 +405,7 @@ const en = Object.freeze({
|
|
|
401
405
|
'toast.save.ok': 'Saved',
|
|
402
406
|
'toast.save.fail': 'Save failed',
|
|
403
407
|
'toast.agents.saved.agents': 'AGENTS.md saved',
|
|
404
|
-
'toast.agents.saved.
|
|
408
|
+
'toast.agents.saved.claudeProject': 'Project CLAUDE.md saved',
|
|
405
409
|
'toast.agents.saved.openclaw': 'OpenClaw AGENTS.md saved',
|
|
406
410
|
'toast.agents.saved.workspace': 'Workspace file saved: {name}',
|
|
407
411
|
'toast.delete.ok': 'Deleted',
|
|
@@ -486,6 +490,7 @@ const en = Object.freeze({
|
|
|
486
490
|
'modal.configTemplate.mode.twoStep': 'Two-step confirm: preview diff, then apply.',
|
|
487
491
|
'modal.configTemplate.mode.oneStep': 'One-step apply: write immediately.',
|
|
488
492
|
'diff.title.configTemplate': 'Diff preview (config.toml)',
|
|
493
|
+
'diff.title.claudeSettings': 'Diff preview (settings.json)',
|
|
489
494
|
'diff.generating': 'Generating...',
|
|
490
495
|
'diff.failed': 'Failed',
|
|
491
496
|
'diff.noChanges': 'No changes detected',
|
|
@@ -871,12 +876,14 @@ const en = Object.freeze({
|
|
|
871
876
|
'config.autoCompact.hint': 'Auto-compaction threshold (default 185000).',
|
|
872
877
|
'config.agents.open': 'Open AGENTS.md',
|
|
873
878
|
'modal.agents.title.default': 'AGENTS.md editor',
|
|
874
|
-
'modal.agents.title.claudeMd': 'CLAUDE.md editor',
|
|
875
879
|
'modal.agents.title.openclaw': 'OpenClaw AGENTS.md editor',
|
|
876
880
|
'modal.agents.hint.default': 'Saved content will be written to AGENTS.md (next to config.toml).',
|
|
877
|
-
'modal.agents.
|
|
878
|
-
'modal.agents.
|
|
879
|
-
'modal.agents.
|
|
881
|
+
'modal.agents.title.claudeProject': 'Project CLAUDE.md: {path}',
|
|
882
|
+
'modal.agents.hint.claudeProject': 'Saved content will be written to CLAUDE.md in: {path}',
|
|
883
|
+
'modal.agents.title.claudeProjectGlobal': 'Global CLAUDE.md',
|
|
884
|
+
'modal.agents.hint.claudeProjectGlobal': 'Saved content will be written to ~/.claude/CLAUDE.md.',
|
|
885
|
+
'modal.agents.contentLabel.claudeProject': 'CLAUDE.md content',
|
|
886
|
+
'modal.agents.placeholder.claudeProject': 'Edit CLAUDE.md here',
|
|
880
887
|
'modal.agents.hint.openclaw': 'Saved content will be written to OpenClaw workspace AGENTS.md.',
|
|
881
888
|
'modal.agents.title.openclawWorkspaceFile': 'OpenClaw workspace file: {fileName}',
|
|
882
889
|
'modal.agents.hint.openclawWorkspaceFile': 'Saved content will be written to OpenClaw workspace {fileName}.',
|
|
@@ -1210,6 +1217,10 @@ const en = Object.freeze({
|
|
|
1210
1217
|
'claude.model': 'Model',
|
|
1211
1218
|
'claude.model.placeholder': 'e.g. claude-3-7-sonnet',
|
|
1212
1219
|
'claude.model.hint': 'Model changes are saved and applied to the current config automatically.',
|
|
1220
|
+
'claude.model.haiku': 'Haiku Model',
|
|
1221
|
+
'claude.model.sonnet': 'Sonnet Model',
|
|
1222
|
+
'claude.model.opus': 'Opus Model',
|
|
1223
|
+
'claude.model.sub.placeholder': 'Defaults to the main model if left empty',
|
|
1213
1224
|
'claude.targetApi.label': 'Target API',
|
|
1214
1225
|
'claude.targetApi.responses': 'Anthropic',
|
|
1215
1226
|
'claude.targetApi.chatCompletions': 'OpenAI Chat Completions (/v1/chat/completions)',
|
|
@@ -221,7 +221,11 @@ const ja = Object.freeze({
|
|
|
221
221
|
'subtitle.settings': 'ダウンロード・ディレクトリ・ゴミ箱の管理。',
|
|
222
222
|
'subtitle.prompts': 'AGENTS.md と CLAUDE.md を編集。',
|
|
223
223
|
'prompts.subTab.codex': 'AGENTS.md (Codex)',
|
|
224
|
-
'prompts.subTab.
|
|
224
|
+
'prompts.subTab.project': 'CLAUDE.md',
|
|
225
|
+
'prompts.project.pathLabel': 'プロジェクトパス(任意)',
|
|
226
|
+
'prompts.project.selectPlaceholder': '-- グローバル (~/.claude/CLAUDE.md) --',
|
|
227
|
+
'prompts.project.manualPlaceholder': 'またはプロジェクトルートパスを入力...',
|
|
228
|
+
'prompts.project.detected': '編集中: {path}',
|
|
225
229
|
|
|
226
230
|
'dashboard.doctor.title': 'Doctor',
|
|
227
231
|
'dashboard.doctor.runChecks': 'チェックを実行',
|
|
@@ -403,7 +407,7 @@ const ja = Object.freeze({
|
|
|
403
407
|
'toast.save.ok': '保存しました',
|
|
404
408
|
'toast.save.fail': '保存に失敗しました',
|
|
405
409
|
'toast.agents.saved.agents': 'AGENTS.md 保存しました',
|
|
406
|
-
'toast.agents.saved.
|
|
410
|
+
'toast.agents.saved.claudeProject': 'プロジェクト CLAUDE.md 保存しました',
|
|
407
411
|
'toast.agents.saved.openclaw': 'OpenClaw AGENTS.md 保存しました',
|
|
408
412
|
'toast.agents.saved.workspace': 'ワークスペースファイル保存済み: {name}',
|
|
409
413
|
'toast.delete.ok': '削除しました',
|
|
@@ -488,6 +492,7 @@ const ja = Object.freeze({
|
|
|
488
492
|
'modal.configTemplate.mode.twoStep': '二段階確認:先に差分をプレビューし、その後適用します。',
|
|
489
493
|
'modal.configTemplate.mode.oneStep': '一段階適用:「適用」をクリックすると直接書き込みます。',
|
|
490
494
|
'diff.title.configTemplate': '差分プレビュー(config.toml)',
|
|
495
|
+
'diff.title.claudeSettings': '差分プレビュー(settings.json)',
|
|
491
496
|
'diff.generating': '生成中...',
|
|
492
497
|
'diff.failed': '生成失敗',
|
|
493
498
|
'diff.noChanges': '変更が検出されませんでした',
|
|
@@ -860,12 +865,14 @@ const ja = Object.freeze({
|
|
|
860
865
|
'config.autoCompact.hint': '自動圧縮閾値、デフォルト 185000。',
|
|
861
866
|
'config.agents.open': 'AGENTS.md を開く',
|
|
862
867
|
'modal.agents.title.default': 'AGENTS.md エディタ',
|
|
863
|
-
'modal.agents.title.claudeMd': 'CLAUDE.md エディタ',
|
|
864
868
|
'modal.agents.title.openclaw': 'OpenClaw AGENTS.md エディタ',
|
|
865
869
|
'modal.agents.hint.default': '保存すると対象の AGENTS.md(config.toml と同階層)に書き込まれます。',
|
|
866
|
-
'modal.agents.
|
|
867
|
-
'modal.agents.
|
|
868
|
-
'modal.agents.
|
|
870
|
+
'modal.agents.title.claudeProject': 'プロジェクト CLAUDE.md: {path}',
|
|
871
|
+
'modal.agents.hint.claudeProject': '保存するとプロジェクトの CLAUDE.md に書き込まれます: {path}',
|
|
872
|
+
'modal.agents.title.claudeProjectGlobal': 'グローバル CLAUDE.md',
|
|
873
|
+
'modal.agents.hint.claudeProjectGlobal': '保存すると ~/.claude/CLAUDE.md に書き込まれます。',
|
|
874
|
+
'modal.agents.contentLabel.claudeProject': 'CLAUDE.md 内容',
|
|
875
|
+
'modal.agents.placeholder.claudeProject': 'CLAUDE.md を編集',
|
|
869
876
|
'modal.agents.hint.openclaw': '保存すると OpenClaw Workspace の AGENTS.md に書き込まれます。',
|
|
870
877
|
'modal.agents.title.openclawWorkspaceFile': 'OpenClaw ワークスペースファイル: {fileName}',
|
|
871
878
|
'modal.agents.hint.openclawWorkspaceFile': '保存すると OpenClaw Workspace の {fileName} に書き込まれます。',
|
|
@@ -1203,6 +1210,10 @@ const ja = Object.freeze({
|
|
|
1203
1210
|
'claude.model': 'モデル',
|
|
1204
1211
|
'claude.model.placeholder': '例: claude-3-7-sonnet',
|
|
1205
1212
|
'claude.model.hint': 'モデル変更後は自動保存され、現在の設定に適用されます。',
|
|
1213
|
+
'claude.model.haiku': 'Haiku モデル',
|
|
1214
|
+
'claude.model.sonnet': 'Sonnet モデル',
|
|
1215
|
+
'claude.model.opus': 'Opus モデル',
|
|
1216
|
+
'claude.model.sub.placeholder': '空欄の場合、メインモデルに従います',
|
|
1206
1217
|
'claude.targetApi.label': 'ターゲット API',
|
|
1207
1218
|
'claude.targetApi.responses': 'Anthropic',
|
|
1208
1219
|
'claude.targetApi.chatCompletions': 'OpenAI Chat Completions (/v1/chat/completions)',
|
|
@@ -234,7 +234,11 @@ const vi = Object.freeze({
|
|
|
234
234
|
'subtitle.settings': 'Quản lý tải xuống, thư mục và dữ liệu.',
|
|
235
235
|
'subtitle.prompts': 'Chỉnh sửa AGENTS.md và CLAUDE.md.',
|
|
236
236
|
'prompts.subTab.codex': 'AGENTS.md (Codex)',
|
|
237
|
-
'prompts.subTab.
|
|
237
|
+
'prompts.subTab.project': 'CLAUDE.md',
|
|
238
|
+
'prompts.project.pathLabel': 'Đường dẫn dự án (tùy chọn)',
|
|
239
|
+
'prompts.project.selectPlaceholder': '-- Toàn cục (~/.claude/CLAUDE.md) --',
|
|
240
|
+
'prompts.project.manualPlaceholder': 'Hoặc nhập đường dẫn gốc dự án...',
|
|
241
|
+
'prompts.project.detected': 'Đang chỉnh sửa CLAUDE.md trong: {path}',
|
|
238
242
|
|
|
239
243
|
|
|
240
244
|
// Task orchestration readiness
|
|
@@ -317,7 +321,7 @@ const vi = Object.freeze({
|
|
|
317
321
|
'toast.save.ok': 'Đã lưu',
|
|
318
322
|
'toast.save.fail': 'Lưu thất bại',
|
|
319
323
|
'toast.agents.saved.agents': 'AGENTS.md đã lưu',
|
|
320
|
-
'toast.agents.saved.
|
|
324
|
+
'toast.agents.saved.claudeProject': 'CLAUDE.md dự án đã lưu',
|
|
321
325
|
'toast.agents.saved.openclaw': 'OpenClaw AGENTS.md đã lưu',
|
|
322
326
|
'toast.agents.saved.workspace': 'Tệp workspace đã lưu: {name}',
|
|
323
327
|
'toast.delete.ok': 'Đã xóa',
|
|
@@ -362,6 +366,10 @@ const vi = Object.freeze({
|
|
|
362
366
|
'validation.claude.baseUrlRequired': 'Base URL là bắt buộc',
|
|
363
367
|
'validation.claude.baseUrlHttpOnly': 'Base URL chỉ hỗ trợ http/https',
|
|
364
368
|
'validation.claude.modelRequired': 'Tên mô hình là bắt buộc',
|
|
369
|
+
'claude.model.haiku': 'Mô hình Haiku',
|
|
370
|
+
'claude.model.sonnet': 'Mô hình Sonnet',
|
|
371
|
+
'claude.model.opus': 'Mô hình Opus',
|
|
372
|
+
'claude.model.sub.placeholder': 'Để trống sẽ dùng mô hình chính',
|
|
365
373
|
'modal.claudeDelete.title': 'Xóa cấu hình Claude',
|
|
366
374
|
'modal.claudeDelete.message': 'Xóa cấu hình "{name}"?',
|
|
367
375
|
'modal.claudeDelete.confirm': 'Xóa',
|
|
@@ -381,6 +389,12 @@ const vi = Object.freeze({
|
|
|
381
389
|
'diff.hint.previewMode': 'Đang xem trước. Nhấp "Lưu" để ghi hoặc "Quay lại chỉnh sửa" để tiếp tục.',
|
|
382
390
|
'modal.agents.unsaved.detectedHint': 'Phát hiện thay đổi chưa lưu: lưu trước khi đóng hoặc áp dụng.',
|
|
383
391
|
'modal.agents.hint.twoStepSave': 'Lưu hai bước: "Xem trước" để kiểm tra diff, rồi "Lưu" để ghi.',
|
|
392
|
+
'modal.agents.title.claudeProject': 'CLAUDE.md dự án: {path}',
|
|
393
|
+
'modal.agents.hint.claudeProject': 'Nội dung sẽ được ghi vào CLAUDE.md trong dự án: {path}',
|
|
394
|
+
'modal.agents.title.claudeProjectGlobal': 'CLAUDE.md toàn cục',
|
|
395
|
+
'modal.agents.hint.claudeProjectGlobal': 'Nội dung sẽ được ghi vào ~/.claude/CLAUDE.md.',
|
|
396
|
+
'modal.agents.contentLabel.claudeProject': 'Nội dung CLAUDE.md',
|
|
397
|
+
'modal.agents.placeholder.claudeProject': 'Chỉnh sửa CLAUDE.md tại đây',
|
|
384
398
|
'diff.viewHint.preview': 'Đang xem trước. Nhấp "Lưu" để ghi hoặc "Quay lại chỉnh sửa" để tiếp tục.',
|
|
385
399
|
'diff.viewHint.truncated': 'Bỏ qua xem trước do nội dung quá lớn. Nhấp "Lưu" để ghi hoặc "Quay lại chỉnh sửa" để tiếp tục.',
|
|
386
400
|
});
|
|
@@ -220,7 +220,11 @@ const zhTw = Object.freeze({
|
|
|
220
220
|
'subtitle.settings': '管理下載、目錄與回收站。',
|
|
221
221
|
'subtitle.prompts': '編輯 AGENTS.md 與 CLAUDE.md。',
|
|
222
222
|
'prompts.subTab.codex': 'AGENTS.md (Codex)',
|
|
223
|
-
'prompts.subTab.
|
|
223
|
+
'prompts.subTab.project': 'CLAUDE.md',
|
|
224
|
+
'prompts.project.pathLabel': '專案路徑(可選)',
|
|
225
|
+
'prompts.project.selectPlaceholder': '-- 全域 (~/.claude/CLAUDE.md) --',
|
|
226
|
+
'prompts.project.manualPlaceholder': '或手動輸入專案根路徑...',
|
|
227
|
+
'prompts.project.detected': '正在編輯: {path}',
|
|
224
228
|
'dashboard.doctor.title': 'Doctor',
|
|
225
229
|
'dashboard.doctor.runChecks': '運行檢查',
|
|
226
230
|
'dashboard.doctor.checking': '檢查中...',
|
|
@@ -401,7 +405,7 @@ const zhTw = Object.freeze({
|
|
|
401
405
|
'toast.save.ok': '已保存',
|
|
402
406
|
'toast.save.fail': '保存失敗',
|
|
403
407
|
'toast.agents.saved.agents': 'AGENTS.md 已保存',
|
|
404
|
-
'toast.agents.saved.
|
|
408
|
+
'toast.agents.saved.claudeProject': '專案 CLAUDE.md 已保存',
|
|
405
409
|
'toast.agents.saved.openclaw': 'OpenClaw AGENTS.md 已保存',
|
|
406
410
|
'toast.agents.saved.workspace': '工作區文件已保存: {name}',
|
|
407
411
|
'toast.delete.ok': '已刪除',
|
|
@@ -486,6 +490,7 @@ const zhTw = Object.freeze({
|
|
|
486
490
|
'modal.configTemplate.mode.twoStep': '兩步確認:先預覽差異,再應用寫入。',
|
|
487
491
|
'modal.configTemplate.mode.oneStep': '一步應用:點擊“應用”直接寫入。',
|
|
488
492
|
'diff.title.configTemplate': '差異預覽(config.toml)',
|
|
493
|
+
'diff.title.claudeSettings': '差異預覽(settings.json)',
|
|
489
494
|
'diff.generating': '生成中...',
|
|
490
495
|
'diff.failed': '生成失敗',
|
|
491
496
|
'diff.noChanges': '未檢測到改動',
|
|
@@ -870,12 +875,14 @@ const zhTw = Object.freeze({
|
|
|
870
875
|
'config.autoCompact.hint': '自動壓縮閾值,預設 185000。',
|
|
871
876
|
'config.agents.open': '打開 AGENTS.md',
|
|
872
877
|
'modal.agents.title.default': 'AGENTS.md 編輯器',
|
|
873
|
-
'modal.agents.title.claudeMd': 'CLAUDE.md 編輯器',
|
|
874
878
|
'modal.agents.title.openclaw': 'OpenClaw AGENTS.md 編輯器',
|
|
875
879
|
'modal.agents.hint.default': '保存後會寫入目標 AGENTS.md(與 config.toml 同級)。',
|
|
876
|
-
'modal.agents.
|
|
877
|
-
'modal.agents.
|
|
878
|
-
'modal.agents.
|
|
880
|
+
'modal.agents.title.claudeProject': '專案 CLAUDE.md: {path}',
|
|
881
|
+
'modal.agents.hint.claudeProject': '保存後會寫入專案目錄下的 CLAUDE.md: {path}',
|
|
882
|
+
'modal.agents.title.claudeProjectGlobal': '全域 CLAUDE.md',
|
|
883
|
+
'modal.agents.hint.claudeProjectGlobal': '保存後會寫入 ~/.claude/CLAUDE.md。',
|
|
884
|
+
'modal.agents.contentLabel.claudeProject': 'CLAUDE.md 內容',
|
|
885
|
+
'modal.agents.placeholder.claudeProject': '在這裡編輯 CLAUDE.md',
|
|
879
886
|
'modal.agents.hint.openclaw': '保存後會寫入 OpenClaw Workspace 下的 AGENTS.md。',
|
|
880
887
|
'modal.agents.title.openclawWorkspaceFile': 'OpenClaw 工作區文件: {fileName}',
|
|
881
888
|
'modal.agents.hint.openclawWorkspaceFile': '保存後會寫入 OpenClaw Workspace 下的 {fileName}。',
|
|
@@ -1213,6 +1220,10 @@ const zhTw = Object.freeze({
|
|
|
1213
1220
|
'claude.model': '模型',
|
|
1214
1221
|
'claude.model.placeholder': '例如: claude-3-7-sonnet',
|
|
1215
1222
|
'claude.model.hint': '模型修改後會自動保存並應用到目前設定。',
|
|
1223
|
+
'claude.model.haiku': 'Haiku 模型',
|
|
1224
|
+
'claude.model.sonnet': 'Sonnet 模型',
|
|
1225
|
+
'claude.model.opus': 'Opus 模型',
|
|
1226
|
+
'claude.model.sub.placeholder': '留空則跟隨主模型',
|
|
1216
1227
|
'claude.targetApi.label': '目標 API',
|
|
1217
1228
|
'claude.targetApi.responses': 'Anthropic',
|
|
1218
1229
|
'claude.targetApi.chatCompletions': 'OpenAI Chat Completions (/v1/chat/completions)',
|
|
@@ -220,7 +220,11 @@ const zh = Object.freeze({
|
|
|
220
220
|
'subtitle.settings': '管理下载、目录与回收站。',
|
|
221
221
|
'subtitle.prompts': '编辑 AGENTS.md 与 CLAUDE.md。',
|
|
222
222
|
'prompts.subTab.codex': 'AGENTS.md (Codex)',
|
|
223
|
-
'prompts.subTab.
|
|
223
|
+
'prompts.subTab.project': 'CLAUDE.md',
|
|
224
|
+
'prompts.project.pathLabel': '项目路径(可选)',
|
|
225
|
+
'prompts.project.selectPlaceholder': '-- 全局 (~/.claude/CLAUDE.md) --',
|
|
226
|
+
'prompts.project.manualPlaceholder': '或手动输入项目根路径...',
|
|
227
|
+
'prompts.project.detected': '正在编辑: {path}',
|
|
224
228
|
'dashboard.doctor.title': 'Doctor',
|
|
225
229
|
'dashboard.doctor.runChecks': '运行检查',
|
|
226
230
|
'dashboard.doctor.checking': '检查中...',
|
|
@@ -401,7 +405,7 @@ const zh = Object.freeze({
|
|
|
401
405
|
'toast.save.ok': '已保存',
|
|
402
406
|
'toast.save.fail': '保存失败',
|
|
403
407
|
'toast.agents.saved.agents': 'AGENTS.md 已保存',
|
|
404
|
-
'toast.agents.saved.
|
|
408
|
+
'toast.agents.saved.claudeProject': '项目 CLAUDE.md 已保存',
|
|
405
409
|
'toast.agents.saved.openclaw': 'OpenClaw AGENTS.md 已保存',
|
|
406
410
|
'toast.agents.saved.workspace': '工作区文件已保存: {name}',
|
|
407
411
|
'toast.delete.ok': '已删除',
|
|
@@ -486,6 +490,7 @@ const zh = Object.freeze({
|
|
|
486
490
|
'modal.configTemplate.mode.twoStep': '两步确认:先预览差异,再应用写入。',
|
|
487
491
|
'modal.configTemplate.mode.oneStep': '一步应用:点击“应用”直接写入。',
|
|
488
492
|
'diff.title.configTemplate': '差异预览(config.toml)',
|
|
493
|
+
'diff.title.claudeSettings': '差异预览(settings.json)',
|
|
489
494
|
'diff.generating': '生成中...',
|
|
490
495
|
'diff.failed': '生成失败',
|
|
491
496
|
'diff.noChanges': '未检测到改动',
|
|
@@ -870,12 +875,14 @@ const zh = Object.freeze({
|
|
|
870
875
|
'config.autoCompact.hint': '自动压缩阈值,默认 185000。',
|
|
871
876
|
'config.agents.open': '打开 AGENTS.md',
|
|
872
877
|
'modal.agents.title.default': 'AGENTS.md 编辑器',
|
|
873
|
-
'modal.agents.title.claudeMd': 'CLAUDE.md 编辑器',
|
|
874
878
|
'modal.agents.title.openclaw': 'OpenClaw AGENTS.md 编辑器',
|
|
875
879
|
'modal.agents.hint.default': '保存后会写入目标 AGENTS.md(与 config.toml 同级)。',
|
|
876
|
-
'modal.agents.
|
|
877
|
-
'modal.agents.
|
|
878
|
-
'modal.agents.
|
|
880
|
+
'modal.agents.title.claudeProject': '项目 CLAUDE.md: {path}',
|
|
881
|
+
'modal.agents.hint.claudeProject': '保存后会写入项目目录下的 CLAUDE.md: {path}',
|
|
882
|
+
'modal.agents.title.claudeProjectGlobal': '全局 CLAUDE.md',
|
|
883
|
+
'modal.agents.hint.claudeProjectGlobal': '保存后会写入 ~/.claude/CLAUDE.md。',
|
|
884
|
+
'modal.agents.contentLabel.claudeProject': 'CLAUDE.md 内容',
|
|
885
|
+
'modal.agents.placeholder.claudeProject': '在这里编辑 CLAUDE.md',
|
|
879
886
|
'modal.agents.hint.openclaw': '保存后会写入 OpenClaw Workspace 下的 AGENTS.md。',
|
|
880
887
|
'modal.agents.title.openclawWorkspaceFile': 'OpenClaw 工作区文件: {fileName}',
|
|
881
888
|
'modal.agents.hint.openclawWorkspaceFile': '保存后会写入 OpenClaw Workspace 下的 {fileName}。',
|
|
@@ -1213,6 +1220,10 @@ const zh = Object.freeze({
|
|
|
1213
1220
|
'claude.model': '模型',
|
|
1214
1221
|
'claude.model.placeholder': '例如: claude-3-7-sonnet',
|
|
1215
1222
|
'claude.model.hint': '模型修改后会自动保存并应用到当前配置。',
|
|
1223
|
+
'claude.model.haiku': 'Haiku 模型',
|
|
1224
|
+
'claude.model.sonnet': 'Sonnet 模型',
|
|
1225
|
+
'claude.model.opus': 'Opus 模型',
|
|
1226
|
+
'claude.model.sub.placeholder': '留空则跟随主模型',
|
|
1216
1227
|
'claude.targetApi.label': '目标 API',
|
|
1217
1228
|
'claude.targetApi.responses': 'Anthropic',
|
|
1218
1229
|
'claude.targetApi.chatCompletions': 'OpenAI Chat Completions (/v1/chat/completions)',
|
|
@@ -255,13 +255,13 @@
|
|
|
255
255
|
</div>
|
|
256
256
|
</button>
|
|
257
257
|
<button
|
|
258
|
-
id="side-tab-prompts-
|
|
258
|
+
id="side-tab-prompts-project"
|
|
259
259
|
data-main-tab="prompts"
|
|
260
|
-
data-prompts-sub-tab="claude-
|
|
261
|
-
:aria-current="mainTab === 'prompts' && promptsSubTab === 'claude-
|
|
262
|
-
:class="['side-item', { active: isMainTabNavActive('prompts') && promptsSubTab === 'claude-
|
|
260
|
+
data-prompts-sub-tab="claude-project"
|
|
261
|
+
:aria-current="mainTab === 'prompts' && promptsSubTab === 'claude-project' ? 'page' : null"
|
|
262
|
+
:class="['side-item', { active: isMainTabNavActive('prompts') && promptsSubTab === 'claude-project' }]"
|
|
263
263
|
@pointerdown="onMainTabPointerDown('prompts', $event)"
|
|
264
|
-
@click="switchPromptsSubTab('claude-
|
|
264
|
+
@click="switchPromptsSubTab('claude-project'); onMainTabClick('prompts')">
|
|
265
265
|
<div class="side-item-title">{{ t('side.prompts.claude') }}</div>
|
|
266
266
|
<div class="side-item-meta">
|
|
267
267
|
<span>{{ t('side.prompts.claude.meta') }}</span>
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
<div v-if="configTemplateDiffVisible" class="agents-diff-container">
|
|
13
13
|
<div class="agents-diff-header">
|
|
14
14
|
<div class="agents-diff-title">
|
|
15
|
-
{{ t('diff.title.configTemplate') }}
|
|
15
|
+
{{ configTemplateContext === 'claude' ? t('diff.title.claudeSettings') : t('diff.title.configTemplate') }}
|
|
16
16
|
<span v-if="configTemplateDiffLoading" class="agents-diff-subtitle">{{ t('diff.generating') }}</span>
|
|
17
17
|
<span v-else-if="configTemplateDiffError" class="agents-diff-subtitle">{{ t('diff.failed') }}</span>
|
|
18
18
|
<span v-else-if="!configTemplateDiffHasChanges" class="agents-diff-subtitle">{{ t('diff.noChanges') }}</span>
|
|
@@ -130,7 +130,7 @@
|
|
|
130
130
|
|
|
131
131
|
|
|
132
132
|
<div class="form-group">
|
|
133
|
-
<label class="form-label">{{ t(agentsContext === 'claude-
|
|
133
|
+
<label class="form-label">{{ t(agentsContext === 'claude-project' ? 'modal.agents.contentLabel.claudeProject' : 'modal.agents.contentLabel') }}</label>
|
|
134
134
|
<div
|
|
135
135
|
v-if="!agentsLoading && (hasAgentsContentChanged() || agentsDiffVisible)"
|
|
136
136
|
class="agents-diff-save-alert">
|
|
@@ -165,7 +165,7 @@
|
|
|
165
165
|
spellcheck="false"
|
|
166
166
|
:readonly="agentsLoading || agentsSaving || agentsDiffVisible"
|
|
167
167
|
@input="onAgentsContentInput"
|
|
168
|
-
:placeholder="t(agentsContext === 'claude-
|
|
168
|
+
:placeholder="t(agentsContext === 'claude-project' ? 'modal.agents.placeholder.claudeProject' : 'modal.agents.placeholder')"></textarea>
|
|
169
169
|
<div class="template-editor-warning">
|
|
170
170
|
{{ agentsModalHint }}
|
|
171
171
|
<div class="agents-diff-hint">{{ t('modal.agents.hint.shortcuts') }}</div>
|
|
@@ -7,7 +7,29 @@
|
|
|
7
7
|
aria-labelledby="tab-prompts">
|
|
8
8
|
<div class="segmented-control">
|
|
9
9
|
<button type="button" :class="['segment', { active: promptsSubTab === 'codex' }]" @click="switchPromptsSubTab('codex')">{{ t('prompts.subTab.codex') }}</button>
|
|
10
|
-
<button type="button" :class="['segment', { active: promptsSubTab === 'claude-
|
|
10
|
+
<button type="button" :class="['segment', { active: promptsSubTab === 'claude-project' }]" @click="switchPromptsSubTab('claude-project')">{{ t('prompts.subTab.project') }}</button>
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
<div v-if="promptsSubTab === 'claude-project'" class="project-path-selector">
|
|
14
|
+
<label class="project-path-label">{{ t('prompts.project.pathLabel') }}</label>
|
|
15
|
+
<div class="project-path-row">
|
|
16
|
+
<select
|
|
17
|
+
class="form-input project-path-select"
|
|
18
|
+
:value="projectClaudeMdPath"
|
|
19
|
+
@change="selectProjectClaudeMdPath($event.target.value)">
|
|
20
|
+
<option value="">{{ t('prompts.project.selectPlaceholder') }}</option>
|
|
21
|
+
<option v-for="p in projectPathOptions" :key="p" :value="p">{{ p }}</option>
|
|
22
|
+
</select>
|
|
23
|
+
<input
|
|
24
|
+
type="text"
|
|
25
|
+
class="form-input project-path-manual"
|
|
26
|
+
:placeholder="t('prompts.project.manualPlaceholder')"
|
|
27
|
+
:value="projectClaudeMdPath"
|
|
28
|
+
@change="setProjectClaudeMdPathManual($event.target.value)">
|
|
29
|
+
</div>
|
|
30
|
+
<div v-if="projectClaudeMdPath" class="form-hint project-path-detected">
|
|
31
|
+
{{ t('prompts.project.detected', { path: projectClaudeMdPath }) }}
|
|
32
|
+
</div>
|
|
11
33
|
</div>
|
|
12
34
|
|
|
13
35
|
<div class="prompts-editor">
|
|
@@ -89,7 +111,7 @@
|
|
|
89
111
|
spellcheck="false"
|
|
90
112
|
:readonly="agentsLoading || agentsSaving || agentsDiffVisible"
|
|
91
113
|
@input="onAgentsContentInput"
|
|
92
|
-
:placeholder="t(promptsSubTab === 'claude-
|
|
114
|
+
:placeholder="t(promptsSubTab === 'claude-project' ? 'modal.agents.placeholder.claudeProject' : 'modal.agents.placeholder')"></textarea>
|
|
93
115
|
</div>
|
|
94
116
|
<div v-if="promptsContextHint" :class="['prompts-context-hint', { 'prompts-context-hint--warn': promptsContextHint.warn }]">
|
|
95
117
|
{{ promptsContextHint.text }}
|
|
@@ -351,13 +351,13 @@ return function render(_ctx, _cache) {
|
|
|
351
351
|
])
|
|
352
352
|
], 42 /* CLASS, PROPS, NEED_HYDRATION */, ["aria-current", "onPointerdown", "onClick"]),
|
|
353
353
|
_createElementVNode("button", {
|
|
354
|
-
id: "side-tab-prompts-
|
|
354
|
+
id: "side-tab-prompts-project",
|
|
355
355
|
"data-main-tab": "prompts",
|
|
356
|
-
"data-prompts-sub-tab": "claude-
|
|
357
|
-
"aria-current": _ctx.mainTab === 'prompts' && _ctx.promptsSubTab === 'claude-
|
|
358
|
-
class: _normalizeClass(['side-item', { active: _ctx.isMainTabNavActive('prompts') && _ctx.promptsSubTab === 'claude-
|
|
356
|
+
"data-prompts-sub-tab": "claude-project",
|
|
357
|
+
"aria-current": _ctx.mainTab === 'prompts' && _ctx.promptsSubTab === 'claude-project' ? 'page' : null,
|
|
358
|
+
class: _normalizeClass(['side-item', { active: _ctx.isMainTabNavActive('prompts') && _ctx.promptsSubTab === 'claude-project' }]),
|
|
359
359
|
onPointerdown: $event => (_ctx.onMainTabPointerDown('prompts', $event)),
|
|
360
|
-
onClick: $event => {_ctx.switchPromptsSubTab('claude-
|
|
360
|
+
onClick: $event => {_ctx.switchPromptsSubTab('claude-project'); _ctx.onMainTabClick('prompts')}
|
|
361
361
|
}, [
|
|
362
362
|
_createElementVNode("div", { class: "side-item-title" }, _toDisplayString(_ctx.t('side.prompts.claude')), 1 /* TEXT */),
|
|
363
363
|
_createElementVNode("div", { class: "side-item-meta" }, [
|
|
@@ -5977,10 +5977,46 @@ return function render(_ctx, _cache) {
|
|
|
5977
5977
|
}, _toDisplayString(_ctx.t('prompts.subTab.codex')), 11 /* TEXT, CLASS, PROPS */, ["onClick"]),
|
|
5978
5978
|
_createElementVNode("button", {
|
|
5979
5979
|
type: "button",
|
|
5980
|
-
class: _normalizeClass(['segment', { active: _ctx.promptsSubTab === 'claude-
|
|
5981
|
-
onClick: $event => (_ctx.switchPromptsSubTab('claude-
|
|
5982
|
-
}, _toDisplayString(_ctx.t('prompts.subTab.
|
|
5980
|
+
class: _normalizeClass(['segment', { active: _ctx.promptsSubTab === 'claude-project' }]),
|
|
5981
|
+
onClick: $event => (_ctx.switchPromptsSubTab('claude-project'))
|
|
5982
|
+
}, _toDisplayString(_ctx.t('prompts.subTab.project')), 11 /* TEXT, CLASS, PROPS */, ["onClick"])
|
|
5983
5983
|
]),
|
|
5984
|
+
(_ctx.promptsSubTab === 'claude-project')
|
|
5985
|
+
? (_openBlock(), _createElementBlock("div", {
|
|
5986
|
+
key: 0,
|
|
5987
|
+
class: "project-path-selector"
|
|
5988
|
+
}, [
|
|
5989
|
+
_createElementVNode("label", { class: "project-path-label" }, _toDisplayString(_ctx.t('prompts.project.pathLabel')), 1 /* TEXT */),
|
|
5990
|
+
_createElementVNode("div", { class: "project-path-row" }, [
|
|
5991
|
+
_createElementVNode("select", {
|
|
5992
|
+
class: "form-input project-path-select",
|
|
5993
|
+
value: _ctx.projectClaudeMdPath,
|
|
5994
|
+
onChange: $event => (_ctx.selectProjectClaudeMdPath($event.target.value))
|
|
5995
|
+
}, [
|
|
5996
|
+
_createElementVNode("option", { value: "" }, _toDisplayString(_ctx.t('prompts.project.selectPlaceholder')), 1 /* TEXT */),
|
|
5997
|
+
(_openBlock(true), _createElementBlock(_Fragment, null, _renderList(_ctx.projectPathOptions, (p) => {
|
|
5998
|
+
return (_openBlock(), _createElementBlock("option", {
|
|
5999
|
+
key: p,
|
|
6000
|
+
value: p
|
|
6001
|
+
}, _toDisplayString(p), 9 /* TEXT, PROPS */, ["value"]))
|
|
6002
|
+
}), 128 /* KEYED_FRAGMENT */))
|
|
6003
|
+
], 40 /* PROPS, NEED_HYDRATION */, ["value", "onChange"]),
|
|
6004
|
+
_createElementVNode("input", {
|
|
6005
|
+
type: "text",
|
|
6006
|
+
class: "form-input project-path-manual",
|
|
6007
|
+
placeholder: _ctx.t('prompts.project.manualPlaceholder'),
|
|
6008
|
+
value: _ctx.projectClaudeMdPath,
|
|
6009
|
+
onChange: $event => (_ctx.setProjectClaudeMdPathManual($event.target.value))
|
|
6010
|
+
}, null, 40 /* PROPS, NEED_HYDRATION */, ["placeholder", "value", "onChange"])
|
|
6011
|
+
]),
|
|
6012
|
+
(_ctx.projectClaudeMdPath)
|
|
6013
|
+
? (_openBlock(), _createElementBlock("div", {
|
|
6014
|
+
key: 0,
|
|
6015
|
+
class: "form-hint project-path-detected"
|
|
6016
|
+
}, _toDisplayString(_ctx.t('prompts.project.detected', { path: _ctx.projectClaudeMdPath })), 1 /* TEXT */))
|
|
6017
|
+
: _createCommentVNode("v-if", true)
|
|
6018
|
+
]))
|
|
6019
|
+
: _createCommentVNode("v-if", true),
|
|
5984
6020
|
_createElementVNode("div", { class: "prompts-editor" }, [
|
|
5985
6021
|
_createElementVNode("div", { class: "prompts-editor-toolbar" }, [
|
|
5986
6022
|
_createElementVNode("div", { class: "form-hint" }, [
|
|
@@ -6099,7 +6135,7 @@ return function render(_ctx, _cache) {
|
|
|
6099
6135
|
spellcheck: "false",
|
|
6100
6136
|
readonly: _ctx.agentsLoading || _ctx.agentsSaving || _ctx.agentsDiffVisible,
|
|
6101
6137
|
onInput: _ctx.onAgentsContentInput,
|
|
6102
|
-
placeholder: _ctx.t(_ctx.promptsSubTab === 'claude-
|
|
6138
|
+
placeholder: _ctx.t(_ctx.promptsSubTab === 'claude-project' ? 'modal.agents.placeholder.claudeProject' : 'modal.agents.placeholder')
|
|
6103
6139
|
}, null, 40 /* PROPS, NEED_HYDRATION */, ["onUpdate:modelValue", "readonly", "onInput", "placeholder"]), [
|
|
6104
6140
|
[_vModelText, _ctx.agentsContent]
|
|
6105
6141
|
])
|
|
@@ -7794,7 +7830,7 @@ return function render(_ctx, _cache) {
|
|
|
7794
7830
|
}, [
|
|
7795
7831
|
_createElementVNode("div", { class: "agents-diff-header" }, [
|
|
7796
7832
|
_createElementVNode("div", { class: "agents-diff-title" }, [
|
|
7797
|
-
_createTextVNode(_toDisplayString(_ctx.t('diff.title.configTemplate')) + " ", 1 /* TEXT */),
|
|
7833
|
+
_createTextVNode(_toDisplayString(_ctx.configTemplateContext === 'claude' ? _ctx.t('diff.title.claudeSettings') : _ctx.t('diff.title.configTemplate')) + " ", 1 /* TEXT */),
|
|
7798
7834
|
(_ctx.configTemplateDiffLoading)
|
|
7799
7835
|
? (_openBlock(), _createElementBlock("span", {
|
|
7800
7836
|
key: 0,
|
|
@@ -7970,7 +8006,7 @@ return function render(_ctx, _cache) {
|
|
|
7970
8006
|
])
|
|
7971
8007
|
]),
|
|
7972
8008
|
_createElementVNode("div", { class: "form-group" }, [
|
|
7973
|
-
_createElementVNode("label", { class: "form-label" }, _toDisplayString(_ctx.t(_ctx.agentsContext === 'claude-
|
|
8009
|
+
_createElementVNode("label", { class: "form-label" }, _toDisplayString(_ctx.t(_ctx.agentsContext === 'claude-project' ? 'modal.agents.contentLabel.claudeProject' : 'modal.agents.contentLabel')), 1 /* TEXT */),
|
|
7974
8010
|
(!_ctx.agentsLoading && (_ctx.hasAgentsContentChanged() || _ctx.agentsDiffVisible))
|
|
7975
8011
|
? (_openBlock(), _createElementBlock("div", {
|
|
7976
8012
|
key: 0,
|
|
@@ -8030,7 +8066,7 @@ return function render(_ctx, _cache) {
|
|
|
8030
8066
|
spellcheck: "false",
|
|
8031
8067
|
readonly: _ctx.agentsLoading || _ctx.agentsSaving || _ctx.agentsDiffVisible,
|
|
8032
8068
|
onInput: _ctx.onAgentsContentInput,
|
|
8033
|
-
placeholder: _ctx.t(_ctx.agentsContext === 'claude-
|
|
8069
|
+
placeholder: _ctx.t(_ctx.agentsContext === 'claude-project' ? 'modal.agents.placeholder.claudeProject' : 'modal.agents.placeholder')
|
|
8034
8070
|
}, null, 40 /* PROPS, NEED_HYDRATION */, ["onUpdate:modelValue", "readonly", "onInput", "placeholder"]), [
|
|
8035
8071
|
[_vModelText, _ctx.agentsContent]
|
|
8036
8072
|
]),
|
|
@@ -580,6 +580,39 @@
|
|
|
580
580
|
border-left: 1px solid var(--color-border-soft);
|
|
581
581
|
}
|
|
582
582
|
|
|
583
|
+
.project-path-selector {
|
|
584
|
+
margin-top: 8px;
|
|
585
|
+
margin-bottom: 4px;
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
.project-path-label {
|
|
589
|
+
display: block;
|
|
590
|
+
font-size: 0.85em;
|
|
591
|
+
color: var(--color-text-secondary);
|
|
592
|
+
margin-bottom: 4px;
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
.project-path-row {
|
|
596
|
+
display: flex;
|
|
597
|
+
gap: 8px;
|
|
598
|
+
align-items: center;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
.project-path-select {
|
|
602
|
+
flex: 1;
|
|
603
|
+
min-width: 0;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
.project-path-manual {
|
|
607
|
+
flex: 1;
|
|
608
|
+
min-width: 0;
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
.project-path-detected {
|
|
612
|
+
margin-top: 4px;
|
|
613
|
+
font-size: 0.82em;
|
|
614
|
+
}
|
|
615
|
+
|
|
583
616
|
.editor-frame {
|
|
584
617
|
position: relative;
|
|
585
618
|
border-radius: var(--radius-md);
|
|
@@ -55,14 +55,14 @@
|
|
|
55
55
|
color: var(--color-text-secondary);
|
|
56
56
|
cursor: pointer;
|
|
57
57
|
border-radius: var(--radius-sm);
|
|
58
|
-
transition: color var(--transition-fast) var(--ease-smooth), background-color var(--transition-fast) var(--ease-smooth);
|
|
59
58
|
position: relative;
|
|
60
59
|
z-index: 2;
|
|
61
60
|
letter-spacing: 0;
|
|
62
61
|
}
|
|
63
62
|
|
|
64
|
-
.segment:hover {
|
|
63
|
+
.segment:not(.active):hover {
|
|
65
64
|
color: var(--color-text-primary);
|
|
65
|
+
transition: color var(--transition-fast) var(--ease-smooth), background-color var(--transition-fast) var(--ease-smooth);
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
.segment.active {
|