dsh-plugin-prompt-tool 0.5.0 → 0.6.0

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.
Files changed (37) hide show
  1. package/README.md +18 -12
  2. package/engine/anchor-match.mjs +117 -0
  3. package/engine/compositions/library/context-gate.yml +2 -2
  4. package/engine/compositions/library/delegation.yml +2 -2
  5. package/engine/compositions/library/str-replace-editor.yml +1 -1
  6. package/engine/compositions/library/tool-bootstrap.yml +2 -2
  7. package/engine/compositions/library/tool-filter.yml +3 -3
  8. package/engine/compositions/source/local/context-gate.yml +2 -2
  9. package/engine/compositions/source/local/tool-bootstrap.yml +3 -3
  10. package/engine/executor.mjs +9 -2
  11. package/engine/interpolate.mjs +66 -0
  12. package/engine/layers.mjs +26 -22
  13. package/engine/schema.mjs +18 -0
  14. package/engine/session-vars.mjs +52 -0
  15. package/engine/shared.mjs +0 -19
  16. package/engine/strategies.mjs +28 -38
  17. package/lib/client.js +471 -162
  18. package/lib/client.js.map +1 -1
  19. package/lib/index.d.mts +35 -9
  20. package/lib/index.mjs +376 -92
  21. package/lib/preset-core.d.mts +2 -2
  22. package/lib/preset-core.mjs +3 -6
  23. package/lib/{prompt-configs-BcP6miu9.d.mts → prompt-configs-B4vH09wx.d.mts} +1 -3
  24. package/lib/{prompt-configs-k7wuZs0C.mjs → prompt-configs-ThS4iXPg.mjs} +85 -33
  25. package/package.json +105 -104
  26. package/preset/anchored/preset.yml +40 -42
  27. package/preset/creative/preset.yml +33 -30
  28. package/preset/creative/skills/cordis-plugin-development/SKILL.md +420 -0
  29. package/preset/creative/skills/editing-cordis-compositions/SKILL.md +165 -0
  30. package/preset/liangshen/preset.yml +24 -18
  31. package/preset/minimal/preset.yml +27 -24
  32. package/preset/ptc/preset.yml +23 -17
  33. package/preset/standard/preset.yml +23 -17
  34. package/templates/20-system-section.yml +5 -0
  35. package/engine/compositions/library/router-first-turn.yml +0 -9
  36. package/engine/compositions/source/local/router-first-turn.yml +0 -5
  37. package/engine/router-first-turn.mjs +0 -85
@@ -1,8 +1,8 @@
1
- import { a as mergePromptConfigs, i as loadPromptConfigFiles, n as PromptConfigFile, o as renderPromptConfigYaml, r as PromptConfigSpec, t as BuildCordisOptions } from "./prompt-configs-BcP6miu9.mjs";
1
+ import { a as mergePromptConfigs, i as loadPromptConfigFiles, n as PromptConfigFile, o as renderPromptConfigYaml, r as PromptConfigSpec, t as BuildCordisOptions } from "./prompt-configs-B4vH09wx.mjs";
2
2
  //#region src/preset-core.d.ts
3
3
  /**
4
4
  * 渲染 anchored 组合文件:
5
- * agent.cordis.yml 是模板自带完整组合(含 router-first-turn 与 prompt-config-engine 行),
5
+ * agent.cordis.yml 是模板自带完整组合(含 prompt-config-engine 行),
6
6
  * 动态值全部由 preset.yml 的 variables 声明为 __TOKEN__;本函数只做变量替换 + YAML 校验。
7
7
  */
8
8
  declare function buildCordis(prompt: string, options?: BuildCordisOptions): string;
@@ -1,4 +1,4 @@
1
- import { n as mergePromptConfigs, o as assertCompositionArray, p as loadPresetSpec, r as renderPromptConfigYaml, t as loadPromptConfigFiles, v as renderComposition } from "./prompt-configs-k7wuZs0C.mjs";
1
+ import { n as mergePromptConfigs, o as assertCompositionArray, p as loadPresetSpec, r as renderPromptConfigYaml, t as loadPromptConfigFiles, y as renderComposition } from "./prompt-configs-ThS4iXPg.mjs";
2
2
  import { fileURLToPath } from "node:url";
3
3
  //#region src/preset-core.ts
4
4
  /**
@@ -9,7 +9,7 @@ import { fileURLToPath } from "node:url";
9
9
  const ANCHORED_TEMPLATE_DIR = fileURLToPath(new URL("../preset/anchored/", import.meta.url));
10
10
  /**
11
11
  * 渲染 anchored 组合文件:
12
- * agent.cordis.yml 是模板自带完整组合(含 router-first-turn 与 prompt-config-engine 行),
12
+ * agent.cordis.yml 是模板自带完整组合(含 prompt-config-engine 行),
13
13
  * 动态值全部由 preset.yml 的 variables 声明为 __TOKEN__;本函数只做变量替换 + YAML 校验。
14
14
  */
