@shuind/dsh-codex-harness 0.1.23 → 0.1.24

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
@@ -13,12 +13,12 @@
13
13
  - **Responses 原生 apply_patch**:在 GPT Responses 请求的插件传输边界,把普通 JSON function tool 改写为 `type: "custom"` + OpenAI `lark` grammar;下一轮历史同步改写为 `custom_tool_call`。如果中转站拒绝 custom tool,则自动回退到普通 function tool,不改变 DSH 工具执行器。
14
14
  - **远程搜索与压缩**:OpenAI Responses 请求默认优先使用 hosted `web_search` 和 `/responses/compact`;失败时回退到 DSH 的本地实现。
15
15
  - **上下文容量**:在 Web 中设置 `1K`–`1000K` tokens,设置值作用于下一次请求。
16
- - **活动状态**:Codex 等待模型响应或进行上下文压缩时,在输入框上方显示对应状态和耗时,让长时间 Deep Diving 不再像卡住。
16
+ - **活动状态**:Codex 等待模型响应或进行上下文压缩时,在 `Deep diving...` 右侧显示对应状态和耗时,让长时间 Deep Diving 不再像卡住。
17
17
 
18
18
  ## 安装
19
19
 
20
20
  ```sh
21
- dsh plugin --profile web add @shuind/dsh-codex-harness@0.1.23
21
+ dsh plugin --profile web add @shuind/dsh-codex-harness@0.1.24
22
22
  ```
23
23
 
24
24
  重启 Web,创建新会话,在模式菜单中选择 **Codex 模式**。
