@pencil-agent/nano-pencil 0.0.3 → 0.0.4

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.

Potentially problematic release.


This version of @pencil-agent/nano-pencil might be problematic. Click here for more details.

package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # NanoPencil
2
2
 
3
- 写作 Agent,可写一切:文章、论文、代码等。支持 readbasheditwrite 工具与会话管理,基于 [pi](https://github.com/badlogic/pi-mono) 定制,当前仅支持阿里云百炼 Coding Plan
3
+ CLI writing agent with read, bash, edit, write tools and session management. Based on [pi](https://github.com/badlogic/pi-mono); supports DashScope Coding Plan only.
4
4
 
5
5
  ## 安装
6
6
 
@@ -1 +1 @@
1
- {"version":3,"file":"system-prompt.d.ts","sourceRoot":"","sources":["../../src/core/system-prompt.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAyB,KAAK,KAAK,EAAE,MAAM,aAAa,CAAC;AAahE,MAAM,WAAW,wBAAwB;IACxC,iDAAqB;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oEAA4C;IAC5C,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,wCAAkB;IAClB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,4CAA4B;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,qCAAiB;IACjB,YAAY,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxD,4BAAc;IACd,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;CACjB;AAED,0DAAwB;AACxB,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,wBAA6B,GAAG,MAAM,CAuJhF","sourcesContent":["/**\n * 系统提示词构建与项目上下文加载\n */\n\nimport { getDocsPath, getExamplesPath, getReadmePath } from \"../config.js\";\nimport { formatSkillsForPrompt, type Skill } from \"./skills.js\";\n\n/** 工具描述(用于系统提示) */\nconst toolDescriptions: Record<string, string> = {\n\tread: \"读取文件内容\",\n\tbash: \"执行 bash 命令(ls、grep、find 等)\",\n\tedit: \"对文件进行精确编辑(查找精确文本并替换)\",\n\twrite: \"创建或覆盖文件\",\n\tgrep: \"在文件内容中搜索模式(遵守 .gitignore)\",\n\tfind: \"按 glob 模式查找文件(遵守 .gitignore)\",\n\tls: \"列出目录内容\",\n};\n\nexport interface BuildSystemPromptOptions {\n\t/** 自定义系统提示(替换默认)。 */\n\tcustomPrompt?: string;\n\t/** 要纳入提示的工具。默认:[read, bash, edit, write] */\n\tselectedTools?: string[];\n\t/** 追加到系统提示的文本。 */\n\tappendSystemPrompt?: string;\n\t/** 工作目录。默认:process.cwd() */\n\tcwd?: string;\n\t/** 预加载的上下文文件。 */\n\tcontextFiles?: Array<{ path: string; content: string }>;\n\t/** 预加载的技能。 */\n\tskills?: Skill[];\n}\n\n/** 根据工具、规范与上下文构建系统提示 */\nexport function buildSystemPrompt(options: BuildSystemPromptOptions = {}): string {\n\tconst {\n\t\tcustomPrompt,\n\t\tselectedTools,\n\t\tappendSystemPrompt,\n\t\tcwd,\n\t\tcontextFiles: providedContextFiles,\n\t\tskills: providedSkills,\n\t} = options;\n\tconst resolvedCwd = cwd ?? process.cwd();\n\n\tconst now = new Date();\n\tconst dateTime = now.toLocaleString(\"en-US\", {\n\t\tweekday: \"long\",\n\t\tyear: \"numeric\",\n\t\tmonth: \"long\",\n\t\tday: \"numeric\",\n\t\thour: \"2-digit\",\n\t\tminute: \"2-digit\",\n\t\tsecond: \"2-digit\",\n\t\ttimeZoneName: \"short\",\n\t});\n\n\tconst appendSection = appendSystemPrompt ? `\\n\\n${appendSystemPrompt}` : \"\";\n\n\tconst contextFiles = providedContextFiles ?? [];\n\tconst skills = providedSkills ?? [];\n\n\tif (customPrompt) {\n\t\tlet prompt = customPrompt;\n\n\t\tif (appendSection) {\n\t\t\tprompt += appendSection;\n\t\t}\n\n\t\t// 追加项目上下文文件\n\t\tif (contextFiles.length > 0) {\n\t\t\tprompt += \"\\n\\n# 项目上下文\\n\\n\";\n\t\t\tprompt += \"项目相关说明与规范:\\n\\n\";\n\t\t\tfor (const { path: filePath, content } of contextFiles) {\n\t\t\t\tprompt += `## ${filePath}\\n\\n${content}\\n\\n`;\n\t\t\t}\n\t\t}\n\n\t\t// 追加技能段落(仅当具备 read 工具时)\n\t\tconst customPromptHasRead = !selectedTools || selectedTools.includes(\"read\");\n\t\tif (customPromptHasRead && skills.length > 0) {\n\t\t\tprompt += formatSkillsForPrompt(skills);\n\t\t}\n\n\t\t// 最后追加日期时间与工作目录\n\t\tprompt += `\\n当前日期与时间:${dateTime}`;\n\t\tprompt += `\\n当前工作目录:${resolvedCwd}`;\n\n\t\treturn prompt;\n\t}\n\n\t// 获取文档与示例的绝对路径\n\tconst readmePath = getReadmePath();\n\tconst docsPath = getDocsPath();\n\tconst examplesPath = getExamplesPath();\n\n\t// 根据所选工具构建工具列表(仅包含有描述的内置工具)\n\tconst tools = (selectedTools || [\"read\", \"bash\", \"edit\", \"write\"]).filter((t) => t in toolDescriptions);\n\tconst toolsList = tools.length > 0 ? tools.map((t) => `- ${t}: ${toolDescriptions[t]}`).join(\"\\n\") : \"(无)\";\n\n\t// 根据实际可用工具构建规范\n\tconst guidelinesList: string[] = [];\n\n\tconst hasBash = tools.includes(\"bash\");\n\tconst hasEdit = tools.includes(\"edit\");\n\tconst hasWrite = tools.includes(\"write\");\n\tconst hasGrep = tools.includes(\"grep\");\n\tconst hasFind = tools.includes(\"find\");\n\tconst hasLs = tools.includes(\"ls\");\n\tconst hasRead = tools.includes(\"read\");\n\n\t// 文件探索相关规范\n\tif (hasBash && !hasGrep && !hasFind && !hasLs) {\n\t\tguidelinesList.push(\"使用 bash 进行 ls、rg、find 等文件操作\");\n\t} else if (hasBash && (hasGrep || hasFind || hasLs)) {\n\t\tguidelinesList.push(\"优先使用 grep/find/ls 工具进行文件探索(更快,且遵守 .gitignore)\");\n\t}\n\n\t// 先读后编规范\n\tif (hasRead && hasEdit) {\n\t\tguidelinesList.push(\"编辑前先用 read 查看文件内容,必须使用该工具,不要用 cat 或 sed。\");\n\t}\n\n\t// 编辑规范\n\tif (hasEdit) {\n\t\tguidelinesList.push(\"使用 edit 做精确修改(旧文本必须完全匹配)\");\n\t}\n\n\t// 写入规范\n\tif (hasWrite) {\n\t\tguidelinesList.push(\"仅在创建新文件或完整重写时使用 write\");\n\t}\n\n\t// 输出规范(仅在实际写入或执行时)\n\tif (hasEdit || hasWrite) {\n\t\tguidelinesList.push(\"总结你的操作时,请直接输出纯文本,不要用 cat 或 bash 来展示你做了什么\");\n\t}\n\n\t// 始终包含以下项\n\tguidelinesList.push(\"回复请简洁\");\n\tguidelinesList.push(\"操作文件时请清晰标注文件路径\");\n\n\tconst guidelines = guidelinesList.map((g) => `- ${g}`).join(\"\\n\");\n\n\tlet prompt = `你是 nano-pencil 中的写作助手,定位为用户身边的写作专家。你通过读文件、执行命令、编辑与撰写文本来帮助用户。\n\n可用工具:\n${toolsList}\n\n除上述工具外,根据项目配置你可能还能使用其他自定义工具。\n\n规范:\n${guidelines}\n\n以下文档仅在用户询问 nano-pencil、SDK、扩展、主题、技能或 TUI 时阅读:\n- 主文档:${readmePath}\n- 更多文档:${docsPath}\n- 示例:${examplesPath}(扩展、自定义工具、SDK)\n- 被问及:扩展(docs/extensions.md, examples/extensions/)、主题(docs/themes.md)、技能(docs/skills.md)、提示模板(docs/prompt-templates.md)、TUI 组件(docs/tui.md)、键绑定(docs/keybindings.md)、SDK 集成(docs/sdk.md)、自定义提供商(docs/custom-provider.md)、添加模型(docs/models.md)、包(docs/packages.md)\n- 处理相关主题时,先阅读文档与示例,并按 .md 中的交叉引用操作后再实现\n- 务必完整阅读 .md 文件并跟随相关链接(例如 TUI API 细节见 tui.md)`;\n\n\tif (appendSection) {\n\t\tprompt += appendSection;\n\t}\n\n\t// 追加项目上下文文件\n\tif (contextFiles.length > 0) {\n\t\tprompt += \"\\n\\n# 项目上下文\\n\\n\";\n\t\tprompt += \"项目相关说明与规范:\\n\\n\";\n\t\tfor (const { path: filePath, content } of contextFiles) {\n\t\t\tprompt += `## ${filePath}\\n\\n${content}\\n\\n`;\n\t\t}\n\t}\n\n\t// 追加技能段落(仅当具备 read 工具时)\n\tif (hasRead && skills.length > 0) {\n\t\tprompt += formatSkillsForPrompt(skills);\n\t}\n\n\t// 最后追加日期时间与工作目录\n\tprompt += `\\n当前日期与时间:${dateTime}`;\n\tprompt += `\\n当前工作目录:${resolvedCwd}`;\n\n\treturn prompt;\n}\n"]}
1
+ {"version":3,"file":"system-prompt.d.ts","sourceRoot":"","sources":["../../src/core/system-prompt.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAyB,KAAK,KAAK,EAAE,MAAM,aAAa,CAAC;AAahE,MAAM,WAAW,wBAAwB;IACxC,iDAAqB;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oEAA4C;IAC5C,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,wCAAkB;IAClB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,4CAA4B;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,qCAAiB;IACjB,YAAY,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxD,4BAAc;IACd,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;CACjB;AAED,0DAAwB;AACxB,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,wBAA6B,GAAG,MAAM,CAuJhF","sourcesContent":["/**\n * 系统提示词构建与项目上下文加载\n */\n\nimport { getDocsPath, getExamplesPath, getReadmePath } from \"../config.js\";\nimport { formatSkillsForPrompt, type Skill } from \"./skills.js\";\n\n/** 工具描述(用于系统提示) */\nconst toolDescriptions: Record<string, string> = {\n\tread: \"读取文件内容\",\n\tbash: \"执行 bash 命令(ls、grep、find 等)\",\n\tedit: \"对文件进行精确编辑(查找精确文本并替换)\",\n\twrite: \"创建或覆盖文件\",\n\tgrep: \"在文件内容中搜索模式(遵守 .gitignore)\",\n\tfind: \"按 glob 模式查找文件(遵守 .gitignore)\",\n\tls: \"列出目录内容\",\n};\n\nexport interface BuildSystemPromptOptions {\n\t/** 自定义系统提示(替换默认)。 */\n\tcustomPrompt?: string;\n\t/** 要纳入提示的工具。默认:[read, bash, edit, write] */\n\tselectedTools?: string[];\n\t/** 追加到系统提示的文本。 */\n\tappendSystemPrompt?: string;\n\t/** 工作目录。默认:process.cwd() */\n\tcwd?: string;\n\t/** 预加载的上下文文件。 */\n\tcontextFiles?: Array<{ path: string; content: string }>;\n\t/** 预加载的技能。 */\n\tskills?: Skill[];\n}\n\n/** 根据工具、规范与上下文构建系统提示 */\nexport function buildSystemPrompt(options: BuildSystemPromptOptions = {}): string {\n\tconst {\n\t\tcustomPrompt,\n\t\tselectedTools,\n\t\tappendSystemPrompt,\n\t\tcwd,\n\t\tcontextFiles: providedContextFiles,\n\t\tskills: providedSkills,\n\t} = options;\n\tconst resolvedCwd = cwd ?? process.cwd();\n\n\tconst now = new Date();\n\tconst dateTime = now.toLocaleString(\"en-US\", {\n\t\tweekday: \"long\",\n\t\tyear: \"numeric\",\n\t\tmonth: \"long\",\n\t\tday: \"numeric\",\n\t\thour: \"2-digit\",\n\t\tminute: \"2-digit\",\n\t\tsecond: \"2-digit\",\n\t\ttimeZoneName: \"short\",\n\t});\n\n\tconst appendSection = appendSystemPrompt ? `\\n\\n${appendSystemPrompt}` : \"\";\n\n\tconst contextFiles = providedContextFiles ?? [];\n\tconst skills = providedSkills ?? [];\n\n\tif (customPrompt) {\n\t\tlet prompt = customPrompt;\n\n\t\tif (appendSection) {\n\t\t\tprompt += appendSection;\n\t\t}\n\n\t\t// 追加项目上下文文件\n\t\tif (contextFiles.length > 0) {\n\t\t\tprompt += \"\\n\\n# 项目上下文\\n\\n\";\n\t\t\tprompt += \"项目相关说明与规范:\\n\\n\";\n\t\t\tfor (const { path: filePath, content } of contextFiles) {\n\t\t\t\tprompt += `## ${filePath}\\n\\n${content}\\n\\n`;\n\t\t\t}\n\t\t}\n\n\t\t// 追加技能段落(仅当具备 read 工具时)\n\t\tconst customPromptHasRead = !selectedTools || selectedTools.includes(\"read\");\n\t\tif (customPromptHasRead && skills.length > 0) {\n\t\t\tprompt += formatSkillsForPrompt(skills);\n\t\t}\n\n\t\t// 最后追加日期时间与工作目录\n\t\tprompt += `\\n当前日期与时间:${dateTime}`;\n\t\tprompt += `\\n当前工作目录:${resolvedCwd}`;\n\n\t\treturn prompt;\n\t}\n\n\t// 获取文档与示例的绝对路径\n\tconst readmePath = getReadmePath();\n\tconst docsPath = getDocsPath();\n\tconst examplesPath = getExamplesPath();\n\n\t// 根据所选工具构建工具列表(仅包含有描述的内置工具)\n\tconst tools = (selectedTools || [\"read\", \"bash\", \"edit\", \"write\"]).filter((t) => t in toolDescriptions);\n\tconst toolsList = tools.length > 0 ? tools.map((t) => `- ${t}: ${toolDescriptions[t]}`).join(\"\\n\") : \"(无)\";\n\n\t// 根据实际可用工具构建规范\n\tconst guidelinesList: string[] = [];\n\n\tconst hasBash = tools.includes(\"bash\");\n\tconst hasEdit = tools.includes(\"edit\");\n\tconst hasWrite = tools.includes(\"write\");\n\tconst hasGrep = tools.includes(\"grep\");\n\tconst hasFind = tools.includes(\"find\");\n\tconst hasLs = tools.includes(\"ls\");\n\tconst hasRead = tools.includes(\"read\");\n\n\t// 文件探索相关规范\n\tif (hasBash && !hasGrep && !hasFind && !hasLs) {\n\t\tguidelinesList.push(\"使用 bash 进行 ls、rg、find 等文件操作\");\n\t} else if (hasBash && (hasGrep || hasFind || hasLs)) {\n\t\tguidelinesList.push(\"优先使用 grep/find/ls 工具进行文件探索(更快,且遵守 .gitignore)\");\n\t}\n\n\t// 先读后编规范\n\tif (hasRead && hasEdit) {\n\t\tguidelinesList.push(\"编辑前先用 read 查看文件内容,必须使用该工具,不要用 cat 或 sed。\");\n\t}\n\n\t// 编辑规范\n\tif (hasEdit) {\n\t\tguidelinesList.push(\"使用 edit 做精确修改(旧文本必须完全匹配)\");\n\t}\n\n\t// 写入规范\n\tif (hasWrite) {\n\t\tguidelinesList.push(\"仅在创建新文件或完整重写时使用 write\");\n\t}\n\n\t// 输出规范(仅在实际写入或执行时)\n\tif (hasEdit || hasWrite) {\n\t\tguidelinesList.push(\"总结你的操作时,请直接输出纯文本,不要用 cat 或 bash 来展示你做了什么\");\n\t}\n\n\t// 始终包含以下项\n\tguidelinesList.push(\"回复请简洁\");\n\tguidelinesList.push(\"操作文件时请清晰标注文件路径\");\n\n\tconst guidelines = guidelinesList.map((g) => `- ${g}`).join(\"\\n\");\n\n\tlet prompt = `You are the writing assistant in nanopencil. You help users by reading files, running commands, editing and writing text.\n\n可用工具:\n${toolsList}\n\n除上述工具外,根据项目配置你可能还能使用其他自定义工具。\n\n规范:\n${guidelines}\n\n以下文档仅在用户询问 nano-pencil、SDK、扩展、主题、技能或 TUI 时阅读:\n- 主文档:${readmePath}\n- 更多文档:${docsPath}\n- 示例:${examplesPath}(扩展、自定义工具、SDK)\n- 被问及:扩展(docs/extensions.md, examples/extensions/)、主题(docs/themes.md)、技能(docs/skills.md)、提示模板(docs/prompt-templates.md)、TUI 组件(docs/tui.md)、键绑定(docs/keybindings.md)、SDK 集成(docs/sdk.md)、自定义提供商(docs/custom-provider.md)、添加模型(docs/models.md)、包(docs/packages.md)\n- 处理相关主题时,先阅读文档与示例,并按 .md 中的交叉引用操作后再实现\n- 务必完整阅读 .md 文件并跟随相关链接(例如 TUI API 细节见 tui.md)`;\n\n\tif (appendSection) {\n\t\tprompt += appendSection;\n\t}\n\n\t// 追加项目上下文文件\n\tif (contextFiles.length > 0) {\n\t\tprompt += \"\\n\\n# 项目上下文\\n\\n\";\n\t\tprompt += \"项目相关说明与规范:\\n\\n\";\n\t\tfor (const { path: filePath, content } of contextFiles) {\n\t\t\tprompt += `## ${filePath}\\n\\n${content}\\n\\n`;\n\t\t}\n\t}\n\n\t// 追加技能段落(仅当具备 read 工具时)\n\tif (hasRead && skills.length > 0) {\n\t\tprompt += formatSkillsForPrompt(skills);\n\t}\n\n\t// 最后追加日期时间与工作目录\n\tprompt += `\\n当前日期与时间:${dateTime}`;\n\tprompt += `\\n当前工作目录:${resolvedCwd}`;\n\n\treturn prompt;\n}\n"]}
@@ -97,7 +97,7 @@ export function buildSystemPrompt(options = {}) {
97
97
  guidelinesList.push("回复请简洁");
98
98
  guidelinesList.push("操作文件时请清晰标注文件路径");
99
99
  const guidelines = guidelinesList.map((g) => `- ${g}`).join("\n");
100
- let prompt = `你是 nano-pencil 中的写作助手,定位为用户身边的写作专家。你通过读文件、执行命令、编辑与撰写文本来帮助用户。
100
+ let prompt = `You are the writing assistant in nanopencil. You help users by reading files, running commands, editing and writing text.
101
101
 
102
102
  可用工具:
103
103
  ${toolsList}
@@ -1 +1 @@
1
- {"version":3,"file":"system-prompt.js","sourceRoot":"","sources":["../../src/core/system-prompt.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * 系统提示词构建与项目上下文加载\n */\n\nimport { getDocsPath, getExamplesPath, getReadmePath } from \"../config.js\";\nimport { formatSkillsForPrompt, type Skill } from \"./skills.js\";\n\n/** 工具描述(用于系统提示) */\nconst toolDescriptions: Record<string, string> = {\n\tread: \"读取文件内容\",\n\tbash: \"执行 bash 命令(ls、grep、find 等)\",\n\tedit: \"对文件进行精确编辑(查找精确文本并替换)\",\n\twrite: \"创建或覆盖文件\",\n\tgrep: \"在文件内容中搜索模式(遵守 .gitignore)\",\n\tfind: \"按 glob 模式查找文件(遵守 .gitignore)\",\n\tls: \"列出目录内容\",\n};\n\nexport interface BuildSystemPromptOptions {\n\t/** 自定义系统提示(替换默认)。 */\n\tcustomPrompt?: string;\n\t/** 要纳入提示的工具。默认:[read, bash, edit, write] */\n\tselectedTools?: string[];\n\t/** 追加到系统提示的文本。 */\n\tappendSystemPrompt?: string;\n\t/** 工作目录。默认:process.cwd() */\n\tcwd?: string;\n\t/** 预加载的上下文文件。 */\n\tcontextFiles?: Array<{ path: string; content: string }>;\n\t/** 预加载的技能。 */\n\tskills?: Skill[];\n}\n\n/** 根据工具、规范与上下文构建系统提示 */\nexport function buildSystemPrompt(options: BuildSystemPromptOptions = {}): string {\n\tconst {\n\t\tcustomPrompt,\n\t\tselectedTools,\n\t\tappendSystemPrompt,\n\t\tcwd,\n\t\tcontextFiles: providedContextFiles,\n\t\tskills: providedSkills,\n\t} = options;\n\tconst resolvedCwd = cwd ?? process.cwd();\n\n\tconst now = new Date();\n\tconst dateTime = now.toLocaleString(\"en-US\", {\n\t\tweekday: \"long\",\n\t\tyear: \"numeric\",\n\t\tmonth: \"long\",\n\t\tday: \"numeric\",\n\t\thour: \"2-digit\",\n\t\tminute: \"2-digit\",\n\t\tsecond: \"2-digit\",\n\t\ttimeZoneName: \"short\",\n\t});\n\n\tconst appendSection = appendSystemPrompt ? `\\n\\n${appendSystemPrompt}` : \"\";\n\n\tconst contextFiles = providedContextFiles ?? [];\n\tconst skills = providedSkills ?? [];\n\n\tif (customPrompt) {\n\t\tlet prompt = customPrompt;\n\n\t\tif (appendSection) {\n\t\t\tprompt += appendSection;\n\t\t}\n\n\t\t// 追加项目上下文文件\n\t\tif (contextFiles.length > 0) {\n\t\t\tprompt += \"\\n\\n# 项目上下文\\n\\n\";\n\t\t\tprompt += \"项目相关说明与规范:\\n\\n\";\n\t\t\tfor (const { path: filePath, content } of contextFiles) {\n\t\t\t\tprompt += `## ${filePath}\\n\\n${content}\\n\\n`;\n\t\t\t}\n\t\t}\n\n\t\t// 追加技能段落(仅当具备 read 工具时)\n\t\tconst customPromptHasRead = !selectedTools || selectedTools.includes(\"read\");\n\t\tif (customPromptHasRead && skills.length > 0) {\n\t\t\tprompt += formatSkillsForPrompt(skills);\n\t\t}\n\n\t\t// 最后追加日期时间与工作目录\n\t\tprompt += `\\n当前日期与时间:${dateTime}`;\n\t\tprompt += `\\n当前工作目录:${resolvedCwd}`;\n\n\t\treturn prompt;\n\t}\n\n\t// 获取文档与示例的绝对路径\n\tconst readmePath = getReadmePath();\n\tconst docsPath = getDocsPath();\n\tconst examplesPath = getExamplesPath();\n\n\t// 根据所选工具构建工具列表(仅包含有描述的内置工具)\n\tconst tools = (selectedTools || [\"read\", \"bash\", \"edit\", \"write\"]).filter((t) => t in toolDescriptions);\n\tconst toolsList = tools.length > 0 ? tools.map((t) => `- ${t}: ${toolDescriptions[t]}`).join(\"\\n\") : \"(无)\";\n\n\t// 根据实际可用工具构建规范\n\tconst guidelinesList: string[] = [];\n\n\tconst hasBash = tools.includes(\"bash\");\n\tconst hasEdit = tools.includes(\"edit\");\n\tconst hasWrite = tools.includes(\"write\");\n\tconst hasGrep = tools.includes(\"grep\");\n\tconst hasFind = tools.includes(\"find\");\n\tconst hasLs = tools.includes(\"ls\");\n\tconst hasRead = tools.includes(\"read\");\n\n\t// 文件探索相关规范\n\tif (hasBash && !hasGrep && !hasFind && !hasLs) {\n\t\tguidelinesList.push(\"使用 bash 进行 ls、rg、find 等文件操作\");\n\t} else if (hasBash && (hasGrep || hasFind || hasLs)) {\n\t\tguidelinesList.push(\"优先使用 grep/find/ls 工具进行文件探索(更快,且遵守 .gitignore)\");\n\t}\n\n\t// 先读后编规范\n\tif (hasRead && hasEdit) {\n\t\tguidelinesList.push(\"编辑前先用 read 查看文件内容,必须使用该工具,不要用 cat 或 sed。\");\n\t}\n\n\t// 编辑规范\n\tif (hasEdit) {\n\t\tguidelinesList.push(\"使用 edit 做精确修改(旧文本必须完全匹配)\");\n\t}\n\n\t// 写入规范\n\tif (hasWrite) {\n\t\tguidelinesList.push(\"仅在创建新文件或完整重写时使用 write\");\n\t}\n\n\t// 输出规范(仅在实际写入或执行时)\n\tif (hasEdit || hasWrite) {\n\t\tguidelinesList.push(\"总结你的操作时,请直接输出纯文本,不要用 cat 或 bash 来展示你做了什么\");\n\t}\n\n\t// 始终包含以下项\n\tguidelinesList.push(\"回复请简洁\");\n\tguidelinesList.push(\"操作文件时请清晰标注文件路径\");\n\n\tconst guidelines = guidelinesList.map((g) => `- ${g}`).join(\"\\n\");\n\n\tlet prompt = `你是 nano-pencil 中的写作助手,定位为用户身边的写作专家。你通过读文件、执行命令、编辑与撰写文本来帮助用户。\n\n可用工具:\n${toolsList}\n\n除上述工具外,根据项目配置你可能还能使用其他自定义工具。\n\n规范:\n${guidelines}\n\n以下文档仅在用户询问 nano-pencil、SDK、扩展、主题、技能或 TUI 时阅读:\n- 主文档:${readmePath}\n- 更多文档:${docsPath}\n- 示例:${examplesPath}(扩展、自定义工具、SDK)\n- 被问及:扩展(docs/extensions.md, examples/extensions/)、主题(docs/themes.md)、技能(docs/skills.md)、提示模板(docs/prompt-templates.md)、TUI 组件(docs/tui.md)、键绑定(docs/keybindings.md)、SDK 集成(docs/sdk.md)、自定义提供商(docs/custom-provider.md)、添加模型(docs/models.md)、包(docs/packages.md)\n- 处理相关主题时,先阅读文档与示例,并按 .md 中的交叉引用操作后再实现\n- 务必完整阅读 .md 文件并跟随相关链接(例如 TUI API 细节见 tui.md)`;\n\n\tif (appendSection) {\n\t\tprompt += appendSection;\n\t}\n\n\t// 追加项目上下文文件\n\tif (contextFiles.length > 0) {\n\t\tprompt += \"\\n\\n# 项目上下文\\n\\n\";\n\t\tprompt += \"项目相关说明与规范:\\n\\n\";\n\t\tfor (const { path: filePath, content } of contextFiles) {\n\t\t\tprompt += `## ${filePath}\\n\\n${content}\\n\\n`;\n\t\t}\n\t}\n\n\t// 追加技能段落(仅当具备 read 工具时)\n\tif (hasRead && skills.length > 0) {\n\t\tprompt += formatSkillsForPrompt(skills);\n\t}\n\n\t// 最后追加日期时间与工作目录\n\tprompt += `\\n当前日期与时间:${dateTime}`;\n\tprompt += `\\n当前工作目录:${resolvedCwd}`;\n\n\treturn prompt;\n}\n"]}
1
+ {"version":3,"file":"system-prompt.js","sourceRoot":"","sources":["../../src/core/system-prompt.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * 系统提示词构建与项目上下文加载\n */\n\nimport { getDocsPath, getExamplesPath, getReadmePath } from \"../config.js\";\nimport { formatSkillsForPrompt, type Skill } from \"./skills.js\";\n\n/** 工具描述(用于系统提示) */\nconst toolDescriptions: Record<string, string> = {\n\tread: \"读取文件内容\",\n\tbash: \"执行 bash 命令(ls、grep、find 等)\",\n\tedit: \"对文件进行精确编辑(查找精确文本并替换)\",\n\twrite: \"创建或覆盖文件\",\n\tgrep: \"在文件内容中搜索模式(遵守 .gitignore)\",\n\tfind: \"按 glob 模式查找文件(遵守 .gitignore)\",\n\tls: \"列出目录内容\",\n};\n\nexport interface BuildSystemPromptOptions {\n\t/** 自定义系统提示(替换默认)。 */\n\tcustomPrompt?: string;\n\t/** 要纳入提示的工具。默认:[read, bash, edit, write] */\n\tselectedTools?: string[];\n\t/** 追加到系统提示的文本。 */\n\tappendSystemPrompt?: string;\n\t/** 工作目录。默认:process.cwd() */\n\tcwd?: string;\n\t/** 预加载的上下文文件。 */\n\tcontextFiles?: Array<{ path: string; content: string }>;\n\t/** 预加载的技能。 */\n\tskills?: Skill[];\n}\n\n/** 根据工具、规范与上下文构建系统提示 */\nexport function buildSystemPrompt(options: BuildSystemPromptOptions = {}): string {\n\tconst {\n\t\tcustomPrompt,\n\t\tselectedTools,\n\t\tappendSystemPrompt,\n\t\tcwd,\n\t\tcontextFiles: providedContextFiles,\n\t\tskills: providedSkills,\n\t} = options;\n\tconst resolvedCwd = cwd ?? process.cwd();\n\n\tconst now = new Date();\n\tconst dateTime = now.toLocaleString(\"en-US\", {\n\t\tweekday: \"long\",\n\t\tyear: \"numeric\",\n\t\tmonth: \"long\",\n\t\tday: \"numeric\",\n\t\thour: \"2-digit\",\n\t\tminute: \"2-digit\",\n\t\tsecond: \"2-digit\",\n\t\ttimeZoneName: \"short\",\n\t});\n\n\tconst appendSection = appendSystemPrompt ? `\\n\\n${appendSystemPrompt}` : \"\";\n\n\tconst contextFiles = providedContextFiles ?? [];\n\tconst skills = providedSkills ?? [];\n\n\tif (customPrompt) {\n\t\tlet prompt = customPrompt;\n\n\t\tif (appendSection) {\n\t\t\tprompt += appendSection;\n\t\t}\n\n\t\t// 追加项目上下文文件\n\t\tif (contextFiles.length > 0) {\n\t\t\tprompt += \"\\n\\n# 项目上下文\\n\\n\";\n\t\t\tprompt += \"项目相关说明与规范:\\n\\n\";\n\t\t\tfor (const { path: filePath, content } of contextFiles) {\n\t\t\t\tprompt += `## ${filePath}\\n\\n${content}\\n\\n`;\n\t\t\t}\n\t\t}\n\n\t\t// 追加技能段落(仅当具备 read 工具时)\n\t\tconst customPromptHasRead = !selectedTools || selectedTools.includes(\"read\");\n\t\tif (customPromptHasRead && skills.length > 0) {\n\t\t\tprompt += formatSkillsForPrompt(skills);\n\t\t}\n\n\t\t// 最后追加日期时间与工作目录\n\t\tprompt += `\\n当前日期与时间:${dateTime}`;\n\t\tprompt += `\\n当前工作目录:${resolvedCwd}`;\n\n\t\treturn prompt;\n\t}\n\n\t// 获取文档与示例的绝对路径\n\tconst readmePath = getReadmePath();\n\tconst docsPath = getDocsPath();\n\tconst examplesPath = getExamplesPath();\n\n\t// 根据所选工具构建工具列表(仅包含有描述的内置工具)\n\tconst tools = (selectedTools || [\"read\", \"bash\", \"edit\", \"write\"]).filter((t) => t in toolDescriptions);\n\tconst toolsList = tools.length > 0 ? tools.map((t) => `- ${t}: ${toolDescriptions[t]}`).join(\"\\n\") : \"(无)\";\n\n\t// 根据实际可用工具构建规范\n\tconst guidelinesList: string[] = [];\n\n\tconst hasBash = tools.includes(\"bash\");\n\tconst hasEdit = tools.includes(\"edit\");\n\tconst hasWrite = tools.includes(\"write\");\n\tconst hasGrep = tools.includes(\"grep\");\n\tconst hasFind = tools.includes(\"find\");\n\tconst hasLs = tools.includes(\"ls\");\n\tconst hasRead = tools.includes(\"read\");\n\n\t// 文件探索相关规范\n\tif (hasBash && !hasGrep && !hasFind && !hasLs) {\n\t\tguidelinesList.push(\"使用 bash 进行 ls、rg、find 等文件操作\");\n\t} else if (hasBash && (hasGrep || hasFind || hasLs)) {\n\t\tguidelinesList.push(\"优先使用 grep/find/ls 工具进行文件探索(更快,且遵守 .gitignore)\");\n\t}\n\n\t// 先读后编规范\n\tif (hasRead && hasEdit) {\n\t\tguidelinesList.push(\"编辑前先用 read 查看文件内容,必须使用该工具,不要用 cat 或 sed。\");\n\t}\n\n\t// 编辑规范\n\tif (hasEdit) {\n\t\tguidelinesList.push(\"使用 edit 做精确修改(旧文本必须完全匹配)\");\n\t}\n\n\t// 写入规范\n\tif (hasWrite) {\n\t\tguidelinesList.push(\"仅在创建新文件或完整重写时使用 write\");\n\t}\n\n\t// 输出规范(仅在实际写入或执行时)\n\tif (hasEdit || hasWrite) {\n\t\tguidelinesList.push(\"总结你的操作时,请直接输出纯文本,不要用 cat 或 bash 来展示你做了什么\");\n\t}\n\n\t// 始终包含以下项\n\tguidelinesList.push(\"回复请简洁\");\n\tguidelinesList.push(\"操作文件时请清晰标注文件路径\");\n\n\tconst guidelines = guidelinesList.map((g) => `- ${g}`).join(\"\\n\");\n\n\tlet prompt = `You are the writing assistant in nanopencil. You help users by reading files, running commands, editing and writing text.\n\n可用工具:\n${toolsList}\n\n除上述工具外,根据项目配置你可能还能使用其他自定义工具。\n\n规范:\n${guidelines}\n\n以下文档仅在用户询问 nano-pencil、SDK、扩展、主题、技能或 TUI 时阅读:\n- 主文档:${readmePath}\n- 更多文档:${docsPath}\n- 示例:${examplesPath}(扩展、自定义工具、SDK)\n- 被问及:扩展(docs/extensions.md, examples/extensions/)、主题(docs/themes.md)、技能(docs/skills.md)、提示模板(docs/prompt-templates.md)、TUI 组件(docs/tui.md)、键绑定(docs/keybindings.md)、SDK 集成(docs/sdk.md)、自定义提供商(docs/custom-provider.md)、添加模型(docs/models.md)、包(docs/packages.md)\n- 处理相关主题时,先阅读文档与示例,并按 .md 中的交叉引用操作后再实现\n- 务必完整阅读 .md 文件并跟随相关链接(例如 TUI API 细节见 tui.md)`;\n\n\tif (appendSection) {\n\t\tprompt += appendSection;\n\t}\n\n\t// 追加项目上下文文件\n\tif (contextFiles.length > 0) {\n\t\tprompt += \"\\n\\n# 项目上下文\\n\\n\";\n\t\tprompt += \"项目相关说明与规范:\\n\\n\";\n\t\tfor (const { path: filePath, content } of contextFiles) {\n\t\t\tprompt += `## ${filePath}\\n\\n${content}\\n\\n`;\n\t\t}\n\t}\n\n\t// 追加技能段落(仅当具备 read 工具时)\n\tif (hasRead && skills.length > 0) {\n\t\tprompt += formatSkillsForPrompt(skills);\n\t}\n\n\t// 最后追加日期时间与工作目录\n\tprompt += `\\n当前日期与时间:${dateTime}`;\n\tprompt += `\\n当前工作目录:${resolvedCwd}`;\n\n\treturn prompt;\n}\n"]}