15
15
  function buildCordis(prompt, options = {}) {
@@ -38,15 +38,12 @@ function buildCordis(prompt, options = {}) {
38
38
  toolFilterAllow: options.toolFilterAllow,
39
39
  toolFilterDeny: options.toolFilterDeny,
40
40
  maxDepth: options.maxDepth,
41
- mainPersona: typeof options.mainPersona === "string" && options.mainPersona.trim().length > 0 ? options.mainPersona : void 0,
42
41
  allowKinds: options.allowKinds,
43
42
  firstTurnWord: typeof options.firstTurnWord === "string" && options.firstTurnWord.length > 0 ? options.firstTurnWord : void 0
44
43
  };
45
44
  const out = renderComposition(spec, runtime, ANCHORED_TEMPLATE_DIR);
46
45
  const parsed = assertCompositionArray(out, spec);
47
- const ids = new Set(parsed.map((row) => row?.id));
48
- if (!ids.has("router-first-turn")) throw new Error("generated agent.cordis.yml is missing the router-first-turn row");
49
- if (!ids.has("prompt-config-engine")) throw new Error("generated agent.cordis.yml is missing the prompt-config-engine row");
46
+ if (!new Set(parsed.map((row) => row?.id)).has("prompt-config-engine")) throw new Error("generated agent.cordis.yml is missing the prompt-config-engine row");
50
47
  if (parsed.find((row) => row?.id === "prompt-config-engine")?.config?.configsDir !== "../prompt-configs") throw new Error("generated agent.cordis.yml prompt-config-engine row must point configsDir at ../prompt-configs");
51
48
  return out;
52
49
  }