@@ -63,9 +63,14 @@ Codex 等待模型首个输出时,Web 会在 `Deep diving...` 右侧显示 `
63
63
 
64
64
  ## 随包提供的 Codex preset
65
65
 
66
- 安装插件后,首次启动对应的 DSH profile 时,插件会把完整 preset 从随包提供的 `presets/codex` 安装到 `${DSH_HOME:-$HOME/.dsh}/.agent-presets/codex/`;如果你已经创建了同名 preset,插件会保留你的文件。普通用户不需要自己创建 preset。
66
+ 安装插件后,首次启动对应的 DSH profile 时,插件会安装两套随包提供的 preset
67
67
 
68
- Web 的 **Agent 预设** 中选择 **Codex**,再新建会话即可使用随包提供的 Codex 工具、网页搜索、远程压缩和 Skills 组合。Fast、思考强度、GPT 图片输入和上下文容量可以在对应的设置位置配置。
68
+ - **Codex 模式**:使用精简版 Codex 提示词。
69
+ - **Codex 协作模式**:在精简版 Codex 提示词后追加协作提示词。
70
+
71
+ 它们分别位于 `${DSH_HOME:-$HOME/.dsh}/.agent-presets/codex/` 和 `${DSH_HOME:-$HOME/.dsh}/.agent-presets/codex-collaboration/`。如果对应目录已经存在,插件会保留你的文件,不会覆盖自定义内容。
72
+
73
+ 在 Web 的 **Agent 预设** 中选择 **Codex 模式** 或 **Codex 协作模式**,再新建会话即可使用随包提供的 Codex 工具、网页搜索、远程压缩和 Skills 组合。两套 preset 共用 Fast、思考强度、GPT 图片输入和上下文容量设置;只有系统提示词是否包含协作指导不同。
69
74
 
70
75
  ## 自定义 preset
71
76
 
package/lib/client.js CHANGED
@@ -13,6 +13,11 @@ window.__ModuleLoader__.load({
13
13
  /** User-selectable Codex context controls use whole K-token units. */
14
14
  const CODEX_CONTEXT_UNIT = 1e3;
15
15
  const CODEX_CONTEXT_MAX = 1e6;
16
+ const CODEX_PRESET_IDS = /* @__PURE__ */ new Set(["codex", "codex-collaboration"]);
17
+ /** Both shipped presets use the same Codex request controls in Web. */
18
+ function isCodexPresetId(value) {
19
+ return value !== void 0 && CODEX_PRESET_IDS.has(value);
20
+ }
16
21
  //#endregion
17
22
  //#region lib/types/client/activity.js
18
23
  /** Client-only inference used while the host activity projection frame is in flight. */
@@ -63,7 +68,7 @@ window.__ModuleLoader__.load({
63
68
  const agentPreset = useSessions((state) => state.byId[sessionId]?.agentPreset);
64
69
  const snapshot = useSettings((state) => state);
65
70
  const fast = snapshot.value?.fast ?? false;
66
- if (agentPreset !== "codex") return null;
71
+ if (!isCodexPresetId(agentPreset)) return null;
67
72
  return (0, react_jsx_runtime.jsxs)("button", {
68
73
  type: "button",
69
74
  role: "menuitemcheckbox",
@@ -108,7 +113,7 @@ window.__ModuleLoader__.load({
108
113
  const agentPreset = useSessions((state) => state.byId[sessionId]?.agentPreset);
109
114
  const snapshot = useSettings((state) => state);
110
115
  const fast = snapshot.value?.fast ?? false;
111
- if (agentPreset !== "codex") return null;
116
+ if (!isCodexPresetId(agentPreset)) return null;
112
117
  return (0, react_jsx_runtime.jsxs)("button", {
113
118
  type: "button",
114
119
  role: "switch",
@@ -279,20 +284,20 @@ window.__ModuleLoader__.load({
279
284
  const agentPreset = useSessions((state) => state.byId[sessionId]?.agentPreset);
280
285
  const projectedActivity = useProjection("codexActivity");
281
286
  const fallbackStartedAt = useSession((snapshot) => awaitingModelStartedAt(snapshot));
282
- const activity = projectedActivity !== void 0 ? projectedActivity : agentPreset === "codex" && fallbackStartedAt !== void 0 ? {
287
+ const activity = projectedActivity !== void 0 ? projectedActivity : isCodexPresetId(agentPreset) && fallbackStartedAt !== void 0 ? {
283
288
  activity: "awaiting-model",
284
289
  startedAt: fallbackStartedAt
285
290
  } : null;
286
291
  const [now, setNow] = (0, react.useState)(() => Date.now());
287
292
  (0, react.useEffect)(() => {
288
- if (agentPreset !== "codex" || activity === void 0 || activity === null) return void 0;
293
+ if (!isCodexPresetId(agentPreset) || activity === void 0 || activity === null) return void 0;
289
294
  setNow(Date.now());
290
295
  const timer = setInterval(() => {
291
296
  setNow(Date.now());
292
297
  }, 1e3);
293
298
  return () => clearInterval(timer);
294
299
  }, [agentPreset, activity?.startedAt]);
295
- if (agentPreset !== "codex" || activity === void 0 || activity === null) return null;
300
+ if (!isCodexPresetId(agentPreset) || activity === void 0 || activity === null) return null;
296
301
  const label = activity.activity === "awaiting-model" ? t("activityAwaitingModel") : t("activityCompacting");
297
302
  return (0, react_jsx_runtime.jsxs)("span", {
298
303
  id: "codex-activity",
package/lib/installer.js CHANGED
@@ -4,9 +4,9 @@ import { dirname, join, resolve } from "node:path";
4
4
  import { fileURLToPath } from "node:url";
5
5
  //#region lib/types/installer.js
6
6
  /** Install the user-visible Codex agent preset supplied by this bundle. */
7
- const PRESET_ID = "codex";
8
7
  const PRESET_FILES = ["agent.cordis.yml", "preset.yml"];
9
8
  const SOURCE_PRESET_DIR = fileURLToPath(new URL("../presets/codex/", import.meta.url));
9
+ const SOURCE_COLLABORATION_PRESET_DIR = fileURLToPath(new URL("../presets/codex-collaboration/", import.meta.url));
10
10
  function dshHomePath(...segments) {
11
11
  const configured = process.env.DSH_HOME?.trim();
12
12
  const expanded = configured === void 0 || configured.length === 0 ? join(homedir(), ".dsh") : configured === "~" ? homedir() : configured.startsWith("~/") || configured.startsWith("~\\") ? join(homedir(), configured.slice(2)) : configured;
@@ -14,21 +14,11 @@ function dshHomePath(...segments) {
14
14
  }
15
15
  /** Bundle plugin name for the preset installer. */
16
16
  const name = "codex-preset-installer";
17
- /**
18
- * Install the shipped Codex preset only when the user has not authored one.
19
- *
20
- * The directory is committed with a staging rename so a failed copy cannot
21
- * leave a half-written preset that hides the mode from the roster. Existing
22
- * directories are intentionally preserved, including user customizations.
23
- *
24
- * @param targetDir - destination preset directory.
25
- * @param sourceDir - directory containing the packaged preset files.
26
- */
27
- function installCodexPreset(targetDir = dshHomePath(".agent-presets", PRESET_ID), sourceDir = SOURCE_PRESET_DIR) {
17
+ function installPreset(targetDir, sourceDir, presetId) {
28
18
  if (existsSync(targetDir)) return;
29
19
  const parentDir = dirname(targetDir);
30
20
  mkdirSync(parentDir, { recursive: true });
31
- const stagingDir = mkdtempSync(join(parentDir, `.${PRESET_ID}-`));
21
+ const stagingDir = mkdtempSync(join(parentDir, `.${presetId}-`));
32
22
  try {
33
23
  for (const file of PRESET_FILES) copyFileSync(join(sourceDir, file), join(stagingDir, file));
34
24
  try {
@@ -43,12 +33,30 @@ function installCodexPreset(targetDir = dshHomePath(".agent-presets", PRESET_ID)
43
33
  });
44
34
  }
45
35
  }
36
+ /**
37
+ * Install the shipped Codex preset only when the user has not authored one.
38
+ *
39
+ * The directory is committed with a staging rename so a failed copy cannot
40
+ * leave a half-written preset that hides the mode from the roster. Existing
41
+ * directories are intentionally preserved, including user customizations.
42
+ *
43
+ * @param targetDir - destination preset directory.
44
+ * @param sourceDir - directory containing the packaged preset files.
45
+ */
46
+ function installCodexPreset(targetDir = dshHomePath(".agent-presets", "codex"), sourceDir = SOURCE_PRESET_DIR) {
47
+ installPreset(targetDir, sourceDir, "codex");
48
+ }
49
+ /** Install the shipped Codex preset with the optional collaboration guidance enabled. */
50
+ function installCodexCollaborationPreset(targetDir = dshHomePath(".agent-presets", "codex-collaboration"), sourceDir = SOURCE_COLLABORATION_PRESET_DIR) {
51
+ installPreset(targetDir, sourceDir, "codex-collaboration");
52
+ }
46
53
  /** Install the preset during profile boot without changing the host tool catalog. */
47
54
  function apply(ctx) {
48
55
  try {
49
56
  installCodexPreset();
57
+ installCodexCollaborationPreset();
50
58
  } catch (error) {
51
- ctx.logger.warn(`dsh-codex: could not install the Codex preset: ${String(error)}`);
59
+ ctx.logger.warn(`dsh-codex: could not install the Codex presets: ${String(error)}`);
52
60
  }
53
61
  }
54
62
  var installer_default = {
@@ -56,4 +64,4 @@ var installer_default = {
56
64
  apply
57
65
  };
58
66
  //#endregion
59
- export { apply, installer_default as default, installCodexPreset, name };
67
+ export { apply, installer_default as default, installCodexCollaborationPreset, installCodexPreset, name };
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  /** Browser controls for the Codex request settings mounted by the Host plugin. */
3
3
  import { useEffect, useState } from 'react';
4
- import { CODEX_CONTEXT_MAX, CODEX_CONTEXT_UNIT, CODEX_PRESET_ID } from "../context.js";
4
+ import { CODEX_CONTEXT_MAX, CODEX_CONTEXT_UNIT, isCodexPresetId } from "../context.js";
5
5
  import { awaitingModelStartedAt } from "./activity.js";
6
6
  const NS = 'codex';
7
7
  const SETTINGS_NAMESPACE = 'codex';
@@ -42,7 +42,7 @@ function FastModeButton({ sessionId, useSessions, useSettings, setSetting, t })
42
42
  const agentPreset = useSessions(state => state.byId[sessionId]?.agentPreset);
43
43
  const snapshot = useSettings(state => state);
44
44
  const fast = snapshot.value?.fast ?? false;
45
- if (agentPreset !== CODEX_PRESET_ID)
45
+ if (!isCodexPresetId(agentPreset))
46
46
  return null;
47
47
  return (_jsxs("button", { type: "button", role: "menuitemcheckbox", disabled: snapshot.writable === false, "aria-pressed": fast, "aria-label": fast ? t('fastOn') : t('fastOff'), title: fast ? t('fastOn') : t('fastOff'), onClick: () => { void setSetting('fast', !fast); }, style: {
48
48
  boxSizing: 'border-box',
@@ -70,7 +70,7 @@ function FastModeFallback(props) {
70
70
  const agentPreset = useSessions(state => state.byId[sessionId]?.agentPreset);
71
71
  const snapshot = useSettings(state => state);
72
72
  const fast = snapshot.value?.fast ?? false;
73
- if (agentPreset !== CODEX_PRESET_ID)
73
+ if (!isCodexPresetId(agentPreset))
74
74
  return null;
75
75
  return (_jsxs("button", { type: "button", role: "switch", disabled: snapshot.writable === false, "aria-checked": fast, "aria-label": fast ? t('fastOn') : t('fastOff'), title: fast ? t('fastOn') : t('fastOff'), onClick: () => { void setSetting('fast', !fast); }, style: {
76
76
  boxSizing: 'border-box',
@@ -149,18 +149,18 @@ export function ActivityLine({ sessionId, useSession, useSessions, useProjection
149
149
  const fallbackStartedAt = useSession((snapshot) => awaitingModelStartedAt(snapshot));
150
150
  // `undefined` means the key has not arrived yet; `null` is an authoritative
151
151
  // clear and must not be resurrected by the local snapshot fallback.
152
- const activity = projectedActivity !== undefined ? projectedActivity : (agentPreset === CODEX_PRESET_ID && fallbackStartedAt !== undefined
152
+ const activity = projectedActivity !== undefined ? projectedActivity : (isCodexPresetId(agentPreset) && fallbackStartedAt !== undefined
153
153
  ? { activity: 'awaiting-model', startedAt: fallbackStartedAt }
154
154
  : null);
155
155
  const [now, setNow] = useState(() => Date.now());
156
156
  useEffect(() => {
157
- if (agentPreset !== CODEX_PRESET_ID || activity === undefined || activity === null)
157
+ if (!isCodexPresetId(agentPreset) || activity === undefined || activity === null)
158
158
  return undefined;
159
159
  setNow(Date.now());
160
160
  const timer = setInterval(() => { setNow(Date.now()); }, 1_000);
161
161
  return () => clearInterval(timer);
162
162
  }, [agentPreset, activity?.startedAt]);
163
- if (agentPreset !== CODEX_PRESET_ID || activity === undefined || activity === null)
163
+ if (!isCodexPresetId(agentPreset) || activity === undefined || activity === null)
164
164
  return null;
165
165
  const label = activity.activity === 'awaiting-model'
166
166
  ? t('activityAwaitingModel')
@@ -2,4 +2,7 @@
2
2
  export declare const CODEX_CONTEXT_UNIT = 1000;
3
3
  export declare const CODEX_CONTEXT_MAX = 1000000;
4
4
  export declare const CODEX_PRESET_ID = "codex";
5
+ export declare const CODEX_COLLABORATION_PRESET_ID = "codex-collaboration";
6
+ /** Both shipped presets use the same Codex request controls in Web. */
7
+ export declare function isCodexPresetId(value: string | undefined): boolean;
5
8
  //# sourceMappingURL=context.d.ts.map
@@ -2,4 +2,13 @@
2
2
  export const CODEX_CONTEXT_UNIT = 1_000;
3
3
  export const CODEX_CONTEXT_MAX = 1_000_000;
4
4
  export const CODEX_PRESET_ID = 'codex';
5
+ export const CODEX_COLLABORATION_PRESET_ID = 'codex-collaboration';
6
+ const CODEX_PRESET_IDS = new Set([
7
+ CODEX_PRESET_ID,
8
+ CODEX_COLLABORATION_PRESET_ID,
9
+ ]);
10
+ /** Both shipped presets use the same Codex request controls in Web. */
11
+ export function isCodexPresetId(value) {
12
+ return value !== undefined && CODEX_PRESET_IDS.has(value);
13
+ }
5
14
  //# sourceMappingURL=context.js.map
@@ -13,6 +13,8 @@ export declare const name = "codex-preset-installer";
13
13
  * @param sourceDir - directory containing the packaged preset files.
14
14
  */
15
15
  export declare function installCodexPreset(targetDir?: string, sourceDir?: string): void;
16
+ /** Install the shipped Codex preset with the optional collaboration guidance enabled. */
17
+ export declare function installCodexCollaborationPreset(targetDir?: string, sourceDir?: string): void;
16
18
  /** Install the preset during profile boot without changing the host tool catalog. */
17
19
  export declare function apply(ctx: Context): void;
18
20
  declare const _default: {
@@ -3,9 +3,9 @@ import { copyFileSync, existsSync, mkdirSync, mkdtempSync, renameSync, rmSync }
3
3
  import { homedir } from 'node:os';
4
4
  import { dirname, join, resolve } from 'node:path';
5
5
  import { fileURLToPath } from 'node:url';
6
- const PRESET_ID = 'codex';
7
6
  const PRESET_FILES = ['agent.cordis.yml', 'preset.yml'];
8
7
  const SOURCE_PRESET_DIR = fileURLToPath(new URL('../presets/codex/', import.meta.url));
8
+ const SOURCE_COLLABORATION_PRESET_DIR = fileURLToPath(new URL('../presets/codex-collaboration/', import.meta.url));
9
9
  function dshHomePath(...segments) {
10
10
  const configured = process.env.DSH_HOME?.trim();
11
11
  const expanded = configured === undefined || configured.length === 0
@@ -19,22 +19,12 @@ function dshHomePath(...segments) {
19
19
  }
20
20
  /** Bundle plugin name for the preset installer. */
21
21
  export const name = 'codex-preset-installer';
22
- /**
23
- * Install the shipped Codex preset only when the user has not authored one.
24
- *
25
- * The directory is committed with a staging rename so a failed copy cannot
26
- * leave a half-written preset that hides the mode from the roster. Existing
27
- * directories are intentionally preserved, including user customizations.
28
- *
29
- * @param targetDir - destination preset directory.
30
- * @param sourceDir - directory containing the packaged preset files.
31
- */
32
- export function installCodexPreset(targetDir = dshHomePath('.agent-presets', PRESET_ID), sourceDir = SOURCE_PRESET_DIR) {
22
+ function installPreset(targetDir, sourceDir, presetId) {
33
23
  if (existsSync(targetDir))
34
24
  return;
35
25
  const parentDir = dirname(targetDir);
36
26
  mkdirSync(parentDir, { recursive: true });
37
- const stagingDir = mkdtempSync(join(parentDir, `.${PRESET_ID}-`));
27
+ const stagingDir = mkdtempSync(join(parentDir, `.${presetId}-`));
38
28
  try {
39
29
  for (const file of PRESET_FILES)
40
30
  copyFileSync(join(sourceDir, file), join(stagingDir, file));
@@ -51,13 +41,31 @@ export function installCodexPreset(targetDir = dshHomePath('.agent-presets', PRE
51
41
  rmSync(stagingDir, { recursive: true, force: true });
52
42
  }
53
43
  }
44
+ /**
45
+ * Install the shipped Codex preset only when the user has not authored one.
46
+ *
47
+ * The directory is committed with a staging rename so a failed copy cannot
48
+ * leave a half-written preset that hides the mode from the roster. Existing
49
+ * directories are intentionally preserved, including user customizations.
50
+ *
51
+ * @param targetDir - destination preset directory.
52
+ * @param sourceDir - directory containing the packaged preset files.
53
+ */
54
+ export function installCodexPreset(targetDir = dshHomePath('.agent-presets', 'codex'), sourceDir = SOURCE_PRESET_DIR) {
55
+ installPreset(targetDir, sourceDir, 'codex');
56
+ }
57
+ /** Install the shipped Codex preset with the optional collaboration guidance enabled. */
58
+ export function installCodexCollaborationPreset(targetDir = dshHomePath('.agent-presets', 'codex-collaboration'), sourceDir = SOURCE_COLLABORATION_PRESET_DIR) {
59
+ installPreset(targetDir, sourceDir, 'codex-collaboration');
60
+ }
54
61
  /** Install the preset during profile boot without changing the host tool catalog. */
55
62
  export function apply(ctx) {
56
63
  try {
57
64
  installCodexPreset();
65
+ installCodexCollaborationPreset();
58
66
  }
59
67
  catch (error) {
60
- ctx.logger.warn(`dsh-codex: could not install the Codex preset: ${String(error)}`);
68
+ ctx.logger.warn(`dsh-codex: could not install the Codex presets: ${String(error)}`);
61
69
  }
62
70
  }
63
71
  export default { name, apply };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shuind/dsh-codex-harness",
3
- "version": "0.1.23",
3
+ "version": "0.1.24",
4
4
  "description": "A Codex harness with a streamlined system prompt for GPT models that do not fit DSH's native interface, while remaining compatible with the DSH plugin ecosystem.",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -35,6 +35,7 @@
35
35
  "lib/client.js",
36
36
  "cordis.patch.yml",
37
37
  "presets/codex",
38
+ "presets/codex-collaboration",
38
39
  "README.md",
39
40
  "README.zh.md",
40
41
  "LICENSE"
@@ -0,0 +1,91 @@
1
+ # The Codex collaboration preset. It shares the standard Codex composition
2
+ # while enabling the optional collaboration guidance in the prompt layer.
3
+
4
+ - id: persona
5
+ name: '@deepseek-ai/dsh-persona'
6
+ config:
7
+ # Keep identity, model, cwd, and runtime context in one persona section.
8
+ text: >-
9
+ You are Codex, a coding agent based on the {{model}} model. Your working directory is {{cwd}}.
10
+ includeRuntimeContext: true
11
+
12
+ - id: agent-instructions
13
+ name: '@deepseek-ai/dsh-agent-instructions'
14
+ config:
15
+ maxBytes: 65536
16
+
17
+ # The collaboration variant only changes this flag; execution remains
18
+ # delegated to the same dsh Codex tool layer.
19
+ - id: codex-tools
20
+ name: '@shuind/dsh-codex-harness'
21
+ config:
22
+ collaborationPrompt: true
23
+
24
+ # Background jobs use the host-plane registry. A busy agent receives a
25
+ # completion in its next step; an idle agent keeps it pending until the next
26
+ # user/tool wake, so finishing work never opens an unsolicited model turn.
27
+ - id: codex-jobs
28
+ name: '@deepseek-ai/dsh-tool-jobs'
29
+ config:
30
+ completionDelivery: quiet
31
+
32
+ # The generic DSH pi-ai adapter still owns the user's configured provider,
33
+ # endpoint, API key, and model. Codex's remote-first transport wrapper is
34
+ # installed only in this Codex scope and falls back to the generic DSH path.
35
+
36
+ # Keep the local tool mounted as the fallback. Codex rewrites the final GPT
37
+ # Responses request to a hosted web_search tool first; a failed remote request
38
+ # is retried through this unchanged local function-tool path.
39
+ - id: codex-web-search
40
+ name: '@deepseek-ai/dsh-tool-web'
41
+ config:
42
+ search: true
43
+ fetch: false
44
+
45
+ # PTY execution is optional. Pipe-backed exec_command remains available on all
46
+ # platforms through the shell capability consumed by the Codex tool layer.
47
+ - id: codex-terminal
48
+ name: cordis:group
49
+ group: true
50
+ isolate:
51
+ terminals: true
52
+ config:
53
+ - id: terminals
54
+ name: '@deepseek-ai/dsh-terminal'
55
+
56
+ - id: terminal-bash
57
+ name: '@deepseek-ai/dsh-terminal-bash'
58
+ disabled: !!js process.platform === 'win32'
59
+ config:
60
+ timeoutMs: 300000
61
+
62
+ # Context compaction is agent-scoped in Web. The token meter stays on the host
63
+ # plane, while this group owns the backend, `/compact`, and optional tool-result
64
+ # pruning for Codex sessions.
65
+ - id: compaction
66
+ name: cordis:group
67
+ group: true
68
+ isolate:
69
+ compaction: true
70
+ toolResultPruner: true
71
+ config:
72
+ - id: compaction-basic
73
+ name: '@deepseek-ai/dsh-compaction-basic'
74
+
75
+ - id: command-compact
76
+ name: '@deepseek-ai/dsh-command-compact'
77
+
78
+ - id: tool-result-pruner
79
+ name: '@deepseek-ai/dsh-compaction-tool-result-pruner'
80
+ config:
81
+ thresholdChars: 8192
82
+ headChars: 4096
83
+ tailChars: 1024
84
+
85
+ # Skills are the dsh extensibility seam and do not change the four Codex core
86
+ # tool names.
87
+ - id: skill-filesystem
88
+ name: '@deepseek-ai/dsh-skill-filesystem'
89
+
90
+ - id: tool-skill
91
+ name: '@deepseek-ai/dsh-tool-skill'
@@ -0,0 +1,3 @@
1
+ name: Codex 协作模式
2
+ description: 使用精简版 Codex 提示词,并加入协作提示词、统一执行工具、后台任务控制和 dsh Skills。
3
+ order: 6