codexmate 0.1.20 → 0.1.21

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 CHANGED
@@ -63,7 +63,7 @@ Unlike simple wrappers, Codex Mate acts as a **Local Agent Bridge**:
63
63
  - **Pi Provider Config**: Manage Pi providers from the Web UI with lossless round-trip writes to `~/.pi/agent/models.json`, auto-fetched remote model lists, and one-click default provider/model switching via `~/.pi/agent/settings.json`.
64
64
  - **Provider Health Cleanup**: Probe local Codex and Claude provider routes, surface failed configs in one modal, and bulk-clean selected broken providers without touching healthy or protected entries.
65
65
  - **Skills Marketplace**: A local-first market to share and import skills between different agent apps.
66
- - **Prompt File Editor**: Unified editor for global and project-level `CLAUDE.md` and `AGENTS.md` with auto-detection of project paths, plus a shared preset pool for reusable prompts.
66
+ - **Prompt File Editor**: Unified editor for global and project-level `CLAUDE.md` and `AGENTS.md` (including OpenCode's `~/.config/opencode/AGENTS.md`) with auto-detection of project paths, plus a shared preset pool for reusable prompts.
67
67
  - **Task Orchestrator**: Plan and execute complex tasks with dependency tracking.
68
68
 
69
69
  ---
package/README.vi.md CHANGED
@@ -69,7 +69,7 @@ Khác với các wrapper đơn giản, Codex Mate hoạt động như một **Ag
69
69
  | **Bridge OpenAI** | ✅ | Chuyển đổi Codex Responses API sang định dạng OpenAI chuẩn |
70
70
  | **Kiểm tra sức khỏe Provider** | ✅ | Kiểm tra route provider Codex/Claude, đánh dấu cấu hình lỗi và xóa hàng loạt các provider hỏng đã chọn một cách an toàn |
71
71
  | **Mẫu Prompt** | ✅ | Plugin prompt tái sử dụng được với hỗ trợ biến |
72
- | **Trình sửa tệp prompt** | ✅ | Chỉnh sửa CLAUDE.md / AGENTS.md và dùng kho preset chung. Áp dụng preset chỉ cập nhật editor; cần lưu thủ công để ghi vào tệp. |
72
+ | **Trình sửa tệp prompt** | ✅ | Chỉnh sửa CLAUDE.md / AGENTS.md (bao gồm `~/.config/opencode/AGENTS.md` của OpenCode) và dùng kho preset chung. Áp dụng preset chỉ cập nhật editor; cần lưu thủ công để ghi vào tệp. |
73
73
  | **Tích hợp MCP** | ✅ | Expose tool và resource cục bộ qua MCP stdio |
74
74
  | **Tự động cập nhật** | ✅ | Cập nhật nhanh qua `codexmate update` |
75
75
 
package/README.zh.md CHANGED
@@ -61,7 +61,7 @@
61
61
  - **Pi Provider 配置**:在 Web UI 中管理 Pi 供应商,写入 `~/.pi/agent/models.json` 时无损保留未知字段,支持自动拉取远端模型列表,并可一键切换 `~/.pi/agent/settings.json` 中的默认供应商/模型。
62
62
  - **Provider 健康清理**:探测本地 Codex 与 Claude provider 路由,在同一个弹窗里集中展示失败配置,并批量清理已选坏配置,不影响正常或受保护项。
63
63
  - **Skills 市场**:本地优先的市场,支持在不同的智能体应用之间共享和导入 Skills。
64
- - **提示词文件编辑器**:统一编辑全局和项目级 `CLAUDE.md` 与 `AGENTS.md`,支持项目路径自动检测,并提供通用预设池复用 prompt。
64
+ - **提示词文件编辑器**:统一编辑全局和项目级 `CLAUDE.md` 与 `AGENTS.md`(含 OpenCode 的 `~/.config/opencode/AGENTS.md`),支持项目路径自动检测,并提供通用预设池复用 prompt。
65
65
  - **任务编排器**:支持带有依赖跟踪的复杂任务规划与执行。
66
66
 
67
67
  ---
@@ -15,6 +15,7 @@ function createAgentsFileController(deps = {}) {
15
15
  CLAUDE_MD_FILE_NAME,
16
16
  readOpenclawAgentsFile,
17
17
  readOpenclawWorkspaceFile,
18
+ OPENCODE_CONFIG_DIR,
18
19
  backupPromptBeforeWrite
19
20
  } = deps;
20
21
 
@@ -33,6 +34,7 @@ function createAgentsFileController(deps = {}) {
33
34
  if (typeof CLAUDE_MD_FILE_NAME !== 'string' || !CLAUDE_MD_FILE_NAME) throw new Error('createAgentsFileController 缺少 CLAUDE_MD_FILE_NAME');
34
35
  if (typeof readOpenclawAgentsFile !== 'function') throw new Error('createAgentsFileController 缺少 readOpenclawAgentsFile');
35
36
  if (typeof readOpenclawWorkspaceFile !== 'function') throw new Error('createAgentsFileController 缺少 readOpenclawWorkspaceFile');
37
+ if (typeof OPENCODE_CONFIG_DIR !== 'string' || !OPENCODE_CONFIG_DIR) throw new Error('createAgentsFileController 缺少 OPENCODE_CONFIG_DIR');
36
38
  if (typeof backupPromptBeforeWrite !== 'function' && typeof backupPromptBeforeWrite !== 'undefined') throw new Error('createAgentsFileController 备份回调无效');
37
39
 
38
40
  function resolveAgentsFilePath(params = {}) {
@@ -236,7 +238,9 @@ function createAgentsFileController(deps = {}) {
236
238
  }
237
239
  let agentsHistoryBucket = '';
238
240
  if (typeof backupPromptBeforeWrite === 'function') {
239
- const bucket = 'codex_' + sanitizeHistoryId(String(params.baseDir || '').trim() || 'global');
241
+ const explicitBucket = typeof params.historyBucket === 'string' ? params.historyBucket.trim() : '';
242
+ const bucket = explicitBucket
243
+ || ('codex_' + sanitizeHistoryId(String(params.baseDir || '').trim() || 'global'));
240
244
  backupPromptBeforeWrite(bucket, filePath);
241
245
  agentsHistoryBucket = bucket;
242
246
  }
@@ -254,6 +258,43 @@ function createAgentsFileController(deps = {}) {
254
258
  }
255
259
  }
256
260
 
261
+
262
+ function readOpencodeAgentsFile(params = {}) {
263
+ const baseDir = OPENCODE_CONFIG_DIR;
264
+ const filePath = path.join(baseDir, AGENTS_FILE_NAME);
265
+ const lineEndingFallback = os.EOL === '\r\n' ? '\r\n' : '\n';
266
+
267
+ if (!fs.existsSync(baseDir)) {
268
+ return {
269
+ exists: false,
270
+ path: filePath,
271
+ content: '',
272
+ lineEnding: lineEndingFallback,
273
+ configDir: baseDir,
274
+ baseDirMissing: true
275
+ };
276
+ }
277
+
278
+ const readResult = readAgentsFile({ baseDir, metaOnly: !!params.metaOnly });
279
+ return {
280
+ ...readResult,
281
+ configDir: baseDir
282
+ };
283
+ }
284
+
285
+ function applyOpencodeAgentsFile(params = {}) {
286
+ const baseDir = OPENCODE_CONFIG_DIR;
287
+ ensureDir(baseDir);
288
+ const result = applyAgentsFile({
289
+ ...params,
290
+ baseDir,
291
+ historyBucket: 'opencode_global'
292
+ });
293
+ return {
294
+ ...result,
295
+ configDir: baseDir
296
+ };
297
+ }
257
298
  function normalizeDiffText(input) {
258
299
  const safe = typeof input === 'string' ? input : '';
259
300
  return normalizeLineEnding(stripUtf8Bom(safe), '\n');
@@ -273,6 +314,8 @@ function createAgentsFileController(deps = {}) {
273
314
  readResult = readOpenclawAgentsFile({ metaOnly });
274
315
  } else if (context === 'openclaw-workspace') {
275
316
  readResult = readOpenclawWorkspaceFile({ ...params, metaOnly });
317
+ } else if (context === 'opencode') {
318
+ readResult = readOpencodeAgentsFile({ metaOnly });
276
319
  } else if (context === 'codex') {
277
320
  readResult = readAgentsFile({ ...params, metaOnly });
278
321
  } else {
@@ -310,6 +353,8 @@ function createAgentsFileController(deps = {}) {
310
353
  applyClaudeMdFile,
311
354
  readAgentsFile,
312
355
  applyAgentsFile,
356
+ readOpencodeAgentsFile,
357
+ applyOpencodeAgentsFile,
313
358
  normalizeDiffText,
314
359
  buildAgentsDiff
315
360
  };
package/cli.js CHANGED
@@ -1190,7 +1190,8 @@ function getApiToolConfigWriteTarget(action) {
1190
1190
  ]);
1191
1191
  const opencodeWriteActions = new Set([
1192
1192
  'apply-opencode-config',
1193
- 'update-opencode-selection'
1193
+ 'update-opencode-selection',
1194
+ 'apply-opencode-agents-file'
1194
1195
  ]);
1195
1196
  const kilocodeWriteActions = new Set([
1196
1197
  'apply-kilocode-config',
@@ -2372,6 +2373,8 @@ const {
2372
2373
  applyClaudeMdFile,
2373
2374
  readAgentsFile,
2374
2375
  applyAgentsFile,
2376
+ readOpencodeAgentsFile,
2377
+ applyOpencodeAgentsFile,
2375
2378
  normalizeDiffText,
2376
2379
  buildAgentsDiff
2377
2380
  } = createAgentsFileController({
@@ -2394,7 +2397,8 @@ const {
2394
2397
  },
2395
2398
  readOpenclawWorkspaceFile() {
2396
2399
  return readOpenclawWorkspaceFile(...arguments);
2397
- }
2400
+ },
2401
+ OPENCODE_CONFIG_DIR
2398
2402
  });
2399
2403
 
2400
2404
  const {
@@ -13694,6 +13698,12 @@ function createWebServer({ htmlPath, assetsDir, webDir, host, port, openBrowser
13694
13698
  case 'get-openclaw-agents-file':
13695
13699
  result = readOpenclawAgentsFile();
13696
13700
  break;
13701
+ case 'get-opencode-agents-file':
13702
+ result = readOpencodeAgentsFile(params || {});
13703
+ break;
13704
+ case 'apply-opencode-agents-file':
13705
+ result = applyOpencodeAgentsFile(params || {});
13706
+ break;
13697
13707
  case 'apply-openclaw-agents-file':
13698
13708
  result = applyOpenclawAgentsFile(params || {});
13699
13709
  break;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codexmate",
3
- "version": "0.1.20",
3
+ "version": "0.1.21",
4
4
  "description": "Codex/Claude Code/OpenClaw 配置、会话与任务编排 CLI + Web 工具",
5
5
  "main": "cli.js",
6
6
  "bin": {
@@ -33,6 +33,9 @@ function resolveAgentsHistoryBucket(instance) {
33
33
  const projectPath = (instance.projectClaudeMdPath || '').trim();
34
34
  return 'claude-project_' + sanitizePromptHistoryId(projectPath || 'global');
35
35
  }
36
+ if (subTab === 'opencode') {
37
+ return 'opencode_global';
38
+ }
36
39
  return 'codex_global';
37
40
  }
38
41
 
@@ -216,6 +219,13 @@ export function createAgentsMethods(options = {}) {
216
219
  this.agentsModalHint = tr('modal.agents.hint.openclawWorkspaceFile', `Workspace / ${fileName}`, { fileName });
217
220
  return;
218
221
  }
222
+ if (context === 'opencode') {
223
+ this.agentsContext = 'opencode';
224
+ this.agentsWorkspaceFileName = '';
225
+ this.agentsModalTitle = tr('modal.agents.title.opencode', 'OpenCode AGENTS.md 编辑器');
226
+ this.agentsModalHint = tr('modal.agents.hint.opencode', '保存后会写入 ~/.config/opencode/AGENTS.md。');
227
+ return;
228
+ }
219
229
  this.agentsContext = context === 'openclaw' ? 'openclaw' : 'codex';
220
230
  if (this.agentsContext === 'openclaw') {
221
231
  this.agentsModalTitle = tr('modal.agents.title.openclaw', 'OpenClaw AGENTS.md 编辑器');
@@ -700,6 +710,8 @@ export function createAgentsMethods(options = {}) {
700
710
  }
701
711
  } else if (this.agentsContext === 'openclaw') {
702
712
  action = 'apply-openclaw-agents-file';
713
+ } else if (this.agentsContext === 'opencode') {
714
+ action = 'apply-opencode-agents-file';
703
715
  } else if (this.agentsContext === 'openclaw-workspace') {
704
716
  action = 'apply-openclaw-workspace-file';
705
717
  params.fileName = this.agentsWorkspaceFileName;
@@ -716,7 +728,11 @@ export function createAgentsMethods(options = {}) {
716
728
  ? this.t('toast.agents.saved.workspace', { name: this.agentsWorkspaceFileName || '' }).replace(/:\s*$/, '')
717
729
  : (this.agentsContext === 'claude-project'
718
730
  ? this.t('toast.agents.saved.claudeProject')
719
- : (this.agentsContext === 'openclaw' ? this.t('toast.agents.saved.openclaw') : this.t('toast.agents.saved.agents')));
731
+ : (this.agentsContext === 'openclaw'
732
+ ? this.t('toast.agents.saved.openclaw')
733
+ : (this.agentsContext === 'opencode'
734
+ ? this.t('toast.agents.saved.opencode')
735
+ : this.t('toast.agents.saved.agents'))));
720
736
  this.showMessage(successLabel, 'success');
721
737
  if (this.mainTab === 'prompts') {
722
738
  this.loadPromptsContent();
@@ -987,7 +1003,7 @@ export function createAgentsMethods(options = {}) {
987
1003
  },
988
1004
 
989
1005
  switchPromptsSubTab(subTab) {
990
- const normalized = subTab === 'claude-project' || subTab === 'system' ? subTab : 'codex';
1006
+ const normalized = subTab === 'claude-project' || subTab === 'system' || subTab === 'opencode' ? subTab : 'codex';
991
1007
  if (normalized === 'claude-project' && !this.projectPathOptions.length && !this.projectPathOptionsLoading) {
992
1008
  this.loadProjectPathOptions();
993
1009
  }
@@ -1035,6 +1051,8 @@ export function createAgentsMethods(options = {}) {
1035
1051
  if (projectPath) {
1036
1052
  rpcParams.baseDir = projectPath;
1037
1053
  }
1054
+ } else if (subTab === 'opencode') {
1055
+ action = 'get-opencode-agents-file';
1038
1056
  } else {
1039
1057
  action = 'get-agents-file';
1040
1058
  }
@@ -1051,7 +1069,7 @@ export function createAgentsMethods(options = {}) {
1051
1069
  this.agentsPath = res.path || '';
1052
1070
  this.agentsExists = !!res.exists;
1053
1071
  this.agentsLineEnding = res.lineEnding === '\r\n' ? '\r\n' : '\n';
1054
- this.agentsContext = subTab === 'claude-project' ? 'claude-project' : 'codex';
1072
+ this.agentsContext = subTab === 'claude-project' ? 'claude-project' : (subTab === 'opencode' ? 'opencode' : 'codex');
1055
1073
  } catch (e) {
1056
1074
  if (!isLatestRequestToken(this, '_agentsOpenRequestToken', requestToken)) {
1057
1075
  return;
@@ -63,6 +63,7 @@ function normalizePromptsSubTab(value) {
63
63
  const normalized = typeof value === 'string' ? value.trim().toLowerCase() : '';
64
64
  if (normalized === 'claude-project') return normalized;
65
65
  if (normalized === 'system') return normalized;
66
+ if (normalized === 'opencode') return normalized;
66
67
  return 'codex';
67
68
  }
68
69
 
@@ -229,6 +229,7 @@ const en = Object.freeze({
229
229
  'subtitle.settings': 'Manage downloads, directories, and trash.',
230
230
  'subtitle.prompts': 'Edit AGENTS.md and CLAUDE.md.',
231
231
  'prompts.subTab.codex': 'AGENTS.md (Codex)',
232
+ 'prompts.subTab.opencode': 'AGENTS.md (OpenCode)',
232
233
  'prompts.subTab.project': 'CLAUDE.md',
233
234
  'prompts.subTab.system': 'System Prompt (Pi)',
234
235
  'prompts.subTab.presets': 'Preset pool',
@@ -439,6 +440,7 @@ const en = Object.freeze({
439
440
  'toast.agents.saved.agents': 'AGENTS.md saved',
440
441
  'toast.agents.saved.claudeProject': 'Project CLAUDE.md saved',
441
442
  'toast.agents.saved.openclaw': 'OpenClaw AGENTS.md saved',
443
+ 'toast.agents.saved.opencode': 'OpenCode AGENTS.md saved',
442
444
  'toast.agents.saved.workspace': 'Workspace file saved: {name}',
443
445
  'toast.delete.ok': 'Deleted',
444
446
  'toast.delete.fail': 'Delete failed',
@@ -961,6 +963,7 @@ const en = Object.freeze({
961
963
  'config.agents.open': 'Open AGENTS.md',
962
964
  'modal.agents.title.default': 'AGENTS.md editor',
963
965
  'modal.agents.title.openclaw': 'OpenClaw AGENTS.md editor',
966
+ 'modal.agents.title.opencode': 'OpenCode AGENTS.md editor',
964
967
  'modal.agents.hint.default': 'Saved content will be written to AGENTS.md (next to config.toml).',
965
968
  'modal.agents.title.claudeProject': 'Project CLAUDE.md: {path}',
966
969
  'modal.agents.hint.claudeProject': 'Saved content will be written to CLAUDE.md in: {path}',
@@ -969,6 +972,7 @@ const en = Object.freeze({
969
972
  'modal.agents.contentLabel.claudeProject': 'CLAUDE.md content',
970
973
  'modal.agents.placeholder.claudeProject': 'Edit CLAUDE.md here',
971
974
  'modal.agents.hint.openclaw': 'Saved content will be written to OpenClaw workspace AGENTS.md.',
975
+ 'modal.agents.hint.opencode': 'Saved content will be written to ~/.config/opencode/AGENTS.md.',
972
976
  'modal.agents.title.openclawWorkspaceFile': 'OpenClaw workspace file: {fileName}',
973
977
  'modal.agents.hint.openclawWorkspaceFile': 'Saved content will be written to OpenClaw workspace {fileName}.',
974
978
  'config.url.unset': 'URL not set',
@@ -230,6 +230,7 @@ const ja = Object.freeze({
230
230
  'subtitle.settings': 'ダウンロード・ディレクトリ・ゴミ箱の管理。',
231
231
  'subtitle.prompts': 'AGENTS.md と CLAUDE.md を編集。',
232
232
  'prompts.subTab.codex': 'AGENTS.md (Codex)',
233
+ 'prompts.subTab.opencode': 'AGENTS.md (OpenCode)',
233
234
  'prompts.subTab.project': 'CLAUDE.md',
234
235
  'prompts.subTab.system': 'System Prompt (Pi)',
235
236
  'prompts.subTab.presets': 'プリセット',
@@ -441,6 +442,7 @@ const ja = Object.freeze({
441
442
  'toast.agents.saved.agents': 'AGENTS.md 保存しました',
442
443
  'toast.agents.saved.claudeProject': 'プロジェクト CLAUDE.md 保存しました',
443
444
  'toast.agents.saved.openclaw': 'OpenClaw AGENTS.md 保存しました',
445
+ 'toast.agents.saved.opencode': 'OpenCode AGENTS.md 保存しました',
444
446
  'toast.agents.saved.workspace': 'ワークスペースファイル保存済み: {name}',
445
447
  'toast.delete.ok': '削除しました',
446
448
  'toast.delete.fail': '削除に失敗しました',
@@ -964,6 +966,7 @@ const ja = Object.freeze({
964
966
  'config.agents.open': 'AGENTS.md を開く',
965
967
  'modal.agents.title.default': 'AGENTS.md エディタ',
966
968
  'modal.agents.title.openclaw': 'OpenClaw AGENTS.md エディタ',
969
+ 'modal.agents.title.opencode': 'OpenCode AGENTS.md エディタ',
967
970
  'modal.agents.hint.default': '保存すると対象の AGENTS.md(config.toml と同階層)に書き込まれます。',
968
971
  'modal.agents.title.claudeProject': 'プロジェクト CLAUDE.md: {path}',
969
972
  'modal.agents.hint.claudeProject': '保存するとプロジェクトの CLAUDE.md に書き込まれます: {path}',
@@ -972,6 +975,7 @@ const ja = Object.freeze({
972
975
  'modal.agents.contentLabel.claudeProject': 'CLAUDE.md 内容',
973
976
  'modal.agents.placeholder.claudeProject': 'CLAUDE.md を編集',
974
977
  'modal.agents.hint.openclaw': '保存すると OpenClaw Workspace の AGENTS.md に書き込まれます。',
978
+ 'modal.agents.hint.opencode': '保存すると ~/.config/opencode/AGENTS.md に書き込まれます。',
975
979
  'modal.agents.title.openclawWorkspaceFile': 'OpenClaw ワークスペースファイル: {fileName}',
976
980
  'modal.agents.hint.openclawWorkspaceFile': '保存すると OpenClaw Workspace の {fileName} に書き込まれます。',
977
981
  'config.url.unset': 'URL 未設定',
@@ -247,6 +247,7 @@ const vi = Object.freeze({
247
247
  'subtitle.settings': 'Quản lý tải xuống, thư mục và dữ liệu.',
248
248
  'subtitle.prompts': 'Chỉnh sửa AGENTS.md và CLAUDE.md.',
249
249
  'prompts.subTab.codex': 'AGENTS.md (Codex)',
250
+ 'prompts.subTab.opencode': 'AGENTS.md (OpenCode)',
250
251
  'prompts.subTab.project': 'CLAUDE.md',
251
252
  'prompts.subTab.system': 'System Prompt (Pi)',
252
253
  'prompts.subTab.presets': 'Kho preset',
@@ -401,6 +402,7 @@ const vi = Object.freeze({
401
402
  'toast.agents.saved.agents': 'AGENTS.md đã lưu',
402
403
  'toast.agents.saved.claudeProject': 'CLAUDE.md dự án đã lưu',
403
404
  'toast.agents.saved.openclaw': 'OpenClaw AGENTS.md đã lưu',
405
+ 'toast.agents.saved.opencode': 'OpenCode AGENTS.md đã lưu',
404
406
  'toast.agents.saved.workspace': 'Tệp workspace đã lưu: {name}',
405
407
  'toast.delete.ok': 'Đã xóa',
406
408
  'toast.delete.fail': 'Xóa thất bại',
@@ -1073,8 +1075,10 @@ const vi = Object.freeze({
1073
1075
  'config.agents.open': 'Mở AGENTS.md',
1074
1076
  'modal.agents.title.default': 'Trình soạn thảo AGENTS.md',
1075
1077
  'modal.agents.title.openclaw': 'Trình soạn thảo AGENTS.md OpenClaw',
1078
+ 'modal.agents.title.opencode': 'Trình soạn thảo AGENTS.md OpenCode',
1076
1079
  'modal.agents.hint.default': 'Nội dung đã lưu sẽ được ghi vào AGENTS.md (cạnh config.toml).',
1077
1080
  'modal.agents.hint.openclaw': 'Nội dung đã lưu sẽ được ghi vào AGENTS.md không gian làm việc OpenClaw.',
1081
+ 'modal.agents.hint.opencode': 'Nội dung đã lưu sẽ được ghi vào ~/.config/opencode/AGENTS.md.',
1078
1082
  'modal.agents.title.openclawWorkspaceFile': 'File không gian làm việc OpenClaw: {fileName}',
1079
1083
  'modal.agents.hint.openclawWorkspaceFile': 'Nội dung đã lưu sẽ được ghi vào OpenClaw {fileName}.',
1080
1084
  'config.url.unset': 'URL chưa đặt',
@@ -229,6 +229,7 @@ const zhTw = Object.freeze({
229
229
  'subtitle.settings': '管理下載、目錄與回收站。',
230
230
  'subtitle.prompts': '編輯 AGENTS.md 與 CLAUDE.md。',
231
231
  'prompts.subTab.codex': 'AGENTS.md (Codex)',
232
+ 'prompts.subTab.opencode': 'AGENTS.md (OpenCode)',
232
233
  'prompts.subTab.project': 'CLAUDE.md',
233
234
  'prompts.subTab.system': 'System Prompt (Pi)',
234
235
  'prompts.subTab.presets': '預設池',
@@ -439,6 +440,7 @@ const zhTw = Object.freeze({
439
440
  'toast.agents.saved.agents': 'AGENTS.md 已保存',
440
441
  'toast.agents.saved.claudeProject': '專案 CLAUDE.md 已保存',
441
442
  'toast.agents.saved.openclaw': 'OpenClaw AGENTS.md 已保存',
443
+ 'toast.agents.saved.opencode': 'OpenCode AGENTS.md 已保存',
442
444
  'toast.agents.saved.workspace': '工作區文件已保存: {name}',
443
445
  'toast.delete.ok': '已刪除',
444
446
  'toast.delete.fail': '刪除失敗',
@@ -960,6 +962,7 @@ const zhTw = Object.freeze({
960
962
  'config.agents.open': '打開 AGENTS.md',
961
963
  'modal.agents.title.default': 'AGENTS.md 編輯器',
962
964
  'modal.agents.title.openclaw': 'OpenClaw AGENTS.md 編輯器',
965
+ 'modal.agents.title.opencode': 'OpenCode AGENTS.md 編輯器',
963
966
  'modal.agents.hint.default': '保存後會寫入目標 AGENTS.md(與 config.toml 同級)。',
964
967
  'modal.agents.title.claudeProject': '專案 CLAUDE.md: {path}',
965
968
  'modal.agents.hint.claudeProject': '保存後會寫入專案目錄下的 CLAUDE.md: {path}',
@@ -968,6 +971,7 @@ const zhTw = Object.freeze({
968
971
  'modal.agents.contentLabel.claudeProject': 'CLAUDE.md 內容',
969
972
  'modal.agents.placeholder.claudeProject': '在這裡編輯 CLAUDE.md',
970
973
  'modal.agents.hint.openclaw': '保存後會寫入 OpenClaw Workspace 下的 AGENTS.md。',
974
+ 'modal.agents.hint.opencode': '儲存後會寫入 ~/.config/opencode/AGENTS.md。',
971
975
  'modal.agents.title.openclawWorkspaceFile': 'OpenClaw 工作區文件: {fileName}',
972
976
  'modal.agents.hint.openclawWorkspaceFile': '保存後會寫入 OpenClaw Workspace 下的 {fileName}。',
973
977
  'config.url.unset': '未設 URL',
@@ -229,6 +229,7 @@ const zh = Object.freeze({
229
229
  'subtitle.settings': '管理下载、目录与回收站。',
230
230
  'subtitle.prompts': '编辑 AGENTS.md 与 CLAUDE.md。',
231
231
  'prompts.subTab.codex': 'AGENTS.md (Codex)',
232
+ 'prompts.subTab.opencode': 'AGENTS.md (OpenCode)',
232
233
  'prompts.subTab.project': 'CLAUDE.md',
233
234
  'prompts.subTab.system': 'System Prompt (Pi)',
234
235
  'prompts.subTab.presets': '预设池',
@@ -439,6 +440,7 @@ const zh = Object.freeze({
439
440
  'toast.agents.saved.agents': 'AGENTS.md 已保存',
440
441
  'toast.agents.saved.claudeProject': '项目 CLAUDE.md 已保存',
441
442
  'toast.agents.saved.openclaw': 'OpenClaw AGENTS.md 已保存',
443
+ 'toast.agents.saved.opencode': 'OpenCode AGENTS.md 已保存',
442
444
  'toast.agents.saved.workspace': '工作区文件已保存: {name}',
443
445
  'toast.delete.ok': '已删除',
444
446
  'toast.delete.fail': '删除失败',
@@ -960,6 +962,7 @@ const zh = Object.freeze({
960
962
  'config.agents.open': '打开 AGENTS.md',
961
963
  'modal.agents.title.default': 'AGENTS.md 编辑器',
962
964
  'modal.agents.title.openclaw': 'OpenClaw AGENTS.md 编辑器',
965
+ 'modal.agents.title.opencode': 'OpenCode AGENTS.md 编辑器',
963
966
  'modal.agents.hint.default': '保存后会写入目标 AGENTS.md(与 config.toml 同级)。',
964
967
  'modal.agents.title.claudeProject': '项目 CLAUDE.md: {path}',
965
968
  'modal.agents.hint.claudeProject': '保存后会写入项目目录下的 CLAUDE.md: {path}',
@@ -968,6 +971,7 @@ const zh = Object.freeze({
968
971
  'modal.agents.contentLabel.claudeProject': 'CLAUDE.md 内容',
969
972
  'modal.agents.placeholder.claudeProject': '在这里编辑 CLAUDE.md',
970
973
  'modal.agents.hint.openclaw': 'Workspace / AGENTS.md',
974
+ 'modal.agents.hint.opencode': '保存后会写入 ~/.config/opencode/AGENTS.md。',
971
975
  'modal.agents.title.openclawWorkspaceFile': 'OpenClaw 工作区文件: {fileName}',
972
976
  'modal.agents.hint.openclawWorkspaceFile': 'Workspace / {fileName}',
973
977
  'config.url.unset': '未设 URL',
@@ -7,6 +7,7 @@
7
7
  aria-labelledby="tab-prompts">
8
8
  <div class="prompts-md-tabs" role="tablist" :aria-label="t('tab.prompts')">
9
9
  <button type="button" :class="['prompts-md-tab', { active: promptsSubTab === 'codex' }]" role="tab" :aria-selected="promptsSubTab === 'codex'" @click="switchPromptsSubTab('codex')">{{ t('prompts.subTab.codex') }}</button>
10
+ <button type="button" :class="['prompts-md-tab', { active: promptsSubTab === 'opencode' }]" role="tab" :aria-selected="promptsSubTab === 'opencode'" @click="switchPromptsSubTab('opencode')">{{ t('prompts.subTab.opencode') }}</button>
10
11
  <button type="button" :class="['prompts-md-tab', { active: promptsSubTab === 'claude-project' }]" role="tab" :aria-selected="promptsSubTab === 'claude-project'" @click="switchPromptsSubTab('claude-project')">{{ t('prompts.subTab.project') }}</button>
11
12
  <button type="button" :class="['prompts-md-tab', { active: promptsSubTab === 'system' }]" role="tab" :aria-selected="promptsSubTab === 'system'" @click="switchPromptsSubTab('system')">{{ t('prompts.subTab.system') }}</button>
12
13
  </div>
@@ -6882,6 +6882,13 @@ return function render(_ctx, _cache) {
6882
6882
  "aria-selected": _ctx.promptsSubTab === 'codex',
6883
6883
  onClick: $event => (_ctx.switchPromptsSubTab('codex'))
6884
6884
  }, _toDisplayString(_ctx.t('prompts.subTab.codex')), 11 /* TEXT, CLASS, PROPS */, ["aria-selected", "onClick"]),
6885
+ _createElementVNode("button", {
6886
+ type: "button",
6887
+ class: _normalizeClass(['prompts-md-tab', { active: _ctx.promptsSubTab === 'opencode' }]),
6888
+ role: "tab",
6889
+ "aria-selected": _ctx.promptsSubTab === 'opencode',
6890
+ onClick: $event => (_ctx.switchPromptsSubTab('opencode'))
6891
+ }, _toDisplayString(_ctx.t('prompts.subTab.opencode')), 11 /* TEXT, CLASS, PROPS */, ["aria-selected", "onClick"]),
6885
6892
  _createElementVNode("button", {
6886
6893
  type: "button",
6887
6894
  class: _normalizeClass(['prompts-md-tab', { active: _ctx.promptsSubTab === 'claude-project' }]),