@@ -73,7 +73,7 @@ interface BuildCordisOptions {
73
73
  subagentTemperature?: string;
74
74
  /** 子代理输出上限(agent-request patch,audience=subagent;''=不设置)。 */
75
75
  subagentMaxTokens?: string;
76
- /** 子代理自定义模型人设(per-child shadow;缺省回退 mainPersona,两者缺省=继承主会话)。 */
76
+ /** 子代理自定义模型人设(per-child shadow;缺省 = 经 scope 链继承主会话 persona 模块)。 */
77
77
  subagentPersona?: string;
78
78
  /** 委派工具集白名单(toolFilter.allow;支持数组或逗号/空格分隔字符串)。 */
79
79
  toolFilterAllow?: string[] | string;
@@ -81,8 +81,6 @@ interface BuildCordisOptions {
81
81
  toolFilterDeny?: string[] | string;
82
82
  /** 委派递归深度上限(0 禁止委派 / provider-managed / 正整数)。 */
83
83
  maxDepth?: number | 'provider-managed';
84
- /** 主对话自定义模型人设(覆盖 preset.yml mainPersona 默认)。 */
85
- mainPersona?: string;
86
84
  /** 注入 kind 白名单(context-gate allowKinds;数组或逗号分隔字符串)。 */
87
85
  allowKinds?: string[] | string;
88
86
  /** custom-fallback 锚定词(prompt-injector params.firstTurnWord)。 */
@@ -1,4 +1,4 @@
1
- import { cpSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from "node:fs";
1
+ import { cpSync, existsSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, writeFileSync } from "node:fs";
2
2
  import { Pair, Scalar, YAMLMap, YAMLSeq, parse, parseDocument } from "yaml";
3
3
  import { basename, dirname, join, resolve, sep } from "node:path";
4
4
  import { spawn } from "node:child_process";
@@ -178,12 +178,44 @@ function listBuiltinTemplates() {
178
178
  return [];
179
179
  }
180
180
  }
181
- /** 首次启动种子化:把插件目录全部内置模板复制到预设根(.pt-seeded 标记后不再自动补)。
182
- * 用户删除的预设不会自动复活;升级新增的模板用「新建」按需复制。 */
181
+ /** 插件状态文件(DSH_HOME 下,预设根之外):与用户资产解耦,删除/备份/迁移预设根不影响状态。
182
+ * 原子写(tmp+rename),避免半写文件。 */
183
+ function stateFilePath() {
184
+ return join(DSH_HOME, ".prompt-tool-state.json");
185
+ }
186
+ /** 读插件状态;文件缺失/损坏返回空对象(按未标记处理,触发首次动作)。 */
187
+ function readPluginState() {
188
+ try {
189
+ const parsed = JSON.parse(readFileSync(stateFilePath(), "utf8"));
190
+ return parsed !== null && typeof parsed === "object" ? parsed : {};
191
+ } catch {
192
+ return {};
193
+ }
194
+ }
195
+ /** 原子写插件状态(tmp+rename)。 */
196
+ function writePluginState(state) {
197
+ const file = stateFilePath();
198
+ const tmp = `${file}.tmp`;
199
+ writeFileSync(tmp, JSON.stringify(state, null, 2), "utf8");
200
+ renameSync(tmp, file);
201
+ }
202
+ /** 首次启动种子化:把插件目录全部内置模板复制到预设根(state.seeded 后不再自动补)。
203
+ * 用户删除的预设不会自动复活;升级新增的模板用「新建」按需复制。
204
+ * 兼容旧版预设根内 .pt-seeded 标记:存在即视为已种子化,并迁入状态文件后删除。 */
183
205
  function ensurePresetSeed() {
184
206
  const root = userPresetsDir();
185
- const mark = join(root, ".pt-seeded");
186
- if (existsSync(mark)) return { created: [] };
207
+ const legacyMark = join(root, ".pt-seeded");
208
+ const state = readPluginState();
209
+ if (state.seeded === true || existsSync(legacyMark)) {
210
+ if (existsSync(legacyMark)) try {
211
+ writePluginState({
212
+ ...state,
213
+ seeded: true
214
+ });
215
+ rmSync(legacyMark, { force: true });
216
+ } catch {}
217
+ return { created: [] };
218
+ }
187
219
  const created = [];
188
220
  try {
189
221
  mkdirSync(root, { recursive: true });
@@ -194,7 +226,10 @@ function ensurePresetSeed() {
194
226
  cpSync(join(packagePresetDir(), entry.name), target, { recursive: true });
195
227
  created.push(entry.name);
196
228
  }
197
- writeFileSync(mark, "", "utf8");
229
+ writePluginState({
230
+ ...readPluginState(),
231
+ seeded: true
232
+ });
198
233
  } catch {}
199
234
  return { created };
200
235
  }
@@ -327,15 +362,40 @@ function openPresetLocation(id, presetRoot = userPresetsDir()) {
327
362
  * (保留 preset.yml 模板默认)。写入后删除 prompt-tool.overrides.yml(旧参数覆盖
328
363
  * 通道残留——参数已并入 preset.yml,避免旧值覆盖新值)。
329
364
  */
330
- function savePresetParams(presetRoot, templateName, params, promptConfigs) {
365
+ function savePresetParams(presetRoot, templateName, params, promptConfigs, variables, variablesEnabled) {
331
366
  const file = join(presetRoot, templateName, "preset.yml");
332
367
  if (!existsSync(file)) throw new Error(`preset ${templateName} 无 preset.yml`);
333
368
  const doc = parseDocument(readFileSync(file, "utf8"), { logLevel: "silent" });
334
369
  if (params !== void 0) for (const [key, value] of Object.entries(params)) {
335
- if (value === void 0 || value === null) continue;
370
+ if (value === void 0 || value === null || key.trim().length === 0) continue;
336
371
  doc.setIn(["params", key], value);
337
372
  }
338
- if (promptConfigs !== void 0) doc.setIn(["promptConfigs"], promptConfigs);
373
+ if (promptConfigs !== void 0) {
374
+ const cleaned = promptConfigs.map((config) => {
375
+ if (config === null || typeof config !== "object" || Array.isArray(config)) return config;
376
+ const vars = config.variables;
377
+ if (vars === null || typeof vars !== "object" || Array.isArray(vars)) return config;
378
+ const kept = Object.fromEntries(Object.entries(vars).filter(([key]) => key.trim().length > 0));
379
+ const next = { ...config };
380
+ if (Object.keys(kept).length > 0) next.variables = kept;
381
+ else delete next.variables;
382
+ return next;
383
+ });
384
+ doc.setIn(["promptConfigs"], cleaned);
385
+ }
386
+ if (variables !== void 0) {
387
+ const kept = Object.fromEntries(Object.entries(variables).filter(([key, value]) => key.trim().length > 0 && typeof value === "string"));
388
+ if (Object.keys(kept).length > 0) doc.setIn(["variables"], kept);
389
+ else doc.deleteIn(["variables"]);
390
+ for (const [key, value] of Object.entries(variables)) {
391
+ if (typeof value !== "string") continue;
392
+ doc.deleteIn(["params", key]);
393
+ }
394
+ }
395
+ if (variablesEnabled !== void 0) {
396
+ if (variablesEnabled) doc.deleteIn(["variablesEnabled"]);
397
+ else doc.setIn(["variablesEnabled"], false);
398
+ }
339
399
  writeFileSync(file, doc.toString(), "utf8");
340
400
  rmSync(join(presetRoot, templateName, "prompt-tool.overrides.yml"), { force: true });
341
401
  }
@@ -386,22 +446,17 @@ function normalizeParam(value) {
386
446
  if (value === "off") return false;
387
447
  return value;
388
448
  }
389
- /** camelCase → SCREAMING_SNAKE_CASE(usePtcMode → USE_PTC_MODE)。 */
390
- function upperKey(key) {
391
- return key.replace(/([a-z0-9])([A-Z])/g, "$1_$2").toUpperCase();
392
- }
393
449
  /** 预设 params(默认参数)与运行时 settings 合并;settings 值优先。 */
394
450
  function resolvePresetParams(spec, runtime) {
395
451
  const params = {};
396
452
  for (const [key, value] of Object.entries(spec.params ?? {})) params[key] = normalizeParam(value);
397
453
  for (const [key, value] of Object.entries(runtime)) if (value !== void 0) params[key] = value;
398
454
  if (typeof params.promptText !== "string" || params.promptText.length === 0) params.promptText = typeof runtime.promptText === "string" ? runtime.promptText : "";
399
- for (const key of Object.keys(params)) params[upperKey(key)] = params[key];
400
455
  return params;
401
456
  }
402
- /** {{key}} 嵌套插值(块模板内引用 params)。 */
457
+ /** {{key}} 嵌套插值(块模板内引用 params);键正则与引擎插值及 processStText 中文变量支持一致。 */
403
458
  function interpolateNested(text, scope) {
404
- return text.replace(/\{\{([A-Za-z0-9_.-]+)\}\}/g, (whole, key, offset) => {
459
+ return text.replace(/\{\{([A-Za-z0-9_.\u4e00-\u9fff-]+)\}\}/g, (whole, key, offset) => {
405
460
  if (!Object.prototype.hasOwnProperty.call(scope, key)) return whole;
406
461
  const value = asString(scope[key]);
407
462
  if (!value.includes("\n")) return value;
@@ -426,10 +481,9 @@ function parseListParam(value) {
426
481
  * 与官方 AgentOptions{provider,model} / toolFilter{allow,deny} / maxDepth 对齐。
427
482
  */
428
483
  function renderEngineTokens(params) {
429
- const mainPersona = asString(params.mainPersona);
430
484
  const provider = asString(params.subagentModelProvider, "");
431
485
  const model = asString(params.subagentModelName, "");
432
- const subagentPersona = asString(params.subagentPersona) || (provider.length > 0 && model.length > 0 ? mainPersona : "");
486
+ const subagentPersona = asString(params.subagentPersona);
433
487
  const toolFilterAllow = parseListParam(params.toolFilterAllow);
434
488
  const toolFilterDeny = parseListParam(params.toolFilterDeny);
435
489
  const mainFilterAllow = parseListParam(params.toolFilterAllow);
@@ -452,15 +506,14 @@ function renderEngineTokens(params) {
452
506
  const bootstrap = typeof params.bootstrapMaxTokens === "number" && params.bootstrapMaxTokens > 0 ? `bootstrapMaxTokens: ${params.bootstrapMaxTokens}` : "";
453
507
  const editorMaxOutputChars = typeof params.strReplaceEditorMaxOutputChars === "number" && Number.isSafeInteger(params.strReplaceEditorMaxOutputChars) && params.strReplaceEditorMaxOutputChars > 0 ? String(params.strReplaceEditorMaxOutputChars) : "16000";
454
508
  return {
455
- USE_PTC_MODE: params.usePtcMode === true ? "true" : "false",
456
- BOOTSTRAP_MAX_TOKENS: bootstrap,
457
- MAIN_PERSONA: JSON.stringify(mainPersona).slice(1, -1),
458
- SUBAGENT_CONFIG: subagentConfigBlock,
459
- ALLOW_KINDS: params.allowKinds === void 0 ? "" : Array.isArray(params.allowKinds) ? `[${params.allowKinds.map((item) => String(item)).join(", ")}]` : asString(params.allowKinds),
460
- STR_REPLACE_EDITOR_MAX_OUTPUT_CHARS: editorMaxOutputChars,
461
- MAIN_TOOL_FILTER_ALLOW: mainFilterAllowLine,
462
- MAIN_TOOL_FILTER_DENY: mainFilterDenyLine,
463
- MAIN_TOOL_FILTER_SUBAGENTS: String(mainFilterSubagents)
509
+ usePtcMode: params.usePtcMode === void 0 ? "" : params.usePtcMode === true ? "true" : "false",
510
+ bootstrapMaxTokens: bootstrap,
511
+ subagentConfig: subagentConfigBlock,
512
+ allowKinds: params.allowKinds === void 0 ? "" : Array.isArray(params.allowKinds) ? `[${params.allowKinds.map((item) => String(item)).join(", ")}]` : asString(params.allowKinds),
513
+ strReplaceEditorMaxOutputChars: editorMaxOutputChars,
514
+ mainToolFilterAllow: mainFilterAllowLine,
515
+ mainToolFilterDeny: mainFilterDenyLine,
516
+ mainToolFilterSubagents: String(mainFilterSubagents)
464
517
  };
465
518
  }
466
519
  /** 预设 params + runtime → 组合 token 渲染(便捷入口)。 */
@@ -470,12 +523,10 @@ function resolvePresetTokens(spec, runtime) {
470
523
  /** 按参数文件的 modules 清单从引擎模块库装配组合文本。 */
471
524
  /** 空模块清单兜底骨架(自定义预设空白起点:模块集与 minimal 一致,参数/配置全空)。 */
472
525
  const FALLBACK_MODULES = [
473
- "persona",
474
526
  "official-persistent-shell",
475
527
  "bootstrap-filesystem",
476
528
  "context-gate",
477
529
  "tool-bootstrap",
478
- "router-first-turn",
479
530
  "prompt-config-engine",
480
531
  "run-code-env",
481
532
  "custom-bash",
@@ -578,7 +629,7 @@ function renderComposition(spec, runtime, templateDir) {
578
629
  }
579
630
  /** 组合文本基础校验(模板无关):无未解析 token,且必须是 YAML 数组。 */
580
631
  function assertCompositionArray(raw, spec) {
581
- const unresolved = raw.match(/__[A-Z0-9_]+__/g);
632
+ const unresolved = raw.match(/__[A-Za-z0-9_]+__/g);
582
633
  if (unresolved !== null) throw new Error(`generated agent.cordis.yml has unresolved variables: ${unresolved.join(", ")}`);
583
634
  const parsed = parse(raw, { logLevel: "silent" });
584
635
  if (!Array.isArray(parsed)) throw new Error(`generated agent.cordis.yml is not a YAML array (preset ${spec.id})`);
@@ -590,8 +641,8 @@ function assertCompositionArray(raw, spec) {
590
641
  * - token 内联时直接替换(用于布尔/字符串标量)。
591
642
  */
592
643
  function renderTemplateVariables(raw, variables) {
593
- let text = raw.replace(/^[ \t]*(?:[A-Za-z0-9_.-]+:[ \t]*)?__([A-Z0-9_]+)__[ \t]*\r?\n/gm, (whole, key) => Object.prototype.hasOwnProperty.call(variables, key) && variables[key] === "" ? "" : whole);
594
- return text.replace(/__([A-Z0-9_]+)__/g, (whole, key, offset) => {
644
+ let text = raw.replace(/^[ \t]*(?:[A-Za-z0-9_.-]+:[ \t]*)?__([A-Za-z0-9_]+)__[ \t]*\r?\n/gm, (whole, key) => Object.prototype.hasOwnProperty.call(variables, key) && variables[key] === "" ? "" : whole);
645
+ return text.replace(/__([A-Za-z0-9_]+)__/g, (whole, key, offset) => {
595
646
  if (!Object.prototype.hasOwnProperty.call(variables, key)) return whole;
596
647
  const value = variables[key];
597
648
  if (value === "") return "";
@@ -707,6 +758,7 @@ function loadPromptConfigFiles(dir) {
707
758
  const specs = [];
708
759
  const files = entries.filter((entry) => entry.isFile() && /\.(ya?ml|json)$/i.test(entry.name)).sort((a, b) => a.name.localeCompare(b.name));
709
760
  for (const entry of files) {
761
+ if (entry.name === "variables.yml") continue;
710
762
  const raw = readFileSync(join(dir, entry.name), "utf8");
711
763
  const parsed = /\.json$/i.test(entry.name) ? JSON.parse(raw) : parse(raw, { logLevel: "silent" });
712
764
  if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) throw new Error(`prompt config file ${entry.name} must contain a single config object`);
@@ -716,4 +768,4 @@ function loadPromptConfigFiles(dir) {
716
768
  return specs;
717
769
  }
718
770
  //#endregion
719
- export { DEFAULT_PRESET_DIR as C, LEGACY_USER_PRESETS_DIR as D, LEGACY_CONTAINER_DIR as E, userPresetsDir as S, DEFAULT_SKILLS_DIR as T, removeUserPreset as _, asString as a, resolvePresetParams as b, duplicateUserPreset as c, listPresets as d, loadPresetContent as f, parseImportedPresetId as g, packageEngineDir as h, applyModuleConfigs as i, ensurePresetSeed as l, openPresetLocation as m, mergePromptConfigs as n, assertCompositionArray as o, loadPresetSpec as p, renderPromptConfigYaml as r, cloneBuiltinPreset as s, loadPromptConfigFiles as t, listBuiltinTemplates as u, renderComposition as v, DEFAULT_RESIDENT_AGENTS_PATH as w, savePresetParams as x, resolvePresetDir as y };
771
+ export { userPresetsDir as C, DEFAULT_SKILLS_DIR as D, DEFAULT_RESIDENT_AGENTS_PATH as E, LEGACY_CONTAINER_DIR as O, savePresetParams as S, DEFAULT_PRESET_DIR as T, readPluginState as _, asString as a, resolvePresetDir as b, duplicateUserPreset as c, listPresets as d, loadPresetContent as f, parseImportedPresetId as g, packageEngineDir as h, applyModuleConfigs as i, LEGACY_USER_PRESETS_DIR as k, ensurePresetSeed as l, openPresetLocation as m, mergePromptConfigs as n, assertCompositionArray as o, loadPresetSpec as p, renderPromptConfigYaml as r, cloneBuiltinPreset as s, loadPromptConfigFiles as t, listBuiltinTemplates as u, removeUserPreset as v, writePluginState as w, resolvePresetParams as x, renderComposition as y };
package/package.json CHANGED
@@ -1,104 +1,105 @@
1
- {
2
- "name": "dsh-plugin-prompt-tool",
3
- "version": "0.5.0",
4
- "description": "DSH 插件:提示词工具,规范模型的思维链与回答内容,提供 Web UI 编辑 preset.md 与 AGENTS.md,并按 skills 目录注册可开关技能。",
5
- "license": "MIT",
6
- "repository": {
7
- "type": "git",
8
- "url": "git+https://github.com/Czerror/dsh-plugin-prompt-tool.git"
9
- },
10
- "type": "module",
11
- "main": "lib/index.mjs",
12
- "types": "lib/index.d.mts",
13
- "exports": {
14
- ".": {
15
- "types": "./lib/index.d.mts",
16
- "default": "./lib/index.mjs"
17
- },
18
- "./client": "./lib/client.js",
19
- "./package.json": "./package.json"
20
- },
21
- "engines": {
22
- "node": ">=20"
23
- },
24
- "dsh": {
25
- "bundle": {
26
- "patch": "./cordis.patch.yml",
27
- "requires": [
28
- "@deepseek-ai/dsh-web-app"
29
- ]
30
- },
31
- "client": {
32
- "inject": [
33
- "@deepseek-ai/dsh-client-runtime",
34
- "@deepseek-ai/dsh-client-connection",
35
- "@deepseek-ai/dsh-client-ui-settings"
36
- ],
37
- "platform": "web"
38
- }
39
- },
40
- "peerDependencies": {
41
- "@deepseek-ai/cordis": "^4.0.1",
42
- "@deepseek-ai/dsh-api-remotes": "^0.1.1-rc.1",
43
- "@deepseek-ai/dsh-client-connection": "^0.1.1-rc.1",
44
- "@deepseek-ai/dsh-client-runtime": "^0.1.1-rc.1",
45
- "@deepseek-ai/dsh-client-ui-primitives": "^0.1.1-rc.1",
46
- "@deepseek-ai/dsh-client-ui-settings": "^0.1.1-rc.1",
47
- "@deepseek-ai/dsh-commands": "^0.1.1-rc.1",
48
- "@deepseek-ai/dsh-host-webserver": "^0.1.1-rc.1",
49
- "@deepseek-ai/dsh-settings": "^0.1.1-rc.1",
50
- "@deepseek-ai/dsh-skill": "^0.1.1-rc.1",
51
- "@deepseek-ai/dsh-system-prompt": "^0.1.1-rc.1",
52
- "@deepseek-ai/dsh-tools": "^0.1.1-rc.2",
53
- "@deepseek-ai/schemastery": "^3.18.1",
54
- "react": "^18.2.0"
55
- },
56
- "devDependencies": {
57
- "@deepseek-ai/cordis": "^4.0.1",
58
- "@deepseek-ai/dsh-api-remotes": "^0.1.1-rc.1",
59
- "@deepseek-ai/dsh-client-connection": "^0.1.1-rc.1",
60
- "@deepseek-ai/dsh-client-runtime": "^0.1.1-rc.1",
61
- "@deepseek-ai/dsh-client-ui-primitives": "^0.1.1-rc.1",
62
- "@deepseek-ai/dsh-client-ui-settings": "^0.1.1-rc.1",
63
- "@deepseek-ai/dsh-client-ui-slots": "^0.1.1-rc.1",
64
- "@deepseek-ai/dsh-commands": "^0.1.1-rc.1",
65
- "@deepseek-ai/dsh-host-webserver": "^0.1.1-rc.1",
66
- "@deepseek-ai/dsh-settings": "^0.1.1-rc.1",
67
- "@deepseek-ai/dsh-skill": "^0.1.1-rc.1",
68
- "@deepseek-ai/dsh-tools": "^0.1.1-rc.2",
69
- "@types/node": "^26.2.0",
70
- "@types/react": "~18.3.1",
71
- "@types/react-dom": "^18.3.0",
72
- "clsx": "^2.1.1",
73
- "lightningcss": "^1.32.0",
74
- "oxlint": "^1.78.0",
75
- "react": "^18.3.1",
76
- "react-dom": "^18.3.1",
77
- "tsdown": "^0.22.2",
78
- "typescript": "^5.9.2"
79
- },
80
- "files": [
81
- "lib",
82
- "engine",
83
- "cordis.patch.yml",
84
- "LICENSE",
85
- "preset",
86
- "templates",
87
- "skills",
88
- "README.md"
89
- ],
90
- "scripts": {
91
- "build": "tsdown",
92
- "prepare": "tsdown",
93
- "typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.client.json --noEmit",
94
- "lint": "oxlint src test tsdown.config.ts",
95
- "test": "pnpm build && node --test \"test/**/*.test.mjs\"",
96
- "link:profile": "node scripts/link-profile.mjs",
97
- "sync:anchored": "node scripts/sync-anchored.mjs",
98
- "sync:yaml": "node scripts/sync-yaml-vendor.mjs",
99
- "rebuild:composition": "node scripts/rebuild-composition.mjs"
100
- },
101
- "dependencies": {
102
- "yaml": "^2.9.0"
103
- }
104
- }
1
+ {
2
+ "name": "dsh-plugin-prompt-tool",
3
+ "version": "0.6.0",
4
+ "description": "DSH 插件:提示词工具,规范模型的思维链与回答内容,提供 Web UI 编辑 preset.md 与 AGENTS.md,并按 skills 目录注册可开关技能。",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/Czerror/dsh-plugin-prompt-tool.git"
9
+ },
10
+ "type": "module",
11
+ "main": "lib/index.mjs",
12
+ "types": "lib/index.d.mts",
13
+ "exports": {
14
+ ".": {
15
+ "types": "./lib/index.d.mts",
16
+ "default": "./lib/index.mjs"
17
+ },
18
+ "./client": "./lib/client.js",
19
+ "./package.json": "./package.json"
20
+ },
21
+ "engines": {
22
+ "node": ">=20"
23
+ },
24
+ "dsh": {
25
+ "bundle": {
26
+ "patch": "./cordis.patch.yml",
27
+ "requires": [
28
+ "@deepseek-ai/dsh-web-app"
29
+ ]
30
+ },
31
+ "client": {
32
+ "inject": [
33
+ "@deepseek-ai/dsh-client-runtime",
34
+ "@deepseek-ai/dsh-client-connection",
35
+ "@deepseek-ai/dsh-client-ui-settings"
36
+ ],
37
+ "platform": "web"
38
+ }
39
+ },
40
+ "peerDependencies": {
41
+ "@deepseek-ai/cordis": "^4.0.1",
42
+ "@deepseek-ai/dsh-api-remotes": "^0.1.1-rc.1",
43
+ "@deepseek-ai/dsh-client-connection": "^0.1.1-rc.1",
44
+ "@deepseek-ai/dsh-client-runtime": "^0.1.1-rc.1",
45
+ "@deepseek-ai/dsh-client-ui-primitives": "^0.1.1-rc.1",
46
+ "@deepseek-ai/dsh-client-ui-settings": "^0.1.1-rc.1",
47
+ "@deepseek-ai/dsh-commands": "^0.1.1-rc.1",
48
+ "@deepseek-ai/dsh-host-webserver": "^0.1.1-rc.1",
49
+ "@deepseek-ai/dsh-settings": "^0.1.1-rc.1",
50
+ "@deepseek-ai/dsh-skill": "^0.1.1-rc.1",
51
+ "@deepseek-ai/dsh-system-prompt": "^0.1.1-rc.1",
52
+ "@deepseek-ai/dsh-tools": "^0.1.1-rc.2",
53
+ "@deepseek-ai/schemastery": "^3.18.1",
54
+ "react": "^18.2.0"
55
+ },
56
+ "devDependencies": {
57
+ "@deepseek-ai/cordis": "^4.0.1",
58
+ "@deepseek-ai/dsh-api-remotes": "^0.1.1-rc.1",
59
+ "@deepseek-ai/dsh-client-connection": "^0.1.1-rc.1",
60
+ "@deepseek-ai/dsh-client-runtime": "^0.1.1-rc.1",
61
+ "@deepseek-ai/dsh-client-ui-primitives": "^0.1.1-rc.1",
62
+ "@deepseek-ai/dsh-client-ui-settings": "^0.1.1-rc.1",
63
+ "@deepseek-ai/dsh-client-ui-slots": "^0.1.1-rc.1",
64
+ "@deepseek-ai/dsh-commands": "^0.1.1-rc.1",
65
+ "@deepseek-ai/dsh-host-webserver": "^0.1.1-rc.1",
66
+ "@deepseek-ai/dsh-scope": "0.0.1-rc.1",
67
+ "@deepseek-ai/dsh-settings": "^0.1.1-rc.1",
68
+ "@deepseek-ai/dsh-skill": "^0.1.1-rc.1",
69
+ "@deepseek-ai/dsh-tools": "^0.1.1-rc.2",
70
+ "@types/node": "^26.2.0",
71
+ "@types/react": "~18.3.1",
72
+ "@types/react-dom": "^18.3.0",
73
+ "clsx": "^2.1.1",
74
+ "lightningcss": "^1.32.0",
75
+ "oxlint": "^1.78.0",
76
+ "react": "^18.3.1",
77
+ "react-dom": "^18.3.1",
78
+ "tsdown": "^0.22.2",
79
+ "typescript": "^5.9.2"
80
+ },
81
+ "files": [
82
+ "lib",
83
+ "engine",
84
+ "cordis.patch.yml",
85
+ "LICENSE",
86
+ "preset",
87
+ "templates",
88
+ "skills",
89
+ "README.md"
90
+ ],
91
+ "scripts": {
92
+ "build": "tsdown",
93
+ "prepare": "tsdown",
94
+ "typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.client.json --noEmit",
95
+ "lint": "oxlint src test tsdown.config.ts",
96
+ "test": "pnpm build && node --test \"test/**/*.test.mjs\"",
97
+ "link:profile": "node scripts/link-profile.mjs",
98
+ "sync:anchored": "node scripts/sync-anchored.mjs",
99
+ "sync:yaml": "node scripts/sync-yaml-vendor.mjs",
100
+ "rebuild:composition": "node scripts/rebuild-composition.mjs"
101
+ },
102
+ "dependencies": {
103
+ "yaml": "^2.9.0"
104
+ }
105
+ }
@@ -163,21 +163,7 @@ params:
163
163
  injectPrompt: true
164
164
  usePtcMode: true
165
165
  bootstrapMaxTokens: 0
166
- # 人设·主对话自定义模型人设:主对话命中快速模型(Flash 档)时替换人设;
167
- # 子代理自定义模型人设(subagentPersona)未设置时回退使用。
168
- mainPersona: >
169
- You are a helpful assistant.
170
-
171
- Before acting, decide the task type (build or fix) and adopt the matching
172
- style: build → hands-on production; fix → inspect-and-plan.
173
-
174
- Before acting, briefly review what you have already done in this session and
175
- continue from where you left off; do not repeat completed steps. Do not run
176
- environment checks (echo, whoami, uname, node --version, date) or exhaustive
177
- grep/glob scans.
178
-
179
- Think deeply first, then produce.
180
- guideCustom: false
166
+ guideCustom: false
181
167
  guideComplexPattern: "架构|重构|全面|详细|设计|系统|优化|分析|architecture|refactor|comprehensive|detailed|design|system|optimize|analyze"
182
168
  guideWeak: "Router: classify this task (build or fix) now, then adopt the matching style — build: direct production; fix: inspect-first. Think deeply first, then commit and act."
183
169
  guideDeep: "Router: classify this task (build or fix) now, then adopt the matching style — build: direct production; fix: inspect-first. Think deeply about the architecture, edge cases, and integration points. Do not spend reasoning on the environment or tooling. Produce when your information is complete. End each reasoning block with a decision or an information need."
@@ -196,7 +182,7 @@ params:
196
182
  # subagentReasoningEffort / Temperature / MaxTokens(子代理)
197
183
  # agent-request patch(官方 LlmCallConfig;audience 区分主/子;''=不设置)
198
184
  # 人设 subagentPersona tool-subagent persona
199
- # (显式 → 固定路由回退 mainPersona → 继承主会话)
185
+ # (显式 → 继承主会话 persona(scope 链))
200
186
  # 工具集 toolFilter.allow / deny tool-subagent toolFilter{allow,deny}
201
187
  # (主会话 tool-filter 模块共用同一扁平键,作用于任意注册工具,
202
188
  # 含第三方插件工具;空列表 = 不过滤)
@@ -227,8 +213,8 @@ params:
227
213
  # 三合一结论:注入(near-anchor/router-guide/prompt-injector/instruction-hint)
228
214
  # 对子代理全部放行/跟随,故本预设全部配置缺省=公用(主会话+子代理都注入)。
229
215
  # 如需仅主会话/仅子代理,显式 audience: main / subagent 即可(配置项,不锁定)。
230
- promptConfigs:
231
- - id: near-anchor
216
+ promptConfigs:
217
+ - id: near-anchor
232
218
  name: 首句锚点
233
219
  enabled: true
234
220
  strategy: first-turn-anchor
@@ -274,24 +260,43 @@ promptConfigs:
274
260
  position: after-all
275
261
  dedupe: session
276
262
  promotion: include-subagents
277
- sourceKind: instruction-hint
278
- form: hint
279
- fill: instruction-hint
280
- legacyCleanup:
263
+ sourceKind: instruction-hint
264
+ form: hint
265
+ fill: instruction-hint
266
+ - id: persona-main
267
+ name: 主会话人设
268
+ layer: system-section
269
+ strategy: static
270
+ order: 0
271
+ params:
272
+ sectionName: deployment:persona
273
+ complete: true
274
+ suppressRuntimeContext: true
275
+ text: >-
276
+ You are a helpful assistant.
277
+
278
+ Before acting, decide the task type (build or fix) and adopt the matching
279
+ style: build → hands-on production; fix → inspect-and-plan.
280
+
281
+ Before acting, briefly review what you have already done in this session and
282
+ continue from where you left off; do not repeat completed steps. Do not run
283
+ environment checks (echo, whoami, uname, node --version, date) or exhaustive
284
+ grep/glob scans.
285
+
286
+ Think deeply first, then produce.
287
+ legacyCleanup:
281
288
  []
282
289
  upstream:
283
290
  repo: dsh-anchored-standard
284
291
  snapshot: upstream/dsh-anchored-standard
285
292
  sync: pnpm sync:anchored
286
293
  modules:
287
- - context-gate
288
- - tool-filter
289
- - tool-bootstrap
290
- - router-first-turn
291
- - prompt-config-engine
292
- - run-code-env
293
- - persona
294
- - tool-bash
294
+ - context-gate
295
+ - tool-filter
296
+ - tool-bootstrap
297
+ - prompt-config-engine
298
+ - run-code-env
299
+ - tool-bash
295
300
  - tool-pwsh
296
301
  - persistent-shell
297
302
  - custom-bash
@@ -309,20 +314,13 @@ modules:
309
314
  - tool-todo
310
315
  - tool-web
311
316
  moduleConfigs:
312
- persona:
313
- text: You are a helpful software engineer assistant.
314
- complete: true
315
- includeRuntimeContext: false
316
- custom-bash:
317
+ custom-bash:
317
318
  timeoutMs: 120000
318
319
  maxOutputBytes: 64000
319
- tool-bootstrap:
320
- includeSubagents: false
321
- promoteOn: either
322
- router-first-turn:
323
- hideSectionPrefixes: ["mnemon:"]
324
- includeSubagents: false
325
- run-code-env:
320
+ tool-bootstrap:
321
+ includeSubagents: false
322
+ promoteOn: either
323
+ run-code-env:
326
324
  envKeys: [PATH, PATHEXT, HOME, USERPROFILE, USERNAME, COMPUTERNAME, OS, TEMP, TMP, SystemRoot, ProgramFiles, ProgramFiles(x86), LOCALAPPDATA, APPDATA]
327
325
  context-gate:
328
326
  promoteOn: either