dsh-plugin-prompt-tool 0.2.0 → 0.3.1
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 +89 -64
- package/lib/client.js +129 -8
- package/lib/client.js.map +1 -1
- package/lib/index.d.mts +9 -2
- package/lib/index.mjs +57 -8
- package/lib/preset-core.d.mts +6 -2
- package/lib/preset-core.mjs +28 -9
- package/package.json +1 -1
- package/plan.md +4 -0
- package/preset/near-anchor.mjs +1 -4
- package/preset/router-first-turn.mjs +70 -59
- package/preset/router-guide.mjs +85 -0
- package/preset.md +0 -1
- package/upstream/dsh-anchored-standard/REVISION +1 -1
- package/upstream/dsh-anchored-standard/preset/agent.cordis.yml +22 -11
- package/upstream/dsh-anchored-standard/preset/custom-bash.mjs +98 -5
package/lib/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","names":["styles","IconChevronDownOutline14","useState","useRef","useCallback"],"sources":["../node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs","../src/client/PromptEditor.tsx","../src/client/index.ts"],"sourcesContent":["function r(e){var t,f,n=\"\";if(\"string\"==typeof e||\"number\"==typeof e)n+=e;else if(\"object\"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=\" \"),n+=f)}else for(f in e)e[f]&&(n&&(n+=\" \"),n+=f);return n}export function clsx(){for(var e,t,f=0,n=\"\",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=\" \"),n+=t);return n}export default clsx;","import { useCallback, useRef, useState } from 'react'\r\nimport type { ReactNode } from 'react'\r\nimport clsx from 'clsx'\r\nimport { IconChevronDownOutline14 } from '@deepseek-ai/dsh-client-ui-primitives'\r\nimport type { IApiClient } from '@deepseek-ai/dsh-client-connection/client'\r\nimport type { InjectFace, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\r\nimport type {} from '@deepseek-ai/dsh-client-ui-settings-plugins/client'\r\nimport styles from './PromptEditor.module.css'\r\n\r\nconst SETTINGS_BRIDGE_PREFIX = '/api/prompt-tool/settings'\r\n\r\ntype BridgePathOp = { op: 'set' | 'unset'; path: string[]; value?: unknown }\r\ninterface BridgeSettingsView { ns: string; value: unknown; base?: unknown; revision: number }\r\ntype BridgeResult<T> = { ok: true; value: T; deepseekAvailable?: boolean; deepseekProviders?: string[]; deepseekError?: string } | { ok: false; code?: string; message?: string }\r\n\r\nasync function bridgePost<T>(path: string, body: unknown): Promise<BridgeResult<T>> {\r\n try {\r\n const response = await fetch(SETTINGS_BRIDGE_PREFIX + path, {\r\n method: 'POST',\r\n headers: { 'content-type': 'application/json' },\r\n body: JSON.stringify(body),\r\n })\r\n const payload = await response.json() as unknown\r\n if (payload !== null && typeof payload === 'object') return payload as BridgeResult<T>\r\n return { ok: false, message: 'settings bridge unavailable' }\r\n } catch (error) {\r\n return { ok: false, message: errorMessage(error) }\r\n }\r\n}\r\n\r\nexport interface PromptEditorInjected {\r\n api: IApiClient\r\n}\r\n\r\nexport type PromptEditorProps = PropsRuntime<'settings.plugin.item'> & InjectFace<PromptEditorInjected>\r\n\r\ninterface SkillCatalogEntry {\r\n folder: string\r\n name: string\r\n description: string\r\n}\r\n\r\ninterface Fields {\r\n promptText: string\r\n promptPath: string\r\n agentsText: string\r\n agentsPath: string\r\n injectAgentsPrompt: boolean\r\n anchorFirstTurn: boolean\r\n anchorText: string\r\n anchorCustom: boolean\r\n subagentFlash: boolean\r\n injectPrompt: boolean\r\n skillSwitches: Record<string, boolean>\r\n skillCatalog: SkillCatalogEntry[]\r\n writeAgents: boolean\r\n writePreset: boolean\r\n}\r\n\r\nconst EMPTY: Fields = {\r\n promptText: '',\r\n promptPath: '',\r\n agentsText: '',\r\n agentsPath: '',\r\n injectAgentsPrompt: false,\r\n anchorFirstTurn: false,\r\n anchorText: '',\r\n anchorCustom: false,\r\n subagentFlash: false,\r\n injectPrompt: true,\r\n skillSwitches: {},\r\n skillCatalog: [],\r\n writeAgents: true,\r\n writePreset: true,\r\n}\r\n\r\ninterface SwitchSnapshot {\r\n injectAgentsPrompt: boolean\r\n anchorFirstTurn: boolean\r\n anchorText: string\r\n anchorCustom: boolean\r\n subagentFlash: boolean\r\n injectPrompt: boolean\r\n skillSwitches: Record<string, boolean>\r\n writeAgents: boolean\r\n writePreset: boolean\r\n}\r\n\r\nconst EMPTY_SWITCHES: SwitchSnapshot = {\r\n injectAgentsPrompt: false,\r\n anchorFirstTurn: false,\r\n anchorText: '',\r\n anchorCustom: false,\r\n subagentFlash: false,\r\n injectPrompt: true,\r\n skillSwitches: {},\r\n writeAgents: true,\r\n writePreset: true,\r\n}\r\n\r\nconst snapshotSwitches = (fields: Fields): SwitchSnapshot => ({\r\n injectAgentsPrompt: fields.injectAgentsPrompt,\r\n anchorFirstTurn: fields.anchorFirstTurn,\r\n anchorText: fields.anchorText,\r\n anchorCustom: fields.anchorCustom,\r\n subagentFlash: fields.subagentFlash,\r\n injectPrompt: fields.injectPrompt,\r\n skillSwitches: { ...fields.skillSwitches },\r\n writeAgents: fields.writeAgents,\r\n writePreset: fields.writePreset,\r\n})\r\n\r\nconst switchesEqual = (a: SwitchSnapshot, b: SwitchSnapshot): boolean =>\r\n a.injectAgentsPrompt === b.injectAgentsPrompt\r\n && a.anchorFirstTurn === b.anchorFirstTurn\r\n && a.anchorText === b.anchorText\r\n && a.anchorCustom === b.anchorCustom\r\n && a.subagentFlash === b.subagentFlash\r\n && a.injectPrompt === b.injectPrompt\r\n && JSON.stringify(a.skillSwitches) === JSON.stringify(b.skillSwitches)\r\n && a.writeAgents === b.writeAgents\r\n && a.writePreset === b.writePreset\r\n\r\nconst asRecord = (value: unknown): Record<string, unknown> =>\r\n value !== null && typeof value === 'object' ? value as Record<string, unknown> : {}\r\n\r\nconst readString = (source: Record<string, unknown>, key: string): string | undefined => {\r\n const value = source[key]\r\n return typeof value === 'string' ? value : undefined\r\n}\r\n\r\nconst readBoolean = (source: Record<string, unknown>, key: string, fallback: boolean): boolean => {\r\n const value = source[key]\r\n return typeof value === 'boolean' ? value : fallback\r\n}\r\n\r\nconst readSkillSwitches = (source: Record<string, unknown>, key: string): Record<string, boolean> => {\r\n const value = source[key]\r\n if (value === null || typeof value !== 'object') return {}\r\n const entries = Object.entries(value as Record<string, unknown>)\r\n const result: Record<string, boolean> = {}\r\n for (const [name, enabled] of entries) {\r\n if (typeof enabled === 'boolean') result[name] = enabled\r\n }\r\n return result\r\n}\r\n\r\nconst readSkillCatalog = (source: Record<string, unknown>, key: string): SkillCatalogEntry[] => {\r\n const value = source[key]\r\n if (!Array.isArray(value)) return []\r\n return value.flatMap((entry) => {\r\n if (entry === null || typeof entry !== 'object') return []\r\n const record = entry as Record<string, unknown>\r\n const folder = readString(record, 'folder')\r\n const name = readString(record, 'name')\r\n if (folder === undefined || name === undefined) return []\r\n return [{ folder, name, description: readString(record, 'description') ?? '' }]\r\n })\r\n}\r\n\r\nconst errorMessage = (error: unknown): string => error instanceof Error ? error.message : String(error)\r\n\r\nfunction CollapsibleSection(props: { title: string; hint?: string; open: boolean; onToggle: () => void; children: ReactNode }): ReactNode {\r\n return (\r\n <div className={styles.subSection}>\r\n <button type=\"button\" className={styles.subHeader} aria-expanded={props.open} onClick={props.onToggle}>\r\n <span className={styles.subTitle}>{props.title}</span>\r\n {props.hint && <span className={styles.subCount}>{props.hint}</span>}\r\n <IconChevronDownOutline14 className={clsx(styles.chevron, props.open && styles.chevronOpen)} />\r\n </button>\r\n {props.open && <div className={styles.subBody}>{props.children}</div>}\r\n </div>\r\n )\r\n}\r\n\r\nexport function PromptEditor(props: PromptEditorProps): ReactNode {\r\n const { api } = props\r\n const [open, setOpen] = useState(false)\r\n const [promptOpen, setPromptOpen] = useState(false)\r\n const [agentsOpen, setAgentsOpen] = useState(false)\r\n const [skillsOpen, setSkillsOpen] = useState(false)\r\n const [presetOpen, setPresetOpen] = useState(false)\r\n const [deepseekAvailable, setDeepseekAvailable] = useState(false)\r\n const [deepseekProviders, setDeepseekProviders] = useState<string[]>([])\r\n const [deepseekError, setDeepseekError] = useState('')\r\n const [loaded, setLoaded] = useState(false)\r\n const [fields, setFields] = useState<Fields>(EMPTY)\r\n const [savedPromptText, setSavedPromptText] = useState('')\r\n const [savedAgentsText, setSavedAgentsText] = useState('')\r\n const [savedSwitches, setSavedSwitches] = useState<SwitchSnapshot>(EMPTY_SWITCHES)\r\n const [loading, setLoading] = useState(false)\r\n const [savingPrompt, setSavingPrompt] = useState(false)\r\n const [savingAgents, setSavingAgents] = useState(false)\r\n const [restoringPrompt, setRestoringPrompt] = useState(false)\r\n const [restoringAgents, setRestoringAgents] = useState(false)\r\n const [notice, setNotice] = useState('')\r\n const [noticeKind, setNoticeKind] = useState<'ok' | 'error'>('ok')\r\n const fieldsRef = useRef<Fields>(EMPTY)\r\n const revisionRef = useRef<number | undefined>(undefined)\r\n const saveQueueRef = useRef<Promise<void>>(Promise.resolve())\r\n\r\n const showNotice = useCallback((kind: 'ok' | 'error', message: string) => {\r\n setNotice(message)\r\n setNoticeKind(kind)\r\n }, [])\r\n\r\n const load = useCallback(async () => {\r\n setLoading(true)\r\n try {\r\n const res = await bridgePost<BridgeSettingsView>('/describe', {})\r\n if (!res.ok) { showNotice('error', '读取配置失败:' + (res.message ?? '')); return }\r\n setDeepseekAvailable(res.deepseekAvailable === true)\r\n setDeepseekProviders(res.deepseekProviders ?? [])\r\n setDeepseekError(res.deepseekError ?? '')\r\n const ns = res.value\r\n const value = asRecord(ns.value)\r\n const base = asRecord(ns.base)\r\n const next: Fields = {\r\n promptText: readString(value, 'promptText') ?? readString(base, 'promptText') ?? '',\r\n promptPath: readString(value, 'promptPath') ?? readString(base, 'promptPath') ?? '',\r\n agentsText: readString(value, 'agentsText') ?? readString(base, 'agentsText') ?? '',\r\n agentsPath: readString(value, 'agentsPath') ?? readString(base, 'agentsPath') ?? '',\r\n injectAgentsPrompt: readBoolean(value, 'injectAgentsPrompt', readBoolean(base, 'injectAgentsPrompt', false)),\r\n anchorFirstTurn: readBoolean(value, 'anchorFirstTurn', readBoolean(base, 'anchorFirstTurn', false)),\r\n anchorText: readString(value, 'anchorText') ?? readString(base, 'anchorText') ?? '',\r\n anchorCustom: readBoolean(value, 'anchorCustom', readBoolean(base, 'anchorCustom', false)),\r\n subagentFlash: readBoolean(value, 'subagentFlash', readBoolean(base, 'subagentFlash', false)),\r\n injectPrompt: readBoolean(value, 'injectPrompt', readBoolean(base, 'injectPrompt', true)),\r\n skillSwitches: value.skillSwitches !== undefined || base.skillSwitches !== undefined\r\n ? { ...readSkillSwitches(base, 'skillSwitches'), ...readSkillSwitches(value, 'skillSwitches') }\r\n : {},\r\n skillCatalog: readSkillCatalog(value, 'skillCatalog').length > 0\r\n ? readSkillCatalog(value, 'skillCatalog')\r\n : readSkillCatalog(base, 'skillCatalog'),\r\n writeAgents: readBoolean(value, 'writeAgents', readBoolean(base, 'writeAgents', true)),\r\n writePreset: readBoolean(value, 'writePreset', readBoolean(base, 'writePreset', true)),\r\n }\r\n fieldsRef.current = next\r\n setFields(next)\r\n setSavedPromptText(next.promptText)\r\n setSavedAgentsText(next.agentsText)\r\n setSavedSwitches(snapshotSwitches(next))\r\n revisionRef.current = ns.revision\r\n setNotice('')\r\n } catch (error) {\r\n showNotice('error', '读取失败:' + errorMessage(error))\r\n } finally {\r\n setLoading(false)\r\n }\r\n }, [showNotice])\r\n\r\n const refreshRevision = useCallback(async () => {\r\n try {\r\n const res = await bridgePost<BridgeSettingsView>('/describe', {})\r\n if (!res.ok) return\r\n revisionRef.current = res.value.revision\r\n } catch {\r\n // 刷新失败保持原 revision,用户可重试。\r\n }\r\n }, [])\r\n\r\n const restoreOriginal = useCallback(async (scope: 'preset' | 'agents') => {\r\n const setBusy = scope === 'preset' ? setRestoringPrompt : setRestoringAgents\r\n setBusy(true)\r\n try {\r\n const res = await bridgePost<BridgeSettingsView>('/restore-originals', {\r\n scope,\r\n expectedRevision: revisionRef.current,\r\n })\r\n if (!res.ok) {\r\n await refreshRevision()\r\n showNotice('error', '从项目还原失败:' + (res.message ?? '') + '(已刷新配置版本,可重试)')\r\n return\r\n }\r\n revisionRef.current = res.value.revision\r\n await load()\r\n showNotice('ok', scope === 'preset' ? 'preset.md 已从项目原文还原到设置' : 'AGENTS.md 已从项目原文还原到设置')\r\n } catch (error) {\r\n await refreshRevision()\r\n showNotice('error', '从项目还原失败:' + errorMessage(error) + '(已刷新配置版本,可重试)')\r\n } finally {\r\n setBusy(false)\r\n }\r\n }, [load, refreshRevision, showNotice])\r\n\r\n const patch = (partial: Partial<Fields>) => {\r\n const next = { ...fieldsRef.current, ...partial }\r\n fieldsRef.current = next\r\n setFields(next)\r\n }\r\n\r\n const toggleOpen = () => {\r\n const next = !open\r\n setOpen(next)\r\n if (!next) return\r\n if (!loaded) {\r\n setLoaded(true)\r\n void load()\r\n } else if (!dirty) {\r\n // 无未保存草稿时,每次展开同步最新 settings(其他客户端可能已修改)。\r\n void load()\r\n }\r\n }\r\n\r\n const openEdit = async () => {\r\n if (!fields.promptPath) { showNotice('error', '路径未知,请先保存一次或在下方直接编辑'); return }\r\n try {\r\n const res = await api.host.openPath({ path: fields.promptPath })\r\n if (res.result.ok) showNotice('ok', '已用系统编辑器打开 preset.md')\r\n else showNotice('error', '打开失败:' + (res.result.error?.message ?? '') + ';可直接在下方编辑框保存')\r\n } catch (error) {\r\n showNotice('error', '打开失败:' + errorMessage(error) + ';可直接在下方编辑框保存')\r\n }\r\n }\r\n\r\n const openAgents = async () => {\r\n if (!fields.agentsPath) { showNotice('error', '路径未知,请先保存一次或在下方直接编辑'); return }\r\n try {\r\n const res = await api.host.openPath({ path: fields.agentsPath })\r\n if (res.result.ok) showNotice('ok', '已用系统编辑器打开 AGENTS.md')\r\n else showNotice('error', '打开失败:' + (res.result.error?.message ?? '') + ';可直接在下方编辑框保存')\r\n } catch (error) {\r\n showNotice('error', '打开失败:' + errorMessage(error) + ';可直接在下方编辑框保存')\r\n }\r\n }\r\n\r\n const enqueueSave = useCallback((ops: BridgePathOp[], okMessage: string | undefined, onSaved: () => void, setBusy?: (busy: boolean) => void) => {\r\n setBusy?.(true)\r\n saveQueueRef.current = saveQueueRef.current.then(async () => {\r\n try {\r\n const res = await bridgePost<BridgeSettingsView>('/mutate', { ops, expectedRevision: revisionRef.current })\r\n if (res.ok) {\r\n revisionRef.current = res.value.revision\r\n onSaved()\r\n if (okMessage) showNotice('ok', okMessage)\r\n } else {\r\n await refreshRevision()\r\n showNotice('error', '保存失败:' + (res.message ?? '') + '(已刷新配置版本,可重试)')\r\n }\r\n } catch (error) {\r\n await refreshRevision()\r\n showNotice('error', '保存失败:' + errorMessage(error) + '(已刷新配置版本,可重试)')\r\n } finally {\r\n setBusy?.(false)\r\n }\r\n }).catch(() => {})\r\n }, [refreshRevision, showNotice])\r\n\r\n const savePrompt = () => enqueueSave(\r\n [{ op: 'set', path: ['promptText'], value: fieldsRef.current.promptText }],\r\n 'preset.md 已保存并生效',\r\n () => setSavedPromptText(fieldsRef.current.promptText),\r\n setSavingPrompt,\r\n )\r\n\r\n const saveAgents = () => enqueueSave(\r\n [{ op: 'set', path: ['agentsText'], value: fieldsRef.current.agentsText }],\r\n 'AGENTS.md 已保存并生效',\r\n () => setSavedAgentsText(fieldsRef.current.agentsText),\r\n setSavingAgents,\r\n )\r\n\r\n const persistSwitches = () => enqueueSave(\r\n [\r\n { op: 'set', path: ['injectAgentsPrompt'], value: fieldsRef.current.injectAgentsPrompt },\r\n { op: 'set', path: ['anchorFirstTurn'], value: fieldsRef.current.anchorFirstTurn },\r\n { op: 'set', path: ['anchorText'], value: fieldsRef.current.anchorText },\r\n { op: 'set', path: ['anchorCustom'], value: fieldsRef.current.anchorCustom },\r\n { op: 'set', path: ['subagentFlash'], value: fieldsRef.current.subagentFlash },\r\n { op: 'set', path: ['injectPrompt'], value: fieldsRef.current.injectPrompt },\r\n { op: 'set', path: ['skillSwitches'], value: fieldsRef.current.skillSwitches },\r\n { op: 'set', path: ['writeAgents'], value: fieldsRef.current.writeAgents },\r\n { op: 'set', path: ['writePreset'], value: fieldsRef.current.writePreset },\r\n ],\r\n undefined,\r\n () => setSavedSwitches(snapshotSwitches(fieldsRef.current)),\r\n )\r\n\r\n const toggle = (key: 'injectAgentsPrompt' | 'anchorFirstTurn' | 'anchorCustom' | 'subagentFlash' | 'injectPrompt' | 'writeAgents' | 'writePreset') => {\r\n if (key === 'subagentFlash' && !deepseekAvailable) {\r\n showNotice('error', '未检测到 DeepSeek 模型配置,子代理 Flash 开关不可用')\r\n return\r\n }\r\n patch({ [key]: !fieldsRef.current[key] })\r\n persistSwitches()\r\n }\r\n\r\n const skillEnabled = (folder: string) => fields.skillSwitches[folder] !== false\r\n\r\n const toggleSkill = (folder: string) => {\r\n const enabled = fieldsRef.current.skillSwitches[folder] !== false\r\n patch({ skillSwitches: { ...fieldsRef.current.skillSwitches, [folder]: !enabled } })\r\n persistSwitches()\r\n }\r\n\r\n const currentSwitches = snapshotSwitches(fields)\r\n const dirtyPrompt = fields.promptText !== savedPromptText\r\n const dirtyAgents = fields.agentsText !== savedAgentsText\r\n const dirtySwitches = !switchesEqual(currentSwitches, savedSwitches)\r\n const dirty = dirtyPrompt || dirtyAgents || dirtySwitches\r\n const promptSwitchDirty = fields.injectPrompt !== savedSwitches.injectPrompt\r\n const agentsSwitchDirty = fields.injectAgentsPrompt !== savedSwitches.injectAgentsPrompt\r\n || fields.writeAgents !== savedSwitches.writeAgents\r\n const skillsSwitchDirty = JSON.stringify(fields.skillSwitches) !== JSON.stringify(savedSwitches.skillSwitches)\r\n const presetSwitchDirty = fields.writePreset !== savedSwitches.writePreset\r\n || fields.anchorFirstTurn !== savedSwitches.anchorFirstTurn\r\n || fields.anchorText !== savedSwitches.anchorText\r\n\r\n const discardPrompt = () => patch({ promptText: savedPromptText })\r\n const discardAgents = () => patch({ agentsText: savedAgentsText })\r\n\r\n return (\r\n <li className={clsx(styles.card, open && styles.cardOpen)}>\r\n <button type=\"button\" className={styles.header} aria-expanded={open} onClick={toggleOpen}>\r\n <span className={styles.headText}>\r\n <span className={styles.name}>提示词工具</span>\r\n <span className={styles.description}>编辑 preset.md / AGENTS.md 与各层注入开关,保存后自动生效</span>\r\n </span>\r\n {dirty && <span className={styles.pending}>未保存</span>}\r\n <IconChevronDownOutline14 className={clsx(styles.chevron, open && styles.chevronOpen)} />\r\n </button>\r\n {open && (\r\n <div className={styles.body}>\r\n {loading && <span className={styles.loading}>正在读取配置…</span>}\r\n\r\n <CollapsibleSection\r\n title=\"Preset预设\"\r\n hint={dirtyPrompt || promptSwitchDirty ? '未保存' : undefined}\r\n open={promptOpen}\r\n onToggle={() => setPromptOpen(!promptOpen)}\r\n >\r\n <label className={styles.row}>\r\n <input\r\n type=\"checkbox\"\r\n checked={fields.injectPrompt}\r\n disabled={!fields.writePreset}\r\n onChange={() => toggle('injectPrompt')}\r\n />\r\n <span className={styles.rowText}>\r\n <span className={styles.rowName}>注入 preset.md(锚定层)</span>\r\n <span className={styles.rowDesc}>注入会话晋升后的 agent/pre-step,消息插入决策消息开头,每会话一次</span>\r\n </span>\r\n </label>\r\n <textarea\r\n className={styles.textarea}\r\n aria-label=\"preset.md 内容\"\r\n value={fields.promptText}\r\n onChange={(e) => patch({ promptText: e.target.value })}\r\n spellCheck={false}\r\n />\r\n <div className={styles.actions}>\r\n <button type=\"button\" className={styles.primary} disabled={savingPrompt || savingAgents || !dirtyPrompt} onClick={savePrompt}>{savingPrompt ? '保存中…' : '保存'}</button>\r\n <button type=\"button\" className={styles.secondary} disabled={!dirtyPrompt} onClick={discardPrompt}>还原草稿</button>\r\n <button type=\"button\" className={styles.secondary} disabled={savingPrompt || savingAgents || restoringPrompt || restoringAgents} onClick={() => void restoreOriginal('preset')}>{restoringPrompt ? '还原中…' : '项目还原'}</button>\r\n <button type=\"button\" className={styles.secondary} onClick={openEdit}>打开</button>\r\n </div>\r\n </CollapsibleSection>\r\n\r\n <CollapsibleSection\r\n title=\"AGENTS设置\"\r\n hint={dirtyAgents || agentsSwitchDirty ? '未保存' : undefined}\r\n open={agentsOpen}\r\n onToggle={() => setAgentsOpen(!agentsOpen)}\r\n >\r\n <label className={styles.row}>\r\n <input\r\n type=\"checkbox\"\r\n checked={fields.injectAgentsPrompt}\r\n disabled={!fields.writePreset}\r\n onChange={() => toggle('injectAgentsPrompt')}\r\n />\r\n <span className={styles.rowText}>\r\n <span className={styles.rowName}>注入 AGENTS.md</span>\r\n <span className={styles.rowDesc}>注入会话晋升后的第一个 agent/pre-step,消息追加在决策消息末尾,每会话一次</span>\r\n </span>\r\n </label>\r\n <label className={styles.row}>\r\n <input\r\n type=\"checkbox\"\r\n checked={fields.writeAgents}\r\n onChange={() => toggle('writeAgents')}\r\n />\r\n <span className={styles.rowText}>\r\n <span className={styles.rowName}>写入 ~/.dsh/AGENTS.md</span>\r\n <span className={styles.rowDesc}>保持 AGENTS.md 的全局常驻注入;关闭后不再写入,已有文件保持原样</span>\r\n </span>\r\n </label>\r\n <textarea\r\n className={styles.textarea}\r\n aria-label=\"AGENTS.md 内容\"\r\n value={fields.agentsText}\r\n onChange={(e) => patch({ agentsText: e.target.value })}\r\n spellCheck={false}\r\n />\r\n <div className={styles.actions}>\r\n <button type=\"button\" className={styles.primary} disabled={savingPrompt || savingAgents || !dirtyAgents} onClick={saveAgents}>{savingAgents ? '保存中…' : '保存'}</button>\r\n <button type=\"button\" className={styles.secondary} disabled={!dirtyAgents} onClick={discardAgents}>还原草稿</button>\r\n <button type=\"button\" className={styles.secondary} disabled={savingPrompt || savingAgents || restoringPrompt || restoringAgents} onClick={() => void restoreOriginal('agents')}>{restoringAgents ? '还原中…' : '项目还原'}</button>\r\n <button type=\"button\" className={styles.secondary} onClick={openAgents}>打开</button>\r\n </div>\r\n </CollapsibleSection>\r\n\r\n <CollapsibleSection\r\n title=\"Skills设置\"\r\n hint={`${fields.skillCatalog.length} 个${skillsSwitchDirty ? ' · 未保存' : ''}`}\r\n open={skillsOpen}\r\n onToggle={() => setSkillsOpen(!skillsOpen)}\r\n >\r\n {fields.skillCatalog.length === 0 ? (\r\n <span className={styles.subEmpty}>skills 目录下没有技能</span>\r\n ) : fields.skillCatalog.map((skill) => (\r\n <label key={skill.folder} className={styles.row}>\r\n <input\r\n type=\"checkbox\"\r\n checked={skillEnabled(skill.folder)}\r\n onChange={() => toggleSkill(skill.folder)}\r\n />\r\n <span className={styles.rowText}>\r\n <span className={styles.rowName}>{skill.name || skill.folder}</span>\r\n <span className={styles.rowDesc}>skills/{skill.folder}{skill.description ? ` · ${skill.description}` : ''}</span>\r\n </span>\r\n </label>\r\n ))}\r\n </CollapsibleSection>\r\n\r\n <CollapsibleSection\r\n title=\"锚定与 preset\"\r\n hint={presetSwitchDirty ? '未保存' : undefined}\r\n open={presetOpen}\r\n onToggle={() => setPresetOpen(!presetOpen)}\r\n >\r\n\r\n <label className={styles.row}>\r\n <input\r\n type=\"checkbox\"\r\n checked={fields.writePreset}\r\n onChange={() => toggle('writePreset')}\r\n />\r\n <span className={styles.rowText}>\r\n <span className={styles.rowName}>启用锚定预设</span>\r\n <span className={styles.rowDesc}>总开关:开启时生成并刷新 ~/.dsh/.agent-presets/prompt-tool/,整套锚定预设才有载体;关闭时移除已生成的目录,下面锚定开关随之失效</span>\r\n </span>\r\n </label>\r\n <label className={styles.row}>\r\n <input\r\n type=\"checkbox\"\r\n checked={fields.subagentFlash}\r\n disabled={!fields.writePreset || !deepseekAvailable}\r\n onChange={() => toggle('subagentFlash')}\r\n />\r\n <span className={styles.rowText}>\r\n <span className={styles.rowName}>子代理固定 Flash 模型</span>\r\n <span className={styles.rowDesc}>{deepseekAvailable ? '开启时采用 dsh-router-standard 的 Flash 子代理方案:固定 Flash 路由 + 任务分类人设 + 三锚;宿主直派子代理(含 dsh-mnemon)也会自动补 Flash 路由。关闭时继承主会话模型,工具目录全量放行' : `未检测到 DeepSeek 模型配置,此开关不可用。providers=[${deepseekProviders.join(', ') || '空'}]${deepseekError ? ' error=' + deepseekError : ''}`}</span>\r\n </span>\r\n </label>\r\n <label className={styles.row}>\r\n <input\r\n type=\"checkbox\"\r\n checked={fields.anchorFirstTurn}\r\n disabled={!fields.writePreset}\r\n onChange={() => toggle('anchorFirstTurn')}\r\n />\r\n <span className={styles.rowText}>\r\n <span className={styles.rowName}>追加任务引导</span>\r\n <span className={styles.rowDesc}>开启后在首条真实用户消息之后追加一句任务引导,不拆轮、不挪任务;内容按下方“使用自定义引导”开关选择</span>\r\n </span>\r\n </label>\r\n <label className={styles.row}>\r\n <input\r\n type=\"checkbox\"\r\n checked={fields.anchorCustom}\r\n disabled={!fields.writePreset || !fields.anchorFirstTurn}\r\n onChange={() => toggle('anchorCustom')}\r\n />\r\n <span className={styles.rowText}>\r\n <span className={styles.rowName}>使用自定义引导</span>\r\n <span className={styles.rowDesc}>开启时使用下方文本作为引导;关闭时忽略下方文本,按任务自动选择 we/let 引导</span>\r\n </span>\r\n </label>\r\n <label className={clsx(styles.rowStack, !fields.anchorFirstTurn && styles.rowDisabled)}>\r\n <span className={styles.rowText}>\r\n <span className={styles.rowName}>自定义引导文本</span>\r\n <span className={styles.rowDesc}>仅在上方“使用自定义引导”开启时生效;关闭时自动文本优先</span>\r\n </span>\r\n <textarea\r\n className={styles.anchorInput}\r\n value={fields.anchorText}\r\n disabled={!fields.writePreset || !fields.anchorFirstTurn || !fields.anchorCustom}\r\n onChange={(e) => patch({ anchorText: e.target.value })}\r\n onBlur={() => persistSwitches()}\r\n spellCheck={false}\r\n />\r\n </label>\r\n </CollapsibleSection>\r\n\r\n {notice && <span className={clsx(styles.notice, noticeKind === 'error' && styles.noticeError)}>{notice}</span>}\r\n </div>\r\n )}\r\n </li>\r\n )\r\n}\r\n","import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\nimport type { ConnectionHandle } from '@deepseek-ai/dsh-api-remotes/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings-plugins/client'\nimport { PromptEditor, type PromptEditorInjected } from './PromptEditor.tsx'\n\nexport const inject = ['slots', 'connection']\n\nexport function apply(ctx: ClientContext): void {\n const connection = ctx.get('connection') as ConnectionHandle\n\n const injected = (): PromptEditorInjected => ({\n api: connection.api,\n })\n\n ctx.slots.inject('settings.plugin.item', () => ctx.slots.register({\n name: 'settings.plugin.item',\n id: 'prompt-tool',\n order: 30,\n inject: injected,\n }, PromptEditor))\n}\r\n"],"x_google_ignoreList":[0],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client.js","names":["styles","IconChevronDownOutline14","useState","useRef","useCallback"],"sources":["../node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs","../src/client/PromptEditor.tsx","../src/client/index.ts"],"sourcesContent":["function r(e){var t,f,n=\"\";if(\"string\"==typeof e||\"number\"==typeof e)n+=e;else if(\"object\"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=\" \"),n+=f)}else for(f in e)e[f]&&(n&&(n+=\" \"),n+=f);return n}export function clsx(){for(var e,t,f=0,n=\"\",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=\" \"),n+=t);return n}export default clsx;","import { useCallback, useRef, useState } from 'react'\r\nimport type { ReactNode } from 'react'\r\nimport clsx from 'clsx'\r\nimport { IconChevronDownOutline14 } from '@deepseek-ai/dsh-client-ui-primitives'\r\nimport type { IApiClient } from '@deepseek-ai/dsh-client-connection/client'\r\nimport type { InjectFace, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\r\nimport type {} from '@deepseek-ai/dsh-client-ui-settings-plugins/client'\r\nimport styles from './PromptEditor.module.css'\r\n\r\nconst SETTINGS_BRIDGE_PREFIX = '/api/prompt-tool/settings'\r\n\r\ntype BridgePathOp = { op: 'set' | 'unset'; path: string[]; value?: unknown }\r\ninterface BridgeSettingsView { ns: string; value: unknown; base?: unknown; revision: number }\r\ntype BridgeResult<T> = { ok: true; value: T; deepseekAvailable?: boolean; deepseekProviders?: string[]; deepseekError?: string } | { ok: false; code?: string; message?: string }\r\n\r\nasync function bridgePost<T>(path: string, body: unknown): Promise<BridgeResult<T>> {\r\n try {\r\n const response = await fetch(SETTINGS_BRIDGE_PREFIX + path, {\r\n method: 'POST',\r\n headers: { 'content-type': 'application/json' },\r\n body: JSON.stringify(body),\r\n })\r\n const payload = await response.json() as unknown\r\n if (payload !== null && typeof payload === 'object') return payload as BridgeResult<T>\r\n return { ok: false, message: 'settings bridge unavailable' }\r\n } catch (error) {\r\n return { ok: false, message: errorMessage(error) }\r\n }\r\n}\r\n\r\nexport interface PromptEditorInjected {\r\n api: IApiClient\r\n}\r\n\r\nexport type PromptEditorProps = PropsRuntime<'settings.plugin.item'> & InjectFace<PromptEditorInjected>\r\n\r\ninterface SkillCatalogEntry {\r\n folder: string\r\n name: string\r\n description: string\r\n}\r\n\r\ninterface Fields {\r\n promptText: string\r\n promptPath: string\r\n agentsText: string\r\n agentsPath: string\r\n injectAgentsPrompt: boolean\r\n anchorFirstTurn: boolean\r\n anchorText: string\r\n anchorCustom: boolean\r\n guideText: string\r\n guideCustom: boolean\r\n subagentFlash: boolean\r\n bootstrapMaxTokens: number\r\n injectPrompt: boolean\r\n skillSwitches: Record<string, boolean>\r\n skillCatalog: SkillCatalogEntry[]\r\n writeAgents: boolean\r\n writePreset: boolean\r\n}\r\n\r\nconst EMPTY: Fields = {\r\n promptText: '',\r\n promptPath: '',\r\n agentsText: '',\r\n agentsPath: '',\r\n injectAgentsPrompt: false,\r\n anchorFirstTurn: false,\r\n anchorText: '',\r\n anchorCustom: false,\r\n guideText: '',\r\n guideCustom: false,\r\n subagentFlash: false,\r\n bootstrapMaxTokens: 0,\r\n injectPrompt: true,\r\n skillSwitches: {},\r\n skillCatalog: [],\r\n writeAgents: true,\r\n writePreset: true,\r\n}\r\n\r\ninterface SwitchSnapshot {\r\n injectAgentsPrompt: boolean\r\n anchorFirstTurn: boolean\r\n anchorText: string\r\n anchorCustom: boolean\r\n guideText: string\r\n guideCustom: boolean\r\n subagentFlash: boolean\r\n bootstrapMaxTokens: number\r\n injectPrompt: boolean\r\n skillSwitches: Record<string, boolean>\r\n writeAgents: boolean\r\n writePreset: boolean\r\n}\r\n\r\nconst EMPTY_SWITCHES: SwitchSnapshot = {\r\n injectAgentsPrompt: false,\r\n anchorFirstTurn: false,\r\n anchorText: '',\r\n anchorCustom: false,\r\n guideText: '',\r\n guideCustom: false,\r\n subagentFlash: false,\r\n bootstrapMaxTokens: 0,\r\n injectPrompt: true,\r\n skillSwitches: {},\r\n writeAgents: true,\r\n writePreset: true,\r\n}\r\n\r\n/** 本项目默认不设上限时的显示值(adapter 默认 maxTokens)。 */\r\nconst DEFAULT_BOOTSTRAP_DISPLAY = '256000'\r\n\r\nconst snapshotSwitches = (fields: Fields): SwitchSnapshot => ({\r\n injectAgentsPrompt: fields.injectAgentsPrompt,\r\n anchorFirstTurn: fields.anchorFirstTurn,\r\n anchorText: fields.anchorText,\r\n anchorCustom: fields.anchorCustom,\r\n guideText: fields.guideText,\r\n guideCustom: fields.guideCustom,\r\n subagentFlash: fields.subagentFlash,\r\n bootstrapMaxTokens: fields.bootstrapMaxTokens,\r\n injectPrompt: fields.injectPrompt,\r\n skillSwitches: { ...fields.skillSwitches },\r\n writeAgents: fields.writeAgents,\r\n writePreset: fields.writePreset,\r\n})\r\n\r\nconst switchesEqual = (a: SwitchSnapshot, b: SwitchSnapshot): boolean =>\r\n a.injectAgentsPrompt === b.injectAgentsPrompt\r\n && a.anchorFirstTurn === b.anchorFirstTurn\r\n && a.anchorText === b.anchorText\r\n && a.anchorCustom === b.anchorCustom\r\n && a.guideText === b.guideText\r\n && a.guideCustom === b.guideCustom\r\n && a.subagentFlash === b.subagentFlash\r\n && a.bootstrapMaxTokens === b.bootstrapMaxTokens\r\n && a.injectPrompt === b.injectPrompt\r\n && JSON.stringify(a.skillSwitches) === JSON.stringify(b.skillSwitches)\r\n && a.writeAgents === b.writeAgents\r\n && a.writePreset === b.writePreset\r\n\r\nconst asRecord = (value: unknown): Record<string, unknown> =>\r\n value !== null && typeof value === 'object' ? value as Record<string, unknown> : {}\r\n\r\nconst readString = (source: Record<string, unknown>, key: string): string | undefined => {\r\n const value = source[key]\r\n return typeof value === 'string' ? value : undefined\r\n}\r\n\r\nconst readBoolean = (source: Record<string, unknown>, key: string, fallback: boolean): boolean => {\r\n const value = source[key]\r\n return typeof value === 'boolean' ? value : fallback\r\n}\r\n\r\nconst readNumber = (source: Record<string, unknown>, key: string, fallback: number): number => {\r\n const value = source[key]\r\n return typeof value === 'number' && Number.isSafeInteger(value) && value >= 0 ? value : fallback\r\n}\r\n\r\nconst readSkillSwitches = (source: Record<string, unknown>, key: string): Record<string, boolean> => {\r\n const value = source[key]\r\n if (value === null || typeof value !== 'object') return {}\r\n const entries = Object.entries(value as Record<string, unknown>)\r\n const result: Record<string, boolean> = {}\r\n for (const [name, enabled] of entries) {\r\n if (typeof enabled === 'boolean') result[name] = enabled\r\n }\r\n return result\r\n}\r\n\r\nconst readSkillCatalog = (source: Record<string, unknown>, key: string): SkillCatalogEntry[] => {\r\n const value = source[key]\r\n if (!Array.isArray(value)) return []\r\n return value.flatMap((entry) => {\r\n if (entry === null || typeof entry !== 'object') return []\r\n const record = entry as Record<string, unknown>\r\n const folder = readString(record, 'folder')\r\n const name = readString(record, 'name')\r\n if (folder === undefined || name === undefined) return []\r\n return [{ folder, name, description: readString(record, 'description') ?? '' }]\r\n })\r\n}\r\n\r\nconst errorMessage = (error: unknown): string => error instanceof Error ? error.message : String(error)\r\n\r\nfunction CollapsibleSection(props: { title: string; hint?: string; open: boolean; onToggle: () => void; children: ReactNode }): ReactNode {\r\n return (\r\n <div className={styles.subSection}>\r\n <button type=\"button\" className={styles.subHeader} aria-expanded={props.open} onClick={props.onToggle}>\r\n <span className={styles.subTitle}>{props.title}</span>\r\n {props.hint && <span className={styles.subCount}>{props.hint}</span>}\r\n <IconChevronDownOutline14 className={clsx(styles.chevron, props.open && styles.chevronOpen)} />\r\n </button>\r\n {props.open && <div className={styles.subBody}>{props.children}</div>}\r\n </div>\r\n )\r\n}\r\n\r\nexport function PromptEditor(props: PromptEditorProps): ReactNode {\r\n const { api } = props\r\n const [open, setOpen] = useState(false)\r\n const [promptOpen, setPromptOpen] = useState(false)\r\n const [agentsOpen, setAgentsOpen] = useState(false)\r\n const [skillsOpen, setSkillsOpen] = useState(false)\r\n const [presetOpen, setPresetOpen] = useState(false)\r\n const [deepseekAvailable, setDeepseekAvailable] = useState(false)\r\n const [deepseekProviders, setDeepseekProviders] = useState<string[]>([])\r\n const [deepseekError, setDeepseekError] = useState('')\r\n const [loaded, setLoaded] = useState(false)\r\n const [fields, setFields] = useState<Fields>(EMPTY)\r\n const [bootstrapTokensDraft, setBootstrapTokensDraft] = useState(DEFAULT_BOOTSTRAP_DISPLAY)\r\n const [savedPromptText, setSavedPromptText] = useState('')\r\n const [savedAgentsText, setSavedAgentsText] = useState('')\r\n const [savedSwitches, setSavedSwitches] = useState<SwitchSnapshot>(EMPTY_SWITCHES)\r\n const [loading, setLoading] = useState(false)\r\n const [savingPrompt, setSavingPrompt] = useState(false)\r\n const [savingAgents, setSavingAgents] = useState(false)\r\n const [restoringPrompt, setRestoringPrompt] = useState(false)\r\n const [restoringAgents, setRestoringAgents] = useState(false)\r\n const [notice, setNotice] = useState('')\r\n const [noticeKind, setNoticeKind] = useState<'ok' | 'error'>('ok')\r\n const fieldsRef = useRef<Fields>(EMPTY)\r\n const revisionRef = useRef<number | undefined>(undefined)\r\n const saveQueueRef = useRef<Promise<void>>(Promise.resolve())\r\n\r\n const showNotice = useCallback((kind: 'ok' | 'error', message: string) => {\r\n setNotice(message)\r\n setNoticeKind(kind)\r\n }, [])\r\n\r\n const load = useCallback(async () => {\r\n setLoading(true)\r\n try {\r\n const res = await bridgePost<BridgeSettingsView>('/describe', {})\r\n if (!res.ok) { showNotice('error', '读取配置失败:' + (res.message ?? '')); return }\r\n setDeepseekAvailable(res.deepseekAvailable === true)\r\n setDeepseekProviders(res.deepseekProviders ?? [])\r\n setDeepseekError(res.deepseekError ?? '')\r\n const ns = res.value\r\n const value = asRecord(ns.value)\r\n const base = asRecord(ns.base)\r\n const next: Fields = {\r\n promptText: readString(value, 'promptText') ?? readString(base, 'promptText') ?? '',\r\n promptPath: readString(value, 'promptPath') ?? readString(base, 'promptPath') ?? '',\r\n agentsText: readString(value, 'agentsText') ?? readString(base, 'agentsText') ?? '',\r\n agentsPath: readString(value, 'agentsPath') ?? readString(base, 'agentsPath') ?? '',\r\n injectAgentsPrompt: readBoolean(value, 'injectAgentsPrompt', readBoolean(base, 'injectAgentsPrompt', false)),\r\n anchorFirstTurn: readBoolean(value, 'anchorFirstTurn', readBoolean(base, 'anchorFirstTurn', false)),\r\n anchorText: readString(value, 'anchorText') ?? readString(base, 'anchorText') ?? '',\r\n anchorCustom: readBoolean(value, 'anchorCustom', readBoolean(base, 'anchorCustom', false)),\r\n guideText: readString(value, 'guideText') ?? readString(base, 'guideText') ?? '',\r\n guideCustom: readBoolean(value, 'guideCustom', readBoolean(base, 'guideCustom', false)),\r\n subagentFlash: readBoolean(value, 'subagentFlash', readBoolean(base, 'subagentFlash', false)),\r\n bootstrapMaxTokens: readNumber(value, 'bootstrapMaxTokens', readNumber(base, 'bootstrapMaxTokens', 0)),\r\n injectPrompt: readBoolean(value, 'injectPrompt', readBoolean(base, 'injectPrompt', true)),\r\n skillSwitches: value.skillSwitches !== undefined || base.skillSwitches !== undefined\r\n ? { ...readSkillSwitches(base, 'skillSwitches'), ...readSkillSwitches(value, 'skillSwitches') }\r\n : {},\r\n skillCatalog: readSkillCatalog(value, 'skillCatalog').length > 0\r\n ? readSkillCatalog(value, 'skillCatalog')\r\n : readSkillCatalog(base, 'skillCatalog'),\r\n writeAgents: readBoolean(value, 'writeAgents', readBoolean(base, 'writeAgents', true)),\r\n writePreset: readBoolean(value, 'writePreset', readBoolean(base, 'writePreset', true)),\r\n }\r\n fieldsRef.current = next\r\n setFields(next)\r\n setBootstrapTokensDraft(next.bootstrapMaxTokens > 0 ? String(next.bootstrapMaxTokens) : DEFAULT_BOOTSTRAP_DISPLAY)\r\n setSavedPromptText(next.promptText)\r\n setSavedAgentsText(next.agentsText)\r\n setSavedSwitches(snapshotSwitches(next))\r\n revisionRef.current = ns.revision\r\n setNotice('')\r\n } catch (error) {\r\n showNotice('error', '读取失败:' + errorMessage(error))\r\n } finally {\r\n setLoading(false)\r\n }\r\n }, [showNotice])\r\n\r\n const refreshRevision = useCallback(async () => {\r\n try {\r\n const res = await bridgePost<BridgeSettingsView>('/describe', {})\r\n if (!res.ok) return\r\n revisionRef.current = res.value.revision\r\n } catch {\r\n // 刷新失败保持原 revision,用户可重试。\r\n }\r\n }, [])\r\n\r\n const restoreOriginal = useCallback(async (scope: 'preset' | 'agents') => {\r\n const setBusy = scope === 'preset' ? setRestoringPrompt : setRestoringAgents\r\n setBusy(true)\r\n try {\r\n const res = await bridgePost<BridgeSettingsView>('/restore-originals', {\r\n scope,\r\n expectedRevision: revisionRef.current,\r\n })\r\n if (!res.ok) {\r\n await refreshRevision()\r\n showNotice('error', '从项目还原失败:' + (res.message ?? '') + '(已刷新配置版本,可重试)')\r\n return\r\n }\r\n revisionRef.current = res.value.revision\r\n await load()\r\n showNotice('ok', scope === 'preset' ? 'preset.md 已从项目原文还原到设置' : 'AGENTS.md 已从项目原文还原到设置')\r\n } catch (error) {\r\n await refreshRevision()\r\n showNotice('error', '从项目还原失败:' + errorMessage(error) + '(已刷新配置版本,可重试)')\r\n } finally {\r\n setBusy(false)\r\n }\r\n }, [load, refreshRevision, showNotice])\r\n\r\n const patch = (partial: Partial<Fields>) => {\r\n const next = { ...fieldsRef.current, ...partial }\r\n fieldsRef.current = next\r\n setFields(next)\r\n }\r\n\r\n const toggleOpen = () => {\r\n const next = !open\r\n setOpen(next)\r\n if (!next) return\r\n if (!loaded) {\r\n setLoaded(true)\r\n void load()\r\n } else if (!dirty) {\r\n // 无未保存草稿时,每次展开同步最新 settings(其他客户端可能已修改)。\r\n void load()\r\n }\r\n }\r\n\r\n const openEdit = async () => {\r\n if (!fields.promptPath) { showNotice('error', '路径未知,请先保存一次或在下方直接编辑'); return }\r\n try {\r\n const res = await api.host.openPath({ path: fields.promptPath })\r\n if (res.result.ok) showNotice('ok', '已用系统编辑器打开 preset.md')\r\n else showNotice('error', '打开失败:' + (res.result.error?.message ?? '') + ';可直接在下方编辑框保存')\r\n } catch (error) {\r\n showNotice('error', '打开失败:' + errorMessage(error) + ';可直接在下方编辑框保存')\r\n }\r\n }\r\n\r\n const openAgents = async () => {\r\n if (!fields.agentsPath) { showNotice('error', '路径未知,请先保存一次或在下方直接编辑'); return }\r\n try {\r\n const res = await api.host.openPath({ path: fields.agentsPath })\r\n if (res.result.ok) showNotice('ok', '已用系统编辑器打开 AGENTS.md')\r\n else showNotice('error', '打开失败:' + (res.result.error?.message ?? '') + ';可直接在下方编辑框保存')\r\n } catch (error) {\r\n showNotice('error', '打开失败:' + errorMessage(error) + ';可直接在下方编辑框保存')\r\n }\r\n }\r\n\r\n const enqueueSave = useCallback((ops: BridgePathOp[], okMessage: string | undefined, onSaved: () => void, setBusy?: (busy: boolean) => void) => {\r\n setBusy?.(true)\r\n saveQueueRef.current = saveQueueRef.current.then(async () => {\r\n try {\r\n const res = await bridgePost<BridgeSettingsView>('/mutate', { ops, expectedRevision: revisionRef.current })\r\n if (res.ok) {\r\n revisionRef.current = res.value.revision\r\n onSaved()\r\n if (okMessage) showNotice('ok', okMessage)\r\n } else {\r\n await refreshRevision()\r\n showNotice('error', '保存失败:' + (res.message ?? '') + '(已刷新配置版本,可重试)')\r\n }\r\n } catch (error) {\r\n await refreshRevision()\r\n showNotice('error', '保存失败:' + errorMessage(error) + '(已刷新配置版本,可重试)')\r\n } finally {\r\n setBusy?.(false)\r\n }\r\n }).catch(() => {})\r\n }, [refreshRevision, showNotice])\r\n\r\n const savePrompt = () => enqueueSave(\r\n [{ op: 'set', path: ['promptText'], value: fieldsRef.current.promptText }],\r\n 'preset.md 已保存并生效',\r\n () => setSavedPromptText(fieldsRef.current.promptText),\r\n setSavingPrompt,\r\n )\r\n\r\n const saveAgents = () => enqueueSave(\r\n [{ op: 'set', path: ['agentsText'], value: fieldsRef.current.agentsText }],\r\n 'AGENTS.md 已保存并生效',\r\n () => setSavedAgentsText(fieldsRef.current.agentsText),\r\n setSavingAgents,\r\n )\r\n\r\n const persistSwitches = () => enqueueSave(\r\n [\r\n { op: 'set', path: ['injectAgentsPrompt'], value: fieldsRef.current.injectAgentsPrompt },\r\n { op: 'set', path: ['anchorFirstTurn'], value: fieldsRef.current.anchorFirstTurn },\r\n { op: 'set', path: ['anchorText'], value: fieldsRef.current.anchorText },\r\n { op: 'set', path: ['anchorCustom'], value: fieldsRef.current.anchorCustom },\r\n { op: 'set', path: ['guideText'], value: fieldsRef.current.guideText },\r\n { op: 'set', path: ['guideCustom'], value: fieldsRef.current.guideCustom },\r\n { op: 'set', path: ['subagentFlash'], value: fieldsRef.current.subagentFlash },\r\n { op: 'set', path: ['bootstrapMaxTokens'], value: fieldsRef.current.bootstrapMaxTokens },\r\n { op: 'set', path: ['injectPrompt'], value: fieldsRef.current.injectPrompt },\r\n { op: 'set', path: ['skillSwitches'], value: fieldsRef.current.skillSwitches },\r\n { op: 'set', path: ['writeAgents'], value: fieldsRef.current.writeAgents },\r\n { op: 'set', path: ['writePreset'], value: fieldsRef.current.writePreset },\r\n ],\r\n undefined,\r\n () => setSavedSwitches(snapshotSwitches(fieldsRef.current)),\r\n )\r\n\r\n const toggle = (key: 'injectAgentsPrompt' | 'anchorFirstTurn' | 'anchorCustom' | 'guideCustom' | 'subagentFlash' | 'injectPrompt' | 'writeAgents' | 'writePreset') => {\r\n if (key === 'subagentFlash' && !deepseekAvailable) {\r\n showNotice('error', '未检测到 DeepSeek 模型配置,子代理 Flash 开关不可用')\r\n return\r\n }\r\n patch({ [key]: !fieldsRef.current[key] })\r\n persistSwitches()\r\n }\r\n\r\n const toggleBootstrapMaxTokens = () => {\r\n const next = fieldsRef.current.bootstrapMaxTokens > 0 ? 0 : 256000\r\n patch({ bootstrapMaxTokens: next })\r\n setBootstrapTokensDraft(DEFAULT_BOOTSTRAP_DISPLAY)\r\n persistSwitches()\r\n }\r\n\r\n const commitBootstrapTokensDraft = () => {\r\n const parsed = Number(bootstrapTokensDraft)\r\n if (!Number.isSafeInteger(parsed) || parsed <= 0) {\r\n // 清空或非法输入不关闭开关:恢复为项目默认 256000(不设上限)。\r\n setBootstrapTokensDraft(DEFAULT_BOOTSTRAP_DISPLAY)\r\n patch({ bootstrapMaxTokens: 256000 })\r\n } else {\r\n patch({ bootstrapMaxTokens: parsed })\r\n }\r\n persistSwitches()\r\n }\r\n\r\n const skillEnabled = (folder: string) => fields.skillSwitches[folder] !== false\r\n\r\n const toggleSkill = (folder: string) => {\r\n const enabled = fieldsRef.current.skillSwitches[folder] !== false\r\n patch({ skillSwitches: { ...fieldsRef.current.skillSwitches, [folder]: !enabled } })\r\n persistSwitches()\r\n }\r\n\r\n const currentSwitches = snapshotSwitches(fields)\r\n const dirtyPrompt = fields.promptText !== savedPromptText\r\n const dirtyAgents = fields.agentsText !== savedAgentsText\r\n const dirtySwitches = !switchesEqual(currentSwitches, savedSwitches)\r\n const dirty = dirtyPrompt || dirtyAgents || dirtySwitches\r\n const promptSwitchDirty = fields.injectPrompt !== savedSwitches.injectPrompt\r\n const agentsSwitchDirty = fields.injectAgentsPrompt !== savedSwitches.injectAgentsPrompt\r\n || fields.writeAgents !== savedSwitches.writeAgents\r\n const skillsSwitchDirty = JSON.stringify(fields.skillSwitches) !== JSON.stringify(savedSwitches.skillSwitches)\r\n const presetSwitchDirty = fields.writePreset !== savedSwitches.writePreset\r\n || fields.anchorFirstTurn !== savedSwitches.anchorFirstTurn\r\n || fields.anchorText !== savedSwitches.anchorText\r\n || fields.bootstrapMaxTokens !== savedSwitches.bootstrapMaxTokens\r\n\r\n const discardPrompt = () => patch({ promptText: savedPromptText })\r\n const discardAgents = () => patch({ agentsText: savedAgentsText })\r\n\r\n return (\r\n <li className={clsx(styles.card, open && styles.cardOpen)}>\r\n <button type=\"button\" className={styles.header} aria-expanded={open} onClick={toggleOpen}>\r\n <span className={styles.headText}>\r\n <span className={styles.name}>提示词工具</span>\r\n <span className={styles.description}>编辑 preset.md / AGENTS.md 与各层注入开关,保存后自动生效</span>\r\n </span>\r\n {dirty && <span className={styles.pending}>未保存</span>}\r\n <IconChevronDownOutline14 className={clsx(styles.chevron, open && styles.chevronOpen)} />\r\n </button>\r\n {open && (\r\n <div className={styles.body}>\r\n {loading && <span className={styles.loading}>正在读取配置…</span>}\r\n\r\n <CollapsibleSection\r\n title=\"Preset预设\"\r\n hint={dirtyPrompt || promptSwitchDirty ? '未保存' : undefined}\r\n open={promptOpen}\r\n onToggle={() => setPromptOpen(!promptOpen)}\r\n >\r\n <label className={styles.row}>\r\n <input\r\n type=\"checkbox\"\r\n checked={fields.injectPrompt}\r\n disabled={!fields.writePreset}\r\n onChange={() => toggle('injectPrompt')}\r\n />\r\n <span className={styles.rowText}>\r\n <span className={styles.rowName}>注入 preset.md(锚定层)</span>\r\n <span className={styles.rowDesc}>注入会话晋升后的 agent/pre-step,消息插入决策消息开头,每会话一次</span>\r\n </span>\r\n </label>\r\n <textarea\r\n className={styles.textarea}\r\n aria-label=\"preset.md 内容\"\r\n value={fields.promptText}\r\n onChange={(e) => patch({ promptText: e.target.value })}\r\n spellCheck={false}\r\n />\r\n <div className={styles.actions}>\r\n <button type=\"button\" className={styles.primary} disabled={savingPrompt || savingAgents || !dirtyPrompt} onClick={savePrompt}>{savingPrompt ? '保存中…' : '保存'}</button>\r\n <button type=\"button\" className={styles.secondary} disabled={!dirtyPrompt} onClick={discardPrompt}>还原草稿</button>\r\n <button type=\"button\" className={styles.secondary} disabled={savingPrompt || savingAgents || restoringPrompt || restoringAgents} onClick={() => void restoreOriginal('preset')}>{restoringPrompt ? '还原中…' : '项目还原'}</button>\r\n <button type=\"button\" className={styles.secondary} onClick={openEdit}>打开</button>\r\n </div>\r\n </CollapsibleSection>\r\n\r\n <CollapsibleSection\r\n title=\"AGENTS设置\"\r\n hint={dirtyAgents || agentsSwitchDirty ? '未保存' : undefined}\r\n open={agentsOpen}\r\n onToggle={() => setAgentsOpen(!agentsOpen)}\r\n >\r\n <label className={styles.row}>\r\n <input\r\n type=\"checkbox\"\r\n checked={fields.injectAgentsPrompt}\r\n disabled={!fields.writePreset}\r\n onChange={() => toggle('injectAgentsPrompt')}\r\n />\r\n <span className={styles.rowText}>\r\n <span className={styles.rowName}>注入 AGENTS.md</span>\r\n <span className={styles.rowDesc}>注入会话晋升后的第一个 agent/pre-step,消息追加在决策消息末尾,每会话一次</span>\r\n </span>\r\n </label>\r\n <label className={styles.row}>\r\n <input\r\n type=\"checkbox\"\r\n checked={fields.writeAgents}\r\n onChange={() => toggle('writeAgents')}\r\n />\r\n <span className={styles.rowText}>\r\n <span className={styles.rowName}>写入 ~/.dsh/AGENTS.md</span>\r\n <span className={styles.rowDesc}>保持 AGENTS.md 的全局常驻注入;关闭后不再写入,已有文件保持原样</span>\r\n </span>\r\n </label>\r\n <textarea\r\n className={styles.textarea}\r\n aria-label=\"AGENTS.md 内容\"\r\n value={fields.agentsText}\r\n onChange={(e) => patch({ agentsText: e.target.value })}\r\n spellCheck={false}\r\n />\r\n <div className={styles.actions}>\r\n <button type=\"button\" className={styles.primary} disabled={savingPrompt || savingAgents || !dirtyAgents} onClick={saveAgents}>{savingAgents ? '保存中…' : '保存'}</button>\r\n <button type=\"button\" className={styles.secondary} disabled={!dirtyAgents} onClick={discardAgents}>还原草稿</button>\r\n <button type=\"button\" className={styles.secondary} disabled={savingPrompt || savingAgents || restoringPrompt || restoringAgents} onClick={() => void restoreOriginal('agents')}>{restoringAgents ? '还原中…' : '项目还原'}</button>\r\n <button type=\"button\" className={styles.secondary} onClick={openAgents}>打开</button>\r\n </div>\r\n </CollapsibleSection>\r\n\r\n <CollapsibleSection\r\n title=\"Skills设置\"\r\n hint={`${fields.skillCatalog.length} 个${skillsSwitchDirty ? ' · 未保存' : ''}`}\r\n open={skillsOpen}\r\n onToggle={() => setSkillsOpen(!skillsOpen)}\r\n >\r\n {fields.skillCatalog.length === 0 ? (\r\n <span className={styles.subEmpty}>skills 目录下没有技能</span>\r\n ) : fields.skillCatalog.map((skill) => (\r\n <label key={skill.folder} className={styles.row}>\r\n <input\r\n type=\"checkbox\"\r\n checked={skillEnabled(skill.folder)}\r\n onChange={() => toggleSkill(skill.folder)}\r\n />\r\n <span className={styles.rowText}>\r\n <span className={styles.rowName}>{skill.name || skill.folder}</span>\r\n <span className={styles.rowDesc}>skills/{skill.folder}{skill.description ? ` · ${skill.description}` : ''}</span>\r\n </span>\r\n </label>\r\n ))}\r\n </CollapsibleSection>\r\n\r\n <CollapsibleSection\r\n title=\"锚定与 preset\"\r\n hint={presetSwitchDirty ? '未保存' : undefined}\r\n open={presetOpen}\r\n onToggle={() => setPresetOpen(!presetOpen)}\r\n >\r\n\r\n <label className={styles.row}>\r\n <input\r\n type=\"checkbox\"\r\n checked={fields.writePreset}\r\n onChange={() => toggle('writePreset')}\r\n />\r\n <span className={styles.rowText}>\r\n <span className={styles.rowName}>启用锚定预设</span>\r\n <span className={styles.rowDesc}>总开关:开启时生成并刷新 ~/.dsh/.agent-presets/prompt-tool/,整套锚定预设才有载体;关闭时移除已生成的目录,下面锚定开关随之失效</span>\r\n </span>\r\n </label>\r\n\r\n <div className={styles.row}>\r\n <input\r\n id=\"prompt-tool-bootstrap-max-tokens\"\r\n type=\"checkbox\"\r\n checked={fields.bootstrapMaxTokens > 0}\r\n disabled={!fields.writePreset}\r\n onChange={toggleBootstrapMaxTokens}\r\n />\r\n <label htmlFor=\"prompt-tool-bootstrap-max-tokens\" className={styles.rowText}>\r\n <span className={styles.rowName}>首轮输出封顶</span>\r\n <span className={styles.rowDesc}>关闭时显示项目默认 256000(不设上限);开启后右侧数值生效,晋升后自动剥离。清空或输入 0 会恢复 256000,不关闭开关</span>\r\n </label>\r\n <input\r\n className={styles.bootstrapTokensInput}\r\n type=\"number\"\r\n min={1}\r\n step={1}\r\n value={bootstrapTokensDraft}\r\n disabled={!fields.writePreset || fields.bootstrapMaxTokens === 0}\r\n onChange={(e) => setBootstrapTokensDraft(e.target.value)}\r\n onBlur={commitBootstrapTokensDraft}\r\n />\r\n </div>\r\n <label className={styles.row}>\r\n <input\r\n type=\"checkbox\"\r\n checked={fields.subagentFlash}\r\n disabled={!fields.writePreset || !deepseekAvailable}\r\n onChange={() => toggle('subagentFlash')}\r\n />\r\n <span className={styles.rowText}>\r\n <span className={styles.rowName}>子代理固定 Flash 模型</span>\r\n <span className={styles.rowDesc}>{deepseekAvailable ? '开启时采用 dsh-router-standard 的 Flash 子代理方案:固定 Flash 路由 + 任务分类人设 + 三锚;宿主直派子代理(含 dsh-mnemon)也会自动补 Flash 路由。关闭时继承主会话模型,工具目录全量放行' : `未检测到 DeepSeek 模型配置,此开关不可用。providers=[${deepseekProviders.join(', ') || '空'}]${deepseekError ? ' error=' + deepseekError : ''}`}</span>\r\n </span>\r\n </label>\r\n <label className={styles.row}>\r\n <input\r\n type=\"checkbox\"\r\n checked={fields.anchorFirstTurn}\r\n disabled={!fields.writePreset}\r\n onChange={() => toggle('anchorFirstTurn')}\r\n />\r\n <span className={styles.rowText}>\r\n <span className={styles.rowName}>追加任务引导</span>\r\n <span className={styles.rowDesc}>总开关:开启后在首条真实用户消息之后追加任务引导;关闭时下方首句与每轮的自定义开关、编辑框全部禁用</span>\r\n </span>\r\n </label>\r\n <label className={styles.row}>\r\n <input\r\n type=\"checkbox\"\r\n checked={fields.anchorCustom}\r\n disabled={!fields.writePreset || !fields.anchorFirstTurn}\r\n onChange={() => toggle('anchorCustom')}\r\n />\r\n <span className={styles.rowText}>\r\n <span className={styles.rowName}>使用自定义引导(首句)</span>\r\n <span className={styles.rowDesc}>开启时使用下方文本作为引导;关闭时忽略下方文本,按任务自动选择 we/let 引导</span>\r\n </span>\r\n </label>\r\n <label className={clsx(styles.rowStack, (!fields.anchorFirstTurn || !fields.anchorCustom) && styles.rowDisabled)}>\r\n <span className={styles.rowText}>\r\n <span className={styles.rowName}>自定义引导文本(首句)</span>\r\n <span className={styles.rowDesc}>仅在上方“使用自定义引导(首句)”开启时生效;关闭时自动文本优先</span>\r\n </span>\r\n <textarea\r\n className={styles.anchorInput}\r\n value={fields.anchorText}\r\n disabled={!fields.writePreset || !fields.anchorFirstTurn || !fields.anchorCustom}\r\n onChange={(e) => patch({ anchorText: e.target.value })}\r\n onBlur={() => persistSwitches()}\r\n spellCheck={false}\r\n />\r\n </label>\r\n <label className={styles.row}>\r\n <input\r\n type=\"checkbox\"\r\n checked={fields.guideCustom}\r\n disabled={!fields.writePreset || !fields.anchorFirstTurn}\r\n onChange={() => toggle('guideCustom')}\r\n />\r\n <span className={styles.rowText}>\r\n <span className={styles.rowName}>使用自定义引导(每轮)</span>\r\n <span className={styles.rowDesc}>开启时每轮固定使用下方文本作为引导;关闭时忽略下方文本,按任务自动选择</span>\r\n </span>\r\n </label>\r\n <label className={clsx(styles.rowStack, (!fields.anchorFirstTurn || !fields.guideCustom) && styles.rowDisabled)}>\r\n <span className={styles.rowText}>\r\n <span className={styles.rowName}>自定义引导文本(每轮)</span>\r\n <span className={styles.rowDesc}>仅在上方“使用自定义引导(每轮)”开启时生效;留空则不注入</span>\r\n </span>\r\n <textarea\r\n className={styles.anchorInput}\r\n value={fields.guideText}\r\n disabled={!fields.writePreset || !fields.anchorFirstTurn || !fields.guideCustom}\r\n onChange={(e) => patch({ guideText: e.target.value })}\r\n onBlur={() => persistSwitches()}\r\n spellCheck={false}\r\n />\r\n </label>\r\n </CollapsibleSection>\r\n\r\n {notice && <span className={clsx(styles.notice, noticeKind === 'error' && styles.noticeError)}>{notice}</span>}\r\n </div>\r\n )}\r\n </li>\r\n )\r\n}\r\n","import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\nimport type { ConnectionHandle } from '@deepseek-ai/dsh-api-remotes/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings-plugins/client'\nimport { PromptEditor, type PromptEditorInjected } from './PromptEditor.tsx'\n\nexport const inject = ['slots', 'connection']\n\nexport function apply(ctx: ClientContext): void {\n const connection = ctx.get('connection') as ConnectionHandle\n\n const injected = (): PromptEditorInjected => ({\n api: connection.api,\n })\n\n ctx.slots.inject('settings.plugin.item', () => ctx.slots.register({\n name: 'settings.plugin.item',\n id: 'prompt-tool',\n order: 30,\n inject: injected,\n }, PromptEditor))\n}\r\n"],"x_google_ignoreList":[0],"mappings":"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"}
|
package/lib/index.d.mts
CHANGED
|
@@ -24,14 +24,18 @@ interface Config {
|
|
|
24
24
|
anchorText: string;
|
|
25
25
|
/** 自定义锚点开关:true 固定使用 anchorText;false 按任务自动选择。 */
|
|
26
26
|
anchorCustom: boolean;
|
|
27
|
+
/** 自定义每轮引导文本;guideCustom=true 时固定使用。 */
|
|
28
|
+
guideText: string;
|
|
29
|
+
/** 自定义每轮引导开关:true 固定使用 guideText;false 按任务自动选择。 */
|
|
30
|
+
guideCustom: boolean;
|
|
27
31
|
/** 子代理固定 Flash 模型:开启时给 subagent/subagent_fork 行加固定 Flash 路由;关闭时子代理继承主会话路由,目录全量放行。 */
|
|
28
32
|
subagentFlash: boolean;
|
|
29
33
|
/** 子代理 Flash 路由 provider(默认 deepseek-official)。 */
|
|
30
34
|
subagentFlashProvider: string;
|
|
31
35
|
/** 子代理 Flash 模型名(默认 deepseek-v4-flash)。 */
|
|
32
36
|
subagentFlashModel: string;
|
|
33
|
-
/**
|
|
34
|
-
|
|
37
|
+
/** 首轮输出封顶;0 或未设置 = 不设封顶(本项目默认),正整数 = 请求 #1 的 maxTokens。 */
|
|
38
|
+
bootstrapMaxTokens: number;
|
|
35
39
|
/** 技能目录(默认包内 skills/,可指向本地测试目录)。 */
|
|
36
40
|
skillsDir: string;
|
|
37
41
|
/** 技能候选排序基数,技能目录内按下标递增。 */
|
|
@@ -60,7 +64,10 @@ interface PromptSettings {
|
|
|
60
64
|
anchorFirstTurn: boolean;
|
|
61
65
|
anchorText: string;
|
|
62
66
|
anchorCustom: boolean;
|
|
67
|
+
guideText: string;
|
|
68
|
+
guideCustom: boolean;
|
|
63
69
|
subagentFlash: boolean;
|
|
70
|
+
bootstrapMaxTokens: number;
|
|
64
71
|
/** 运行时检测:是否注册了 DeepSeek 模型路由(不写入 settings)。 */
|
|
65
72
|
deepseekAvailable: boolean;
|
|
66
73
|
injectPrompt: boolean;
|
package/lib/index.mjs
CHANGED
|
@@ -26,10 +26,13 @@ const DEFAULT_PRESET_DIR = join(DSH_HOME, ".agent-presets", "prompt-tool");
|
|
|
26
26
|
const DEFAULT_SKILLS_DIR = SKILLS_DIR;
|
|
27
27
|
const DEFAULT_PRESET_ORDER = 5;
|
|
28
28
|
const DEFAULT_SKILL_RANK_BASE = 250;
|
|
29
|
+
/** 每轮引导文本框的默认内容:写入自动引导的两段文本。 */
|
|
30
|
+
const DEFAULT_GUIDE_TEXT = `简单任务自动引导:${"\nRouter: 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.".trim()}\n\n复杂任务自动引导:${"\nRouter: 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.".trim()}`;
|
|
29
31
|
const PRESET_TEMPLATE_META = fileURLToPath(new URL("../preset/preset.yml", import.meta.url));
|
|
30
32
|
const PRESET_TEMPLATE_INJECTOR = fileURLToPath(new URL("../preset/prompt-injector.mjs", import.meta.url));
|
|
31
33
|
const PRESET_TEMPLATE_ANCHOR = fileURLToPath(new URL("../preset/near-anchor.mjs", import.meta.url));
|
|
32
34
|
const PRESET_TEMPLATE_ROUTER = fileURLToPath(new URL("../preset/router-first-turn.mjs", import.meta.url));
|
|
35
|
+
const PRESET_TEMPLATE_GUIDE = fileURLToPath(new URL("../preset/router-guide.mjs", import.meta.url));
|
|
33
36
|
const VENDOR_PRESET_DIR = fileURLToPath(new URL("../upstream/dsh-anchored-standard/preset", import.meta.url));
|
|
34
37
|
const Config = z.object({
|
|
35
38
|
text: z.string().default(""),
|
|
@@ -42,10 +45,12 @@ const Config = z.object({
|
|
|
42
45
|
anchorFirstTurn: z.boolean().default(false),
|
|
43
46
|
anchorText: z.string().default(""),
|
|
44
47
|
anchorCustom: z.boolean().default(false),
|
|
48
|
+
guideText: z.string().default(DEFAULT_GUIDE_TEXT),
|
|
49
|
+
guideCustom: z.boolean().default(false),
|
|
45
50
|
subagentFlash: z.boolean().default(false),
|
|
46
51
|
subagentFlashProvider: z.string().default("deepseek-official"),
|
|
47
52
|
subagentFlashModel: z.string().default("deepseek-v4-flash"),
|
|
48
|
-
|
|
53
|
+
bootstrapMaxTokens: z.natural().default(0),
|
|
49
54
|
skillsDir: z.string().default(DEFAULT_SKILLS_DIR),
|
|
50
55
|
skillRankBase: z.natural().default(DEFAULT_SKILL_RANK_BASE),
|
|
51
56
|
residentAgentsPath: z.string().default(DEFAULT_RESIDENT_AGENTS_PATH),
|
|
@@ -62,7 +67,10 @@ const PromptSettingsSchema = z.object({
|
|
|
62
67
|
anchorFirstTurn: z.boolean().default(false),
|
|
63
68
|
anchorText: z.string().default(""),
|
|
64
69
|
anchorCustom: z.boolean().default(false),
|
|
70
|
+
guideText: z.string().default(DEFAULT_GUIDE_TEXT),
|
|
71
|
+
guideCustom: z.boolean().default(false),
|
|
65
72
|
subagentFlash: z.boolean().default(false),
|
|
73
|
+
bootstrapMaxTokens: z.natural().default(0),
|
|
66
74
|
deepseekAvailable: z.boolean().default(true),
|
|
67
75
|
injectPrompt: z.boolean().default(true),
|
|
68
76
|
skillSwitches: z.dict(z.boolean()).default({}),
|
|
@@ -286,7 +294,8 @@ const TUI_BOOLEAN_SWITCHES = [
|
|
|
286
294
|
["injectPrompt", "锚定确认后注入 preset.md"],
|
|
287
295
|
["injectAgentsPrompt", "用 AGENTS.md 替换 instruction-hint 提示"],
|
|
288
296
|
["anchorFirstTurn", "追加任务引导"],
|
|
289
|
-
["anchorCustom", "
|
|
297
|
+
["anchorCustom", "使用自定义引导(首句)"],
|
|
298
|
+
["guideCustom", "使用自定义引导(每轮)"],
|
|
290
299
|
["subagentFlash", "子代理固定 Flash 模型"]
|
|
291
300
|
];
|
|
292
301
|
/** 把布尔开关渲染成 dsh-tui 命令输出。 */
|
|
@@ -301,6 +310,7 @@ function renderTuiStatus(source) {
|
|
|
301
310
|
"锚点文本:",
|
|
302
311
|
` anchorText ${source.anchorText.length > 0 ? source.anchorText : "(空 = 按任务自动选择)"}`,
|
|
303
312
|
` deepseekAvailable ${source.deepseekAvailable ? "是" : "否(未检测到 DeepSeek 模型,subagentFlash 不可用)"}`,
|
|
313
|
+
` bootstrapMaxTokens ${source.bootstrapMaxTokens > 0 ? source.bootstrapMaxTokens : "0(关闭,不设封顶)"}`,
|
|
304
314
|
"技能开关:"
|
|
305
315
|
];
|
|
306
316
|
for (const skill of source.skillCatalog) {
|
|
@@ -325,7 +335,7 @@ function registerTuiCommand(ctx, getSource, getDeepseekAvailable, getDeepseekSta
|
|
|
325
335
|
handler: async (invocation) => {
|
|
326
336
|
const usage = () => ({
|
|
327
337
|
kind: "error",
|
|
328
|
-
text: "用法:/prompt-tool status\n /prompt-tool on|off|toggle <writeAgents|writePreset|injectPrompt|injectAgentsPrompt|anchorFirstTurn|anchorCustom|subagentFlash>\n /prompt-tool skill <技能目录名> on|off|toggle"
|
|
338
|
+
text: "用法:/prompt-tool status\n /prompt-tool on|off|toggle <writeAgents|writePreset|injectPrompt|injectAgentsPrompt|anchorFirstTurn|anchorCustom|guideCustom|subagentFlash>\n /prompt-tool skill <技能目录名> on|off|toggle\n /prompt-tool bootstrapMaxTokens <正整数|0(关闭)>"
|
|
329
339
|
});
|
|
330
340
|
const tokens = invocation.rawInput.trim().split(/\s+/).filter((token) => token.length > 0);
|
|
331
341
|
const source = getSource();
|
|
@@ -352,6 +362,25 @@ function registerTuiCommand(ctx, getSource, getDeepseekAvailable, getDeepseekSta
|
|
|
352
362
|
kind: "success",
|
|
353
363
|
text: `已把技能 ${folder} 设为 ${next ? "开" : "关"}
|
|
354
364
|
|
|
365
|
+
${renderTuiStatus(getSource())}`
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
if (tokens[0] === "bootstrapMaxTokens") {
|
|
369
|
+
const raw = tokens[1];
|
|
370
|
+
const value = raw === void 0 ? NaN : Number(raw);
|
|
371
|
+
if (!Number.isSafeInteger(value) || value < 0) return {
|
|
372
|
+
kind: "error",
|
|
373
|
+
text: "bootstrapMaxTokens 需要非负整数:0 关闭封顶,正整数设置首轮 maxTokens。"
|
|
374
|
+
};
|
|
375
|
+
await sctx.settings.mutate(NS, [{
|
|
376
|
+
op: "set",
|
|
377
|
+
path: ["bootstrapMaxTokens"],
|
|
378
|
+
value
|
|
379
|
+
}]);
|
|
380
|
+
return {
|
|
381
|
+
kind: "success",
|
|
382
|
+
text: `已把 bootstrapMaxTokens 设为 ${value === 0 ? "关闭(不设封顶)" : String(value)}
|
|
383
|
+
|
|
355
384
|
${renderTuiStatus(getSource())}`
|
|
356
385
|
};
|
|
357
386
|
}
|
|
@@ -654,11 +683,13 @@ function writePreset(prompt, options) {
|
|
|
654
683
|
anchorFirstTurn: options.anchorFirstTurn,
|
|
655
684
|
anchorText: options.anchorText,
|
|
656
685
|
anchorCustom: options.anchorCustom,
|
|
686
|
+
guideText: options.guideText,
|
|
687
|
+
guideCustom: options.guideCustom,
|
|
657
688
|
injectPrompt: options.injectPrompt,
|
|
658
689
|
subagentFlash: options.subagentFlash,
|
|
659
690
|
subagentFlashProvider: options.subagentFlashProvider,
|
|
660
691
|
subagentFlashModel: options.subagentFlashModel,
|
|
661
|
-
|
|
692
|
+
bootstrapMaxTokens: options.bootstrapMaxTokens
|
|
662
693
|
}), "utf8");
|
|
663
694
|
const meta = readFileSync(PRESET_TEMPLATE_META, "utf8").replace(/^order:.*$/m, `order: ${options.presetOrder}`);
|
|
664
695
|
writeFileSync(join(presetDir, "preset.yml"), meta, "utf8");
|
|
@@ -677,6 +708,7 @@ function writePreset(prompt, options) {
|
|
|
677
708
|
if (options.injectPrompt) writeFileSync(injectorPath, readFileSync(PRESET_TEMPLATE_INJECTOR, "utf8"), "utf8");
|
|
678
709
|
else rmSync(injectorPath, { force: true });
|
|
679
710
|
writeFileSync(join(presetDir, "router-first-turn.mjs"), readFileSync(PRESET_TEMPLATE_ROUTER, "utf8"), "utf8");
|
|
711
|
+
writeFileSync(join(presetDir, "router-guide.mjs"), readFileSync(PRESET_TEMPLATE_GUIDE, "utf8"), "utf8");
|
|
680
712
|
rmSync(join(presetDir, "turn-anchor.mjs"), { force: true });
|
|
681
713
|
const anchorPath = join(presetDir, "near-anchor.mjs");
|
|
682
714
|
if (options.anchorFirstTurn) writeFileSync(anchorPath, readFileSync(PRESET_TEMPLATE_ANCHOR, "utf8"), "utf8");
|
|
@@ -750,7 +782,10 @@ function apply(ctx, config) {
|
|
|
750
782
|
anchorFirstTurn: config.anchorFirstTurn,
|
|
751
783
|
anchorText: config.anchorText,
|
|
752
784
|
anchorCustom: config.anchorCustom,
|
|
753
|
-
|
|
785
|
+
guideText: config.guideText,
|
|
786
|
+
guideCustom: config.guideCustom,
|
|
787
|
+
subagentFlash: config.subagentFlash && getDeepseekAvailable(),
|
|
788
|
+
bootstrapMaxTokens: config.bootstrapMaxTokens
|
|
754
789
|
};
|
|
755
790
|
installSubagentFlashRoute(ctx, () => runtime.subagentFlash, config.subagentFlashProvider, config.subagentFlashModel);
|
|
756
791
|
let currentSource = () => ({
|
|
@@ -762,7 +797,10 @@ function apply(ctx, config) {
|
|
|
762
797
|
anchorFirstTurn: runtime.anchorFirstTurn,
|
|
763
798
|
anchorText: normalizeAnchorText(runtime.anchorText),
|
|
764
799
|
anchorCustom: runtime.anchorCustom,
|
|
800
|
+
guideText: runtime.guideText,
|
|
801
|
+
guideCustom: runtime.guideCustom,
|
|
765
802
|
subagentFlash: runtime.subagentFlash,
|
|
803
|
+
bootstrapMaxTokens: runtime.bootstrapMaxTokens,
|
|
766
804
|
deepseekAvailable: getDeepseekAvailable(),
|
|
767
805
|
injectPrompt: runtime.injectPrompt,
|
|
768
806
|
skillSwitches: runtime.skillSwitches,
|
|
@@ -783,12 +821,15 @@ function apply(ctx, config) {
|
|
|
783
821
|
anchorFirstTurn: typeof next.anchorFirstTurn === "boolean" ? next.anchorFirstTurn : config.anchorFirstTurn,
|
|
784
822
|
anchorText: normalizeAnchorText(typeof next.anchorText === "string" ? next.anchorText : config.anchorText),
|
|
785
823
|
anchorCustom: typeof next.anchorCustom === "boolean" ? next.anchorCustom : config.anchorCustom,
|
|
786
|
-
|
|
824
|
+
guideText: typeof next.guideText === "string" ? next.guideText : config.guideText,
|
|
825
|
+
guideCustom: typeof next.guideCustom === "boolean" ? next.guideCustom : config.guideCustom,
|
|
826
|
+
subagentFlash: (typeof next.subagentFlash === "boolean" ? next.subagentFlash : config.subagentFlash) && getDeepseekAvailable(),
|
|
827
|
+
bootstrapMaxTokens: Number.isSafeInteger(next.bootstrapMaxTokens) && next.bootstrapMaxTokens >= 0 ? next.bootstrapMaxTokens : config.bootstrapMaxTokens
|
|
787
828
|
};
|
|
788
829
|
const promptChanged = next.promptText !== current;
|
|
789
830
|
const agentsChanged = next.agentsText !== currentAgents;
|
|
790
831
|
const skillSwitchesChanged = JSON.stringify(runtime.skillSwitches) !== JSON.stringify(nextRuntime.skillSwitches);
|
|
791
|
-
const settingsChanged = runtime.writeAgents !== nextRuntime.writeAgents || runtime.writePreset !== nextRuntime.writePreset || runtime.injectAgentsPrompt !== nextRuntime.injectAgentsPrompt || runtime.injectPrompt !== nextRuntime.injectPrompt || skillSwitchesChanged || runtime.anchorFirstTurn !== nextRuntime.anchorFirstTurn || runtime.anchorText !== nextRuntime.anchorText || runtime.anchorCustom !== nextRuntime.anchorCustom || runtime.subagentFlash !== nextRuntime.subagentFlash;
|
|
832
|
+
const settingsChanged = runtime.writeAgents !== nextRuntime.writeAgents || runtime.writePreset !== nextRuntime.writePreset || runtime.injectAgentsPrompt !== nextRuntime.injectAgentsPrompt || runtime.injectPrompt !== nextRuntime.injectPrompt || skillSwitchesChanged || runtime.anchorFirstTurn !== nextRuntime.anchorFirstTurn || runtime.anchorText !== nextRuntime.anchorText || runtime.anchorCustom !== nextRuntime.anchorCustom || runtime.guideText !== nextRuntime.guideText || runtime.guideCustom !== nextRuntime.guideCustom || runtime.subagentFlash !== nextRuntime.subagentFlash || runtime.bootstrapMaxTokens !== nextRuntime.bootstrapMaxTokens;
|
|
792
833
|
if (!needsInitialApply && !promptChanged && !agentsChanged && !settingsChanged) return;
|
|
793
834
|
needsInitialApply = false;
|
|
794
835
|
if (promptChanged) current = next.promptText;
|
|
@@ -801,7 +842,10 @@ function apply(ctx, config) {
|
|
|
801
842
|
runtime.anchorFirstTurn = nextRuntime.anchorFirstTurn;
|
|
802
843
|
runtime.anchorText = nextRuntime.anchorText;
|
|
803
844
|
runtime.anchorCustom = nextRuntime.anchorCustom;
|
|
845
|
+
runtime.guideText = nextRuntime.guideText;
|
|
846
|
+
runtime.guideCustom = nextRuntime.guideCustom;
|
|
804
847
|
runtime.subagentFlash = nextRuntime.subagentFlash;
|
|
848
|
+
runtime.bootstrapMaxTokens = nextRuntime.bootstrapMaxTokens;
|
|
805
849
|
skillSwitches = runtime.skillSwitches;
|
|
806
850
|
if (skillSwitchesChanged) invalidateSkills?.();
|
|
807
851
|
let residentAgentsWritten = false;
|
|
@@ -816,11 +860,13 @@ function apply(ctx, config) {
|
|
|
816
860
|
anchorFirstTurn: runtime.anchorFirstTurn,
|
|
817
861
|
anchorText: runtime.anchorText,
|
|
818
862
|
anchorCustom: runtime.anchorCustom,
|
|
863
|
+
guideText: runtime.guideText,
|
|
864
|
+
guideCustom: runtime.guideCustom,
|
|
819
865
|
injectPrompt: runtime.injectPrompt,
|
|
820
866
|
subagentFlash: runtime.subagentFlash,
|
|
821
867
|
subagentFlashProvider: config.subagentFlashProvider,
|
|
822
868
|
subagentFlashModel: config.subagentFlashModel,
|
|
823
|
-
|
|
869
|
+
bootstrapMaxTokens: runtime.bootstrapMaxTokens,
|
|
824
870
|
agentsInstructionText: runtime.injectAgentsPrompt && currentAgents.length > 0 ? currentAgents : void 0,
|
|
825
871
|
presetDir: config.presetDir,
|
|
826
872
|
presetOrder: config.presetOrder
|
|
@@ -843,7 +889,10 @@ function apply(ctx, config) {
|
|
|
843
889
|
anchorFirstTurn: config.anchorFirstTurn,
|
|
844
890
|
anchorText: config.anchorText,
|
|
845
891
|
anchorCustom: config.anchorCustom,
|
|
892
|
+
guideText: config.guideText,
|
|
893
|
+
guideCustom: config.guideCustom,
|
|
846
894
|
subagentFlash: config.subagentFlash && getDeepseekAvailable(),
|
|
895
|
+
bootstrapMaxTokens: config.bootstrapMaxTokens,
|
|
847
896
|
deepseekAvailable: getDeepseekAvailable(),
|
|
848
897
|
injectPrompt: config.injectPrompt,
|
|
849
898
|
skillSwitches: { ...config.skillSwitches },
|
package/lib/preset-core.d.mts
CHANGED
|
@@ -16,6 +16,10 @@ interface BuildCordisOptions {
|
|
|
16
16
|
anchorText?: string;
|
|
17
17
|
/** 自定义锚点开关:true 固定使用 anchorText;false 按任务自动选择。 */
|
|
18
18
|
anchorCustom?: boolean;
|
|
19
|
+
/** 自定义每轮引导文本;guideCustom=true 时固定使用。 */
|
|
20
|
+
guideText?: string;
|
|
21
|
+
/** 自定义每轮引导开关:true 固定使用 guideText;false 按任务自动选择。 */
|
|
22
|
+
guideCustom?: boolean;
|
|
19
23
|
/** 锚定确认后注入 preset.md;关闭时仍保留工具引导,但不注册 prompt-injector 行。 */
|
|
20
24
|
injectPrompt?: boolean;
|
|
21
25
|
/** 子代理固定 Flash 模型:true 时给 subagent/subagent_fork 行加 agentOptions。 */
|
|
@@ -24,8 +28,8 @@ interface BuildCordisOptions {
|
|
|
24
28
|
subagentFlashProvider?: string;
|
|
25
29
|
/** 子代理 Flash 模型名(默认 deepseek-v4-flash)。 */
|
|
26
30
|
subagentFlashModel?: string;
|
|
27
|
-
/**
|
|
28
|
-
|
|
31
|
+
/** 首轮输出封顶(bootstrapMaxTokens);0 或未设置 = 本项目默认无封顶。 */
|
|
32
|
+
bootstrapMaxTokens?: number;
|
|
29
33
|
}
|
|
30
34
|
declare function buildCordis(prompt: string, options?: BuildCordisOptions): string;
|
|
31
35
|
//#endregion
|
package/lib/preset-core.mjs
CHANGED
|
@@ -13,6 +13,17 @@ const ROUTER_FIRST_TURN_BLOCK = `# prompt-tool 本地附加件(最优组合)
|
|
|
13
13
|
- id: router-first-turn
|
|
14
14
|
name: ./router-first-turn.mjs
|
|
15
15
|
`;
|
|
16
|
+
const ROUTER_GUIDE_BLOCK = `# Flash 主会话每轮近距离深度引导(dsh-router-standard 方案)。
|
|
17
|
+
# 模型为 Flash 且会话晋升后,每个真实用户消息之后追加固定引导。
|
|
18
|
+
# useCustom=true 时固定使用 text;false 按任务自动选择。
|
|
19
|
+
- id: router-guide
|
|
20
|
+
name: ./router-guide.mjs
|
|
21
|
+
config:
|
|
22
|
+
text: |-
|
|
23
|
+
__GUIDE_TEXT__
|
|
24
|
+
useCustom: __USE_GUIDE_CUSTOM__
|
|
25
|
+
enabled: __GUIDE_ENABLED__
|
|
26
|
+
`;
|
|
16
27
|
const NEAR_ANCHOR_BLOCK = `# prompt-tool 近距离首句锚定:在首条真实用户消息之后追加一次性锚点。
|
|
17
28
|
# 不拆轮、不挪任务;useCustom=false 时按任务自动选择 we/let 首句,
|
|
18
29
|
# useCustom=true 时固定使用 anchorText。
|
|
@@ -71,15 +82,20 @@ function normalizeContextGate(source) {
|
|
|
71
82
|
config:
|
|
72
83
|
promoteOn: either
|
|
73
84
|
includeSubagents: false
|
|
74
|
-
allowKinds: [skill-invocation, near-anchor]`;
|
|
85
|
+
allowKinds: [skill-invocation, near-anchor, router-guide]`;
|
|
75
86
|
if (!source.includes(block)) throw new Error("vendor agent.cordis.yml missing context-gate row");
|
|
76
87
|
return source.replace(block, replaced);
|
|
77
88
|
}
|
|
78
|
-
/**
|
|
79
|
-
function
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
89
|
+
/** 按开关向上游 tool-bootstrap 行注入 bootstrapMaxTokens;0/未设置保持无封顶。 */
|
|
90
|
+
function applyBootstrapMaxTokens(source, value) {
|
|
91
|
+
if (value === void 0 || !Number.isSafeInteger(value) || value <= 0) return source;
|
|
92
|
+
const rowStart = source.indexOf("- id: tool-bootstrap\n name: ./tool-bootstrap.mjs\n config:\n");
|
|
93
|
+
if (rowStart < 0) throw new Error("vendor agent.cordis.yml missing tool-bootstrap config block");
|
|
94
|
+
const include = source.indexOf(" includeSubagents: true\n", rowStart);
|
|
95
|
+
if (include < 0) throw new Error("vendor agent.cordis.yml tool-bootstrap row missing includeSubagents");
|
|
96
|
+
const at = include + 26 + 1;
|
|
97
|
+
return source.slice(0, at) + ` bootstrapMaxTokens: ${value}
|
|
98
|
+
` + source.slice(at);
|
|
83
99
|
}
|
|
84
100
|
/** 给 subagent/subagent_fork 行加 dsh-router-standard 的 Flash 子代理方案;关闭时保持继承主会话路由。 */
|
|
85
101
|
function applySubagentFlash(source, enabled, provider, model) {
|
|
@@ -117,10 +133,12 @@ ${persona}`;
|
|
|
117
133
|
function buildCordis(prompt, options = {}) {
|
|
118
134
|
const anchorFirstTurn = options.anchorFirstTurn === true;
|
|
119
135
|
const anchorCustom = options.anchorCustom === true;
|
|
136
|
+
const guideCustom = options.guideCustom === true;
|
|
137
|
+
const guideText = typeof options.guideText === "string" && options.guideText.length > 0 ? options.guideText : "";
|
|
120
138
|
const injectPrompt = options.injectPrompt !== false;
|
|
121
139
|
const anchorText = typeof options.anchorText === "string" && options.anchorText.length > 0 ? options.anchorText : "";
|
|
122
140
|
const indent = (s) => s.split(/\r?\n/).map((l) => l.length === 0 ? "" : " " + l).join("\n");
|
|
123
|
-
const up = normalizeContextGate(
|
|
141
|
+
const up = applyBootstrapMaxTokens(normalizeContextGate(applySubagentFlash(readFileSync(VENDOR_CORDIS, "utf8").replace(/\r\n/g, "\n"), options.subagentFlash === true, typeof options.subagentFlashProvider === "string" && options.subagentFlashProvider.length > 0 ? options.subagentFlashProvider : "deepseek-official", typeof options.subagentFlashModel === "string" && options.subagentFlashModel.length > 0 ? options.subagentFlashModel : "deepseek-v4-flash")), options.bootstrapMaxTokens);
|
|
124
142
|
const bootstrap = /^-\s+id:\s+tool-bootstrap\s*$/m.exec(up);
|
|
125
143
|
if (!bootstrap) throw new Error("vendor agent.cordis.yml missing tool-bootstrap row");
|
|
126
144
|
let cursor = up.indexOf("\n", bootstrap.index);
|
|
@@ -141,7 +159,8 @@ function buildCordis(prompt, options = {}) {
|
|
|
141
159
|
const head = up.slice(0, insertAt);
|
|
142
160
|
const tail = up.slice(insertAt);
|
|
143
161
|
const separator = head.endsWith("\n\n") ? "" : head.endsWith("\n") ? "\n" : "\n\n";
|
|
144
|
-
const
|
|
162
|
+
const guideBlock = ROUTER_GUIDE_BLOCK.replace(" useCustom: __USE_GUIDE_CUSTOM__", ` useCustom: ${anchorFirstTurn && guideCustom}`).replace(" enabled: __GUIDE_ENABLED__", ` enabled: ${anchorFirstTurn}`).replace(" text: |-\n __GUIDE_TEXT__", " text: |-\n" + (guideText.length > 0 ? indent(guideText) : " "));
|
|
163
|
+
const parts = [ROUTER_FIRST_TURN_BLOCK, guideBlock];
|
|
145
164
|
if (anchorFirstTurn) {
|
|
146
165
|
const anchorMarker = " anchorText: |-\n __ANCHOR_TEXT__";
|
|
147
166
|
if (!NEAR_ANCHOR_BLOCK.includes(anchorMarker)) throw new Error("internal error: near-anchor template lost its anchorText placeholder");
|
|
@@ -155,7 +174,7 @@ function buildCordis(prompt, options = {}) {
|
|
|
155
174
|
}
|
|
156
175
|
const extra = parts.join("\n");
|
|
157
176
|
const out = head + separator + extra + "\n" + tail;
|
|
158
|
-
if (injectPrompt && out.includes("__PROMPT_TOOL_TEXT__") || anchorFirstTurn && (out.includes("__ANCHOR_TEXT__") || out.includes("__USE_CUSTOM__"))) throw new Error("internal error: preset template placeholder was not replaced");
|
|
177
|
+
if (injectPrompt && out.includes("__PROMPT_TOOL_TEXT__") || anchorFirstTurn && (out.includes("__ANCHOR_TEXT__") || out.includes("__USE_CUSTOM__")) || out.includes("__GUIDE_TEXT__") || out.includes("__USE_GUIDE_CUSTOM__") || out.includes("__GUIDE_ENABLED__")) throw new Error("internal error: preset template placeholder was not replaced");
|
|
159
178
|
let parsed;
|
|
160
179
|
try {
|
|
161
180
|
parsed = parse(out, { logLevel: "silent" });
|
package/package.json
CHANGED
package/plan.md
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
# dsh-plugin-prompt-tool 重新设计计划(v2)
|
|
2
|
+
> **v2.15 上游同步(当前实现)**:同步上游到 `25f21ae`;移除
|
|
3
|
+
> `customBashPath` 生成时改写,直接沿用上游 custom-bash 运行时探测。
|
|
4
|
+
> 新增 `bootstrapMaxTokens` 开关(0=关闭;正整数写入上游 tool-bootstrap)。
|
|
5
|
+
|
|
2
6
|
> **v2.14 上游同步与路径校对(当前实现)**:已从上游 main 同步到
|
|
3
7
|
> `ba7a27c`;新增 context-gate.mjs;custom-bash 的固定路径在生成时归一化为
|
|
4
8
|
> `customBashPath`(默认 bash.exe,PATH 查找)。
|