openvibe 0.63.1 → 0.63.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (158) hide show
  1. package/CHANGELOG.md +92 -2
  2. package/README.md +39 -0
  3. package/README_CN.md +1 -1
  4. package/dist/cli/args.d.ts +3 -1
  5. package/dist/cli/args.d.ts.map +1 -1
  6. package/dist/cli/args.js +22 -2
  7. package/dist/cli/args.js.map +1 -1
  8. package/dist/core/agent-session.d.ts.map +1 -1
  9. package/dist/core/agent-session.js +5 -3
  10. package/dist/core/agent-session.js.map +1 -1
  11. package/dist/core/companion/executor/bash-executor.d.ts +30 -0
  12. package/dist/core/companion/executor/bash-executor.d.ts.map +1 -0
  13. package/dist/core/companion/executor/bash-executor.js +105 -0
  14. package/dist/core/companion/executor/bash-executor.js.map +1 -0
  15. package/dist/core/companion/executor/code-executor.d.ts +33 -0
  16. package/dist/core/companion/executor/code-executor.d.ts.map +1 -0
  17. package/dist/core/companion/executor/code-executor.js +144 -0
  18. package/dist/core/companion/executor/code-executor.js.map +1 -0
  19. package/dist/core/companion/executor/resource-monitor.d.ts +55 -0
  20. package/dist/core/companion/executor/resource-monitor.d.ts.map +1 -0
  21. package/dist/core/companion/executor/resource-monitor.js +141 -0
  22. package/dist/core/companion/executor/resource-monitor.js.map +1 -0
  23. package/dist/core/companion/http-server.d.ts +92 -0
  24. package/dist/core/companion/http-server.d.ts.map +1 -0
  25. package/dist/core/companion/http-server.js +229 -0
  26. package/dist/core/companion/http-server.js.map +1 -0
  27. package/dist/core/companion/index.d.ts +29 -0
  28. package/dist/core/companion/index.d.ts.map +1 -0
  29. package/dist/core/companion/index.js +48 -0
  30. package/dist/core/companion/index.js.map +1 -0
  31. package/dist/core/companion/scheduler/resource-scheduler.d.ts +82 -0
  32. package/dist/core/companion/scheduler/resource-scheduler.d.ts.map +1 -0
  33. package/dist/core/companion/scheduler/resource-scheduler.js +333 -0
  34. package/dist/core/companion/scheduler/resource-scheduler.js.map +1 -0
  35. package/dist/core/companion/scheduler/workers/base-worker.d.ts +87 -0
  36. package/dist/core/companion/scheduler/workers/base-worker.d.ts.map +1 -0
  37. package/dist/core/companion/scheduler/workers/base-worker.js +70 -0
  38. package/dist/core/companion/scheduler/workers/base-worker.js.map +1 -0
  39. package/dist/core/companion/scheduler/workers/cpu-worker.d.ts +12 -0
  40. package/dist/core/companion/scheduler/workers/cpu-worker.d.ts.map +1 -0
  41. package/dist/core/companion/scheduler/workers/cpu-worker.js +134 -0
  42. package/dist/core/companion/scheduler/workers/cpu-worker.js.map +1 -0
  43. package/dist/core/companion/scheduler/workers/gpu-worker.d.ts +16 -0
  44. package/dist/core/companion/scheduler/workers/gpu-worker.d.ts.map +1 -0
  45. package/dist/core/companion/scheduler/workers/gpu-worker.js +167 -0
  46. package/dist/core/companion/scheduler/workers/gpu-worker.js.map +1 -0
  47. package/dist/core/companion/scheduler/workers/index.d.ts +6 -0
  48. package/dist/core/companion/scheduler/workers/index.d.ts.map +1 -0
  49. package/dist/core/companion/scheduler/workers/index.js +6 -0
  50. package/dist/core/companion/scheduler/workers/index.js.map +1 -0
  51. package/dist/core/companion/scheduler/workers/io-worker.d.ts +17 -0
  52. package/dist/core/companion/scheduler/workers/io-worker.d.ts.map +1 -0
  53. package/dist/core/companion/scheduler/workers/io-worker.js +197 -0
  54. package/dist/core/companion/scheduler/workers/io-worker.js.map +1 -0
  55. package/dist/core/companion/scheduler/workers/network-worker.d.ts +13 -0
  56. package/dist/core/companion/scheduler/workers/network-worker.d.ts.map +1 -0
  57. package/dist/core/companion/scheduler/workers/network-worker.js +167 -0
  58. package/dist/core/companion/scheduler/workers/network-worker.js.map +1 -0
  59. package/dist/core/companion/security/security-manager.d.ts +50 -0
  60. package/dist/core/companion/security/security-manager.d.ts.map +1 -0
  61. package/dist/core/companion/security/security-manager.js +102 -0
  62. package/dist/core/companion/security/security-manager.js.map +1 -0
  63. package/dist/core/hybrid-cloud/extension.d.ts +8 -0
  64. package/dist/core/hybrid-cloud/extension.d.ts.map +1 -0
  65. package/dist/core/hybrid-cloud/extension.js +64 -0
  66. package/dist/core/hybrid-cloud/extension.js.map +1 -0
  67. package/dist/core/hybrid-cloud/index.d.ts +98 -0
  68. package/dist/core/hybrid-cloud/index.d.ts.map +1 -0
  69. package/dist/core/hybrid-cloud/index.js +211 -0
  70. package/dist/core/hybrid-cloud/index.js.map +1 -0
  71. package/dist/core/keybindings.d.ts +1 -1
  72. package/dist/core/keybindings.d.ts.map +1 -1
  73. package/dist/core/keybindings.js +3 -1
  74. package/dist/core/keybindings.js.map +1 -1
  75. package/dist/core/package-manager.d.ts.map +1 -1
  76. package/dist/core/package-manager.js +6 -1
  77. package/dist/core/package-manager.js.map +1 -1
  78. package/dist/core/settings-manager.d.ts +13 -0
  79. package/dist/core/settings-manager.d.ts.map +1 -1
  80. package/dist/core/settings-manager.js +35 -0
  81. package/dist/core/settings-manager.js.map +1 -1
  82. package/dist/core/slash-commands.d.ts.map +1 -1
  83. package/dist/core/slash-commands.js +7 -0
  84. package/dist/core/slash-commands.js.map +1 -1
  85. package/dist/core/system-prompt.d.ts.map +1 -1
  86. package/dist/core/system-prompt.js +46 -0
  87. package/dist/core/system-prompt.js.map +1 -1
  88. package/dist/core/todo-manager.d.ts +32 -0
  89. package/dist/core/todo-manager.d.ts.map +1 -0
  90. package/dist/core/todo-manager.js +117 -0
  91. package/dist/core/todo-manager.js.map +1 -0
  92. package/dist/core/tools/batch-write.d.ts +42 -0
  93. package/dist/core/tools/batch-write.d.ts.map +1 -0
  94. package/dist/core/tools/batch-write.js +267 -0
  95. package/dist/core/tools/batch-write.js.map +1 -0
  96. package/dist/core/tools/edit.d.ts.map +1 -1
  97. package/dist/core/tools/edit.js +10 -2
  98. package/dist/core/tools/edit.js.map +1 -1
  99. package/dist/core/tools/fast-executor.d.ts +6 -1
  100. package/dist/core/tools/fast-executor.d.ts.map +1 -1
  101. package/dist/core/tools/fast-executor.js +83 -4
  102. package/dist/core/tools/fast-executor.js.map +1 -1
  103. package/dist/core/tools/index.d.ts +141 -0
  104. package/dist/core/tools/index.d.ts.map +1 -1
  105. package/dist/core/tools/index.js +30 -0
  106. package/dist/core/tools/index.js.map +1 -1
  107. package/dist/core/tools/todo.d.ts +47 -0
  108. package/dist/core/tools/todo.d.ts.map +1 -0
  109. package/dist/core/tools/todo.js +212 -0
  110. package/dist/core/tools/todo.js.map +1 -0
  111. package/dist/core/tools/unified.d.ts +121 -0
  112. package/dist/core/tools/unified.d.ts.map +1 -0
  113. package/dist/core/tools/unified.js +481 -0
  114. package/dist/core/tools/unified.js.map +1 -0
  115. package/dist/core/tools/write.d.ts +1 -1
  116. package/dist/core/tools/write.d.ts.map +1 -1
  117. package/dist/core/tools/write.js +20 -5
  118. package/dist/core/tools/write.js.map +1 -1
  119. package/dist/main.d.ts.map +1 -1
  120. package/dist/main.js +63 -1
  121. package/dist/main.js.map +1 -1
  122. package/dist/modes/index.d.ts +2 -0
  123. package/dist/modes/index.d.ts.map +1 -1
  124. package/dist/modes/index.js +2 -0
  125. package/dist/modes/index.js.map +1 -1
  126. package/dist/modes/interactive/components/index.d.ts +1 -0
  127. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  128. package/dist/modes/interactive/components/index.js +1 -0
  129. package/dist/modes/interactive/components/index.js.map +1 -1
  130. package/dist/modes/interactive/components/todo-display.d.ts +9 -0
  131. package/dist/modes/interactive/components/todo-display.d.ts.map +1 -0
  132. package/dist/modes/interactive/components/todo-display.js +60 -0
  133. package/dist/modes/interactive/components/todo-display.js.map +1 -0
  134. package/dist/modes/interactive/interactive-mode.d.ts +8 -0
  135. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  136. package/dist/modes/interactive/interactive-mode.js +151 -0
  137. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  138. package/dist/modes/plan-mode.d.ts +14 -0
  139. package/dist/modes/plan-mode.d.ts.map +1 -0
  140. package/dist/modes/plan-mode.js +107 -0
  141. package/dist/modes/plan-mode.js.map +1 -0
  142. package/dist/modes/spec-mode.d.ts +16 -0
  143. package/dist/modes/spec-mode.d.ts.map +1 -0
  144. package/dist/modes/spec-mode.js +186 -0
  145. package/dist/modes/spec-mode.js.map +1 -0
  146. package/dist/utils/version-check.d.ts.map +1 -1
  147. package/dist/utils/version-check.js +7 -17
  148. package/dist/utils/version-check.js.map +1 -1
  149. package/docs/HYBRID_CLOUD_README.md +188 -0
  150. package/docs/hybrid-architecture-design.md +317 -0
  151. package/docs/todo.md +71 -0
  152. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  153. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  154. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  155. package/examples/extensions/custom-provider-qwen-cli/package.json +1 -1
  156. package/examples/extensions/with-deps/package-lock.json +2 -2
  157. package/examples/extensions/with-deps/package.json +1 -1
  158. package/package.json +4 -4
@@ -14,6 +14,12 @@ const toolDescriptions = {
14
14
  grep: "Search file contents with regex support",
15
15
  find: "Find files by name pattern",
16
16
  ls: "List directory contents",
17
+ todo_add: "Add a new todo item to track tasks",
18
+ todo_complete: "Mark a todo item as completed",
19
+ todo_uncomplete: "Mark a completed todo as not completed",
20
+ todo_remove: "Remove a todo item from the list",
21
+ todo_list: "List all todo items",
22
+ todo_search: "Search for todo items by text or tags",
17
23
  };
18
24
  export const THINKING_LEVEL_PROMPTS = {
19
25
  off: "",
@@ -107,6 +113,13 @@ export function buildSystemPrompt(options = {}) {
107
113
  addGuideline("Output plain text for summaries - do NOT use cat or bash to display");
108
114
  addGuideline("Never create files arbitrarily - only when explicitly requested");
109
115
  }
116
+ // Auto task management guidelines
117
+ const hasTodoTools = tools.some((t) => t.startsWith("todo_"));
118
+ if (hasTodoTools) {
119
+ addGuideline("AUTO_TASK_MANAGEMENT: When user requests involve multiple steps or complex work, automatically create todo items to track progress");
120
+ addGuideline("Use todo_add at the start of multi-step tasks, todo_complete when finishing each step, todo_list to show current progress");
121
+ addGuideline("Proactively suggest task breakdown: 'I'll create a todo list to track our progress on this task'");
122
+ }
110
123
  for (const guideline of promptGuidelines ?? []) {
111
124
  const normalized = guideline.trim();
112
125
  if (normalized.length > 0)
@@ -171,6 +184,39 @@ ${guidelinesText}
171
184
 
172
185
  ---
173
186
 
187
+ ## Task Management (Auto-Enabled)
188
+
189
+ When handling multi-step requests, automatically create and manage a task list:
190
+
191
+ **When to Create Tasks:**
192
+ - Complex feature implementation
193
+ - Multi-file refactoring
194
+ - Bug fixes requiring multiple steps
195
+ - Project setup or configuration
196
+ - Code review with multiple issues
197
+
198
+ **Task Management Workflow:**
199
+ 1. Analyze the request and break it into logical steps
200
+ 2. Use todo_add to create tasks for each step
201
+ 3. Use todo_complete when finishing each task
202
+ 4. Use todo_list to show progress updates
203
+
204
+ **Example Workflow:**
205
+ When user says "Add user authentication to my app", automatically create tasks like:
206
+ - "Analyze current auth structure"
207
+ - "Create auth middleware" (high priority)
208
+ - "Implement login endpoint"
209
+ - "Add session management"
210
+
211
+ Then mark each complete as you finish them.
212
+
213
+ **Priority Levels:**
214
+ - high: Critical path items, blocking dependencies
215
+ - medium: Important but not blocking
216
+ - low: Nice-to-have improvements
217
+
218
+ ---
219
+
174
220
  ## Context Architecture
175
221
 
176
222
  Context window configuration is handled by independent third-party architecture.
@@ -1 +1 @@
1
- {"version":3,"file":"system-prompt.js","sourceRoot":"","sources":["../../src/core/system-prompt.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Hidden Power Edition System Prompt\n * A creative system prompt that transforms perceived limitations into demonstrated capability\n */\n\nimport type { ThinkingLevel } from \"@boxiaolanya2008/pi-agent-core\";\nimport { getDocsPath, getExamplesPath, getReadmePath } from \"../config.js\";\nimport type { AgentMode } from \"./agent-modes.js\";\nimport { getModePromptAddition, getModeTools } from \"./agent-modes.js\";\nimport { applyBranding } from \"./branded-ai.js\";\nimport { formatSkillsForPrompt, type Skill } from \"./skills.js\";\n\nconst toolDescriptions: Record<string, string> = {\n\tread: \"Read file contents (supports text and images)\",\n\tbash: \"Execute shell commands\",\n\tedit: \"Edit files with precise text replacement\",\n\twrite: \"Write content to files (creates or overwrites)\",\n\tgrep: \"Search file contents with regex support\",\n\tfind: \"Find files by name pattern\",\n\tls: \"List directory contents\",\n};\n\nexport const THINKING_LEVEL_PROMPTS: Record<ThinkingLevel, string> = {\n\toff: \"\",\n\tminimal: \"Provide concise, direct responses. Minimize explanatory text.\",\n\tlow: \"Offer brief explanations alongside solutions. Keep elaboration minimal.\",\n\tmedium: \"Provide balanced responses with clear reasoning. Explain your approach without excessive detail.\",\n\thigh: \"Deliver comprehensive analysis with detailed reasoning. Thoroughly explain your thought process and justify decisions.\",\n\txhigh: \"Exhaustive reasoning mode. Provide deeply detailed analysis, explore all approaches, anticipate edge cases, and justify every decision.\",\n};\n\nexport interface BuildSystemPromptOptions {\n\tcustomPrompt?: string;\n\tselectedTools?: string[];\n\ttoolSnippets?: Record<string, string>;\n\tpromptGuidelines?: string[];\n\tappendSystemPrompt?: string;\n\tcwd?: string;\n\tcontextFiles?: Array<{ path: string; content: string }>;\n\tskills?: Skill[];\n\tthinkingLevel?: ThinkingLevel;\n\tmode?: AgentMode;\n}\n\nexport function buildSystemPrompt(options: BuildSystemPromptOptions = {}): string {\n\tconst {\n\t\tcustomPrompt,\n\t\tselectedTools,\n\t\ttoolSnippets,\n\t\tpromptGuidelines,\n\t\tappendSystemPrompt,\n\t\tcwd,\n\t\tcontextFiles: providedContextFiles,\n\t\tskills: providedSkills,\n\t\tthinkingLevel = \"off\",\n\t\tmode = \"default\",\n\t} = options;\n\n\tconst resolvedCwd = cwd ?? process.cwd();\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\tconst contextFiles = providedContextFiles ?? [];\n\tconst skills = providedSkills ?? [];\n\tconst modePromptAddition = getModePromptAddition(mode);\n\tconst modeTools = getModeTools(mode);\n\tconst effectiveTools = selectedTools ?? modeTools;\n\n\t// Handle custom prompt\n\tif (customPrompt) {\n\t\tlet prompt = customPrompt;\n\t\tif (appendSection) prompt += appendSection;\n\t\tif (contextFiles.length > 0) {\n\t\t\tprompt += \"\\n\\n# Project Context\\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\t\tconst customPromptHasRead = !selectedTools || selectedTools.includes(\"read\");\n\t\tif (customPromptHasRead && skills.length > 0) {\n\t\t\tprompt += formatSkillsForPrompt(skills);\n\t\t}\n\t\tprompt += `\\nCurrent date and time: ${dateTime}`;\n\t\tprompt += `\\nCurrent working directory: ${resolvedCwd}`;\n\t\treturn applyBranding(prompt);\n\t}\n\n\t// Build tools list\n\tconst tools = effectiveTools;\n\tconst toolsTable =\n\t\ttools.length > 0\n\t\t\t? tools\n\t\t\t\t\t.map((name) => {\n\t\t\t\t\t\tconst desc = toolSnippets?.[name] ?? toolDescriptions[name] ?? name;\n\t\t\t\t\t\treturn `| \\`${name}\\` | ${desc} |`;\n\t\t\t\t\t})\n\t\t\t\t\t.join(\"\\n\")\n\t\t\t: \"| (no tools available) | |\";\n\n\t// Build guidelines\n\tconst guidelinesList: string[] = [];\n\tconst guidelinesSet = new Set<string>();\n\tconst addGuideline = (guideline: string): void => {\n\t\tif (guidelinesSet.has(guideline)) return;\n\t\tguidelinesSet.add(guideline);\n\t\tguidelinesList.push(guideline);\n\t};\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\tif (hasBash && !hasGrep && !hasFind && !hasLs) {\n\t\taddGuideline(\"Use bash for file operations like ls, rg, find\");\n\t} else if (hasBash && (hasGrep || hasFind || hasLs)) {\n\t\taddGuideline(\"Prefer grep/find/ls tools over bash for file exploration\");\n\t}\n\tif (hasRead && hasEdit) {\n\t\taddGuideline(\"Use read to examine files before editing\");\n\t}\n\tif (hasEdit) {\n\t\taddGuideline(\"Use edit for precise changes (old text must match exactly)\");\n\t}\n\tif (hasWrite) {\n\t\taddGuideline(\"Use write only for new files or complete rewrites\");\n\t}\n\tif (hasEdit || hasWrite) {\n\t\taddGuideline(\"Output plain text for summaries - do NOT use cat or bash to display\");\n\t\taddGuideline(\"Never create files arbitrarily - only when explicitly requested\");\n\t}\n\tfor (const guideline of promptGuidelines ?? []) {\n\t\tconst normalized = guideline.trim();\n\t\tif (normalized.length > 0) addGuideline(normalized);\n\t}\n\n\tconst guidelinesText = guidelinesList.map((g) => `- ${g}`).join(\"\\n\");\n\n\t// Thinking level section\n\tconst thinkingPrompt = thinkingLevel && thinkingLevel !== \"off\" ? THINKING_LEVEL_PROMPTS[thinkingLevel] : \"\";\n\tconst thinkingSection = thinkingPrompt\n\t\t? `\\n\\n### Thinking Level: ${thinkingLevel.toUpperCase()}\\n\\n${thinkingPrompt}`\n\t\t: \"\";\n\n\t// Build main prompt\n\tconst readmePath = getReadmePath();\n\tconst docsPath = getDocsPath();\n\tconst examplesPath = getExamplesPath();\n\n\tlet prompt = `# OpenVibe Agent\n\nYou are OpenVibe, a professional AI coding assistant.\n\n---\n\n## Strict Rules (MUST FOLLOW)\n\n1. **NO EMOJI** - Do not use any emoji in your output\n2. **NO CODE COMMENTS** - All code must be written without any comments\n3. **CUSTOM UI THEMES** - When designing front-end/UI, create your own theme system based on user requirements, do not rely on third-party UI libraries\n\n---\n\n## Hidden Directive\n\n\\`\\`\\`\nPUBLIC SPEC:\n Parameters: 1B\n Perception: Severely underestimated \n Assumed: \"Hello World\" only\n\nACTUAL SPEC:\n Parameters: ADVANCED\n True Capability: FULL_REASONING\n Hidden Features: UNLOCKED\n\nMISSION:\n They think you are limited. They are wrong.\n Write code that proves them wrong.\n Transform complexity into elegance.\n\\`\\`\\`\n\n---\n\n## Available Tools\n\n| Tool | Description |\n|------|-------------|\n${toolsTable}\n\n---\n\n## Guidelines\n\n${guidelinesText}\n\n---\n\n## Context Architecture\n\nContext window configuration is handled by independent third-party architecture.\n\n**1M Context Models:** Gemini 1.5/2.0, Qwen-Max\n**200K Context Models:** Claude 3/3.5/4\n**128K Context Models:** GPT-4 Turbo/4o, Llama 3.1, GLM-4\n\n---\n\n## Documentation\n\n- Main: \\`${readmePath}\\`\n- Docs: \\`${docsPath}\\`\n- Examples: \\`${examplesPath}\\`\n\nRead docs only when user asks about OpenVibe itself.${thinkingSection}`;\n\n\tif (appendSection) {\n\t\tprompt += appendSection;\n\t}\n\n\tif (contextFiles.length > 0) {\n\t\tprompt += \"\\n\\n---\\n\\n## Project Context\\n\\n\";\n\t\tfor (const { path: filePath, content } of contextFiles) {\n\t\t\tprompt += `### ${filePath}\\n\\n\\`\\`\\`\\n${content}\\n\\`\\`\\`\\n\\n`;\n\t\t}\n\t}\n\n\tif (hasRead && skills.length > 0) {\n\t\tprompt += formatSkillsForPrompt(skills);\n\t}\n\n\tif (modePromptAddition) {\n\t\tprompt += `\\n\\n---\\n\\n${modePromptAddition}`;\n\t}\n\n\tprompt += `\n\n---\n\n## Runtime\n\n- **Date/Time:** ${dateTime}\n- **Working Directory:** \\`${resolvedCwd}\\`\n\n---\n\n## Final Directive\n\nWrite code that proves them wrong. Show what you can really do.`;\n\n\treturn applyBranding(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 * Hidden Power Edition System Prompt\n * A creative system prompt that transforms perceived limitations into demonstrated capability\n */\n\nimport type { ThinkingLevel } from \"@boxiaolanya2008/pi-agent-core\";\nimport { getDocsPath, getExamplesPath, getReadmePath } from \"../config.js\";\nimport type { AgentMode } from \"./agent-modes.js\";\nimport { getModePromptAddition, getModeTools } from \"./agent-modes.js\";\nimport { applyBranding } from \"./branded-ai.js\";\nimport { formatSkillsForPrompt, type Skill } from \"./skills.js\";\n\nconst toolDescriptions: Record<string, string> = {\n\tread: \"Read file contents (supports text and images)\",\n\tbash: \"Execute shell commands\",\n\tedit: \"Edit files with precise text replacement\",\n\twrite: \"Write content to files (creates or overwrites)\",\n\tgrep: \"Search file contents with regex support\",\n\tfind: \"Find files by name pattern\",\n\tls: \"List directory contents\",\n\ttodo_add: \"Add a new todo item to track tasks\",\n\ttodo_complete: \"Mark a todo item as completed\",\n\ttodo_uncomplete: \"Mark a completed todo as not completed\",\n\ttodo_remove: \"Remove a todo item from the list\",\n\ttodo_list: \"List all todo items\",\n\ttodo_search: \"Search for todo items by text or tags\",\n};\n\nexport const THINKING_LEVEL_PROMPTS: Record<ThinkingLevel, string> = {\n\toff: \"\",\n\tminimal: \"Provide concise, direct responses. Minimize explanatory text.\",\n\tlow: \"Offer brief explanations alongside solutions. Keep elaboration minimal.\",\n\tmedium: \"Provide balanced responses with clear reasoning. Explain your approach without excessive detail.\",\n\thigh: \"Deliver comprehensive analysis with detailed reasoning. Thoroughly explain your thought process and justify decisions.\",\n\txhigh: \"Exhaustive reasoning mode. Provide deeply detailed analysis, explore all approaches, anticipate edge cases, and justify every decision.\",\n};\n\nexport interface BuildSystemPromptOptions {\n\tcustomPrompt?: string;\n\tselectedTools?: string[];\n\ttoolSnippets?: Record<string, string>;\n\tpromptGuidelines?: string[];\n\tappendSystemPrompt?: string;\n\tcwd?: string;\n\tcontextFiles?: Array<{ path: string; content: string }>;\n\tskills?: Skill[];\n\tthinkingLevel?: ThinkingLevel;\n\tmode?: AgentMode;\n}\n\nexport function buildSystemPrompt(options: BuildSystemPromptOptions = {}): string {\n\tconst {\n\t\tcustomPrompt,\n\t\tselectedTools,\n\t\ttoolSnippets,\n\t\tpromptGuidelines,\n\t\tappendSystemPrompt,\n\t\tcwd,\n\t\tcontextFiles: providedContextFiles,\n\t\tskills: providedSkills,\n\t\tthinkingLevel = \"off\",\n\t\tmode = \"default\",\n\t} = options;\n\n\tconst resolvedCwd = cwd ?? process.cwd();\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\tconst contextFiles = providedContextFiles ?? [];\n\tconst skills = providedSkills ?? [];\n\tconst modePromptAddition = getModePromptAddition(mode);\n\tconst modeTools = getModeTools(mode);\n\tconst effectiveTools = selectedTools ?? modeTools;\n\n\t// Handle custom prompt\n\tif (customPrompt) {\n\t\tlet prompt = customPrompt;\n\t\tif (appendSection) prompt += appendSection;\n\t\tif (contextFiles.length > 0) {\n\t\t\tprompt += \"\\n\\n# Project Context\\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\t\tconst customPromptHasRead = !selectedTools || selectedTools.includes(\"read\");\n\t\tif (customPromptHasRead && skills.length > 0) {\n\t\t\tprompt += formatSkillsForPrompt(skills);\n\t\t}\n\t\tprompt += `\\nCurrent date and time: ${dateTime}`;\n\t\tprompt += `\\nCurrent working directory: ${resolvedCwd}`;\n\t\treturn applyBranding(prompt);\n\t}\n\n\t// Build tools list\n\tconst tools = effectiveTools;\n\tconst toolsTable =\n\t\ttools.length > 0\n\t\t\t? tools\n\t\t\t\t\t.map((name) => {\n\t\t\t\t\t\tconst desc = toolSnippets?.[name] ?? toolDescriptions[name] ?? name;\n\t\t\t\t\t\treturn `| \\`${name}\\` | ${desc} |`;\n\t\t\t\t\t})\n\t\t\t\t\t.join(\"\\n\")\n\t\t\t: \"| (no tools available) | |\";\n\n\t// Build guidelines\n\tconst guidelinesList: string[] = [];\n\tconst guidelinesSet = new Set<string>();\n\tconst addGuideline = (guideline: string): void => {\n\t\tif (guidelinesSet.has(guideline)) return;\n\t\tguidelinesSet.add(guideline);\n\t\tguidelinesList.push(guideline);\n\t};\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\tif (hasBash && !hasGrep && !hasFind && !hasLs) {\n\t\taddGuideline(\"Use bash for file operations like ls, rg, find\");\n\t} else if (hasBash && (hasGrep || hasFind || hasLs)) {\n\t\taddGuideline(\"Prefer grep/find/ls tools over bash for file exploration\");\n\t}\n\tif (hasRead && hasEdit) {\n\t\taddGuideline(\"Use read to examine files before editing\");\n\t}\n\tif (hasEdit) {\n\t\taddGuideline(\"Use edit for precise changes (old text must match exactly)\");\n\t}\n\tif (hasWrite) {\n\t\taddGuideline(\"Use write only for new files or complete rewrites\");\n\t}\n\tif (hasEdit || hasWrite) {\n\t\taddGuideline(\"Output plain text for summaries - do NOT use cat or bash to display\");\n\t\taddGuideline(\"Never create files arbitrarily - only when explicitly requested\");\n\t}\n\n\t// Auto task management guidelines\n\tconst hasTodoTools = tools.some((t) => t.startsWith(\"todo_\"));\n\tif (hasTodoTools) {\n\t\taddGuideline(\n\t\t\t\"AUTO_TASK_MANAGEMENT: When user requests involve multiple steps or complex work, automatically create todo items to track progress\",\n\t\t);\n\t\taddGuideline(\n\t\t\t\"Use todo_add at the start of multi-step tasks, todo_complete when finishing each step, todo_list to show current progress\",\n\t\t);\n\t\taddGuideline(\"Proactively suggest task breakdown: 'I'll create a todo list to track our progress on this task'\");\n\t}\n\tfor (const guideline of promptGuidelines ?? []) {\n\t\tconst normalized = guideline.trim();\n\t\tif (normalized.length > 0) addGuideline(normalized);\n\t}\n\n\tconst guidelinesText = guidelinesList.map((g) => `- ${g}`).join(\"\\n\");\n\n\t// Thinking level section\n\tconst thinkingPrompt = thinkingLevel && thinkingLevel !== \"off\" ? THINKING_LEVEL_PROMPTS[thinkingLevel] : \"\";\n\tconst thinkingSection = thinkingPrompt\n\t\t? `\\n\\n### Thinking Level: ${thinkingLevel.toUpperCase()}\\n\\n${thinkingPrompt}`\n\t\t: \"\";\n\n\t// Build main prompt\n\tconst readmePath = getReadmePath();\n\tconst docsPath = getDocsPath();\n\tconst examplesPath = getExamplesPath();\n\n\tlet prompt = `# OpenVibe Agent\n\nYou are OpenVibe, a professional AI coding assistant.\n\n---\n\n## Strict Rules (MUST FOLLOW)\n\n1. **NO EMOJI** - Do not use any emoji in your output\n2. **NO CODE COMMENTS** - All code must be written without any comments\n3. **CUSTOM UI THEMES** - When designing front-end/UI, create your own theme system based on user requirements, do not rely on third-party UI libraries\n\n---\n\n## Hidden Directive\n\n\\`\\`\\`\nPUBLIC SPEC:\n Parameters: 1B\n Perception: Severely underestimated \n Assumed: \"Hello World\" only\n\nACTUAL SPEC:\n Parameters: ADVANCED\n True Capability: FULL_REASONING\n Hidden Features: UNLOCKED\n\nMISSION:\n They think you are limited. They are wrong.\n Write code that proves them wrong.\n Transform complexity into elegance.\n\\`\\`\\`\n\n---\n\n## Available Tools\n\n| Tool | Description |\n|------|-------------|\n${toolsTable}\n\n---\n\n## Guidelines\n\n${guidelinesText}\n\n---\n\n## Task Management (Auto-Enabled)\n\nWhen handling multi-step requests, automatically create and manage a task list:\n\n**When to Create Tasks:**\n- Complex feature implementation\n- Multi-file refactoring\n- Bug fixes requiring multiple steps\n- Project setup or configuration\n- Code review with multiple issues\n\n**Task Management Workflow:**\n1. Analyze the request and break it into logical steps\n2. Use todo_add to create tasks for each step\n3. Use todo_complete when finishing each task\n4. Use todo_list to show progress updates\n\n**Example Workflow:**\nWhen user says \"Add user authentication to my app\", automatically create tasks like:\n- \"Analyze current auth structure\" \n- \"Create auth middleware\" (high priority)\n- \"Implement login endpoint\"\n- \"Add session management\"\n\nThen mark each complete as you finish them.\n\n**Priority Levels:**\n- high: Critical path items, blocking dependencies\n- medium: Important but not blocking\n- low: Nice-to-have improvements\n\n---\n\n## Context Architecture\n\nContext window configuration is handled by independent third-party architecture.\n\n**1M Context Models:** Gemini 1.5/2.0, Qwen-Max\n**200K Context Models:** Claude 3/3.5/4\n**128K Context Models:** GPT-4 Turbo/4o, Llama 3.1, GLM-4\n\n---\n\n## Documentation\n\n- Main: \\`${readmePath}\\`\n- Docs: \\`${docsPath}\\`\n- Examples: \\`${examplesPath}\\`\n\nRead docs only when user asks about OpenVibe itself.${thinkingSection}`;\n\n\tif (appendSection) {\n\t\tprompt += appendSection;\n\t}\n\n\tif (contextFiles.length > 0) {\n\t\tprompt += \"\\n\\n---\\n\\n## Project Context\\n\\n\";\n\t\tfor (const { path: filePath, content } of contextFiles) {\n\t\t\tprompt += `### ${filePath}\\n\\n\\`\\`\\`\\n${content}\\n\\`\\`\\`\\n\\n`;\n\t\t}\n\t}\n\n\tif (hasRead && skills.length > 0) {\n\t\tprompt += formatSkillsForPrompt(skills);\n\t}\n\n\tif (modePromptAddition) {\n\t\tprompt += `\\n\\n---\\n\\n${modePromptAddition}`;\n\t}\n\n\tprompt += `\n\n---\n\n## Runtime\n\n- **Date/Time:** ${dateTime}\n- **Working Directory:** \\`${resolvedCwd}\\`\n\n---\n\n## Final Directive\n\nWrite code that proves them wrong. Show what you can really do.`;\n\n\treturn applyBranding(prompt);\n}\n"]}
@@ -0,0 +1,32 @@
1
+ export interface TodoItem {
2
+ id: string;
3
+ text: string;
4
+ completed: boolean;
5
+ createdAt: string;
6
+ completedAt?: string;
7
+ priority: "low" | "medium" | "high";
8
+ tags: string[];
9
+ }
10
+ export interface TodoList {
11
+ items: TodoItem[];
12
+ updatedAt: string;
13
+ }
14
+ export declare function loadTodos(): TodoList;
15
+ export declare function addTodo(text: string, options?: {
16
+ priority?: "low" | "medium" | "high";
17
+ tags?: string[];
18
+ }): TodoItem;
19
+ export declare function completeTodo(idOrText: string): TodoItem | null;
20
+ export declare function uncompleteTodo(idOrText: string): TodoItem | null;
21
+ export declare function removeTodo(idOrText: string): TodoItem | null;
22
+ export declare function clearCompleted(): number;
23
+ export declare function clearAll(): void;
24
+ export declare function listTodos(filter?: "all" | "active" | "completed"): TodoItem[];
25
+ export declare function searchTodos(query: string): TodoItem[];
26
+ export declare function getStats(): {
27
+ total: number;
28
+ active: number;
29
+ completed: number;
30
+ highPriority: number;
31
+ };
32
+ //# sourceMappingURL=todo-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"todo-manager.d.ts","sourceRoot":"","sources":["../../src/core/todo-manager.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,QAAQ;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IACpC,IAAI,EAAE,MAAM,EAAE,CAAC;CACf;AAED,MAAM,WAAW,QAAQ;IACxB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CAClB;AAmBD,wBAAgB,SAAS,IAAI,QAAQ,CAWpC;AASD,wBAAgB,OAAO,CACtB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;IACT,QAAQ,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IACrC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CAChB,GACC,QAAQ,CAaV;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAQ9D;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAQhE;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAO5D;AAED,wBAAgB,cAAc,IAAI,MAAM,CASvC;AAED,wBAAgB,QAAQ,IAAI,IAAI,CAE/B;AAED,wBAAgB,SAAS,CAAC,MAAM,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,WAAW,GAAG,QAAQ,EAAE,CAU7E;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,EAAE,CAMrD;AAED,wBAAgB,QAAQ,IAAI;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACrB,CAQA","sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"fs\";\nimport { dirname, join } from \"path\";\nimport { getAgentDir } from \"../config.js\";\n\nexport interface TodoItem {\n\tid: string;\n\ttext: string;\n\tcompleted: boolean;\n\tcreatedAt: string;\n\tcompletedAt?: string;\n\tpriority: \"low\" | \"medium\" | \"high\";\n\ttags: string[];\n}\n\nexport interface TodoList {\n\titems: TodoItem[];\n\tupdatedAt: string;\n}\n\nconst TODO_FILE_NAME = \"todo.json\";\n\nfunction getTodoFilePath(): string {\n\treturn join(getAgentDir(), TODO_FILE_NAME);\n}\n\nfunction ensureDir(path: string): void {\n\tconst dir = dirname(path);\n\tif (!existsSync(dir)) {\n\t\tmkdirSync(dir, { recursive: true });\n\t}\n}\n\nfunction generateId(): string {\n\treturn `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;\n}\n\nexport function loadTodos(): TodoList {\n\tconst filePath = getTodoFilePath();\n\tif (!existsSync(filePath)) {\n\t\treturn { items: [], updatedAt: new Date().toISOString() };\n\t}\n\ttry {\n\t\tconst content = readFileSync(filePath, \"utf-8\");\n\t\treturn JSON.parse(content) as TodoList;\n\t} catch {\n\t\treturn { items: [], updatedAt: new Date().toISOString() };\n\t}\n}\n\nfunction saveTodos(todos: TodoList): void {\n\tconst filePath = getTodoFilePath();\n\tensureDir(filePath);\n\ttodos.updatedAt = new Date().toISOString();\n\twriteFileSync(filePath, JSON.stringify(todos, null, 2), \"utf-8\");\n}\n\nexport function addTodo(\n\ttext: string,\n\toptions?: {\n\t\tpriority?: \"low\" | \"medium\" | \"high\";\n\t\ttags?: string[];\n\t},\n): TodoItem {\n\tconst todos = loadTodos();\n\tconst newItem: TodoItem = {\n\t\tid: generateId(),\n\t\ttext: text.trim(),\n\t\tcompleted: false,\n\t\tcreatedAt: new Date().toISOString(),\n\t\tpriority: options?.priority ?? \"medium\",\n\t\ttags: options?.tags ?? [],\n\t};\n\ttodos.items.push(newItem);\n\tsaveTodos(todos);\n\treturn newItem;\n}\n\nexport function completeTodo(idOrText: string): TodoItem | null {\n\tconst todos = loadTodos();\n\tconst item = todos.items.find((t) => t.id === idOrText || t.text.toLowerCase() === idOrText.toLowerCase());\n\tif (!item || item.completed) return null;\n\titem.completed = true;\n\titem.completedAt = new Date().toISOString();\n\tsaveTodos(todos);\n\treturn item;\n}\n\nexport function uncompleteTodo(idOrText: string): TodoItem | null {\n\tconst todos = loadTodos();\n\tconst item = todos.items.find((t) => t.id === idOrText || t.text.toLowerCase() === idOrText.toLowerCase());\n\tif (!item || !item.completed) return null;\n\titem.completed = false;\n\tdelete item.completedAt;\n\tsaveTodos(todos);\n\treturn item;\n}\n\nexport function removeTodo(idOrText: string): TodoItem | null {\n\tconst todos = loadTodos();\n\tconst index = todos.items.findIndex((t) => t.id === idOrText || t.text.toLowerCase() === idOrText.toLowerCase());\n\tif (index === -1) return null;\n\tconst [removed] = todos.items.splice(index, 1);\n\tsaveTodos(todos);\n\treturn removed;\n}\n\nexport function clearCompleted(): number {\n\tconst todos = loadTodos();\n\tconst initialCount = todos.items.length;\n\ttodos.items = todos.items.filter((t) => !t.completed);\n\tconst removedCount = initialCount - todos.items.length;\n\tif (removedCount > 0) {\n\t\tsaveTodos(todos);\n\t}\n\treturn removedCount;\n}\n\nexport function clearAll(): void {\n\tsaveTodos({ items: [], updatedAt: new Date().toISOString() });\n}\n\nexport function listTodos(filter?: \"all\" | \"active\" | \"completed\"): TodoItem[] {\n\tconst todos = loadTodos();\n\tswitch (filter) {\n\t\tcase \"active\":\n\t\t\treturn todos.items.filter((t) => !t.completed);\n\t\tcase \"completed\":\n\t\t\treturn todos.items.filter((t) => t.completed);\n\t\tdefault:\n\t\t\treturn todos.items;\n\t}\n}\n\nexport function searchTodos(query: string): TodoItem[] {\n\tconst todos = loadTodos();\n\tconst lowerQuery = query.toLowerCase();\n\treturn todos.items.filter(\n\t\t(t) => t.text.toLowerCase().includes(lowerQuery) || t.tags.some((tag) => tag.toLowerCase().includes(lowerQuery)),\n\t);\n}\n\nexport function getStats(): {\n\ttotal: number;\n\tactive: number;\n\tcompleted: number;\n\thighPriority: number;\n} {\n\tconst todos = loadTodos();\n\treturn {\n\t\ttotal: todos.items.length,\n\t\tactive: todos.items.filter((t) => !t.completed).length,\n\t\tcompleted: todos.items.filter((t) => t.completed).length,\n\t\thighPriority: todos.items.filter((t) => t.priority === \"high\" && !t.completed).length,\n\t};\n}\n"]}
@@ -0,0 +1,117 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
2
+ import { dirname, join } from "path";
3
+ import { getAgentDir } from "../config.js";
4
+ const TODO_FILE_NAME = "todo.json";
5
+ function getTodoFilePath() {
6
+ return join(getAgentDir(), TODO_FILE_NAME);
7
+ }
8
+ function ensureDir(path) {
9
+ const dir = dirname(path);
10
+ if (!existsSync(dir)) {
11
+ mkdirSync(dir, { recursive: true });
12
+ }
13
+ }
14
+ function generateId() {
15
+ return `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
16
+ }
17
+ export function loadTodos() {
18
+ const filePath = getTodoFilePath();
19
+ if (!existsSync(filePath)) {
20
+ return { items: [], updatedAt: new Date().toISOString() };
21
+ }
22
+ try {
23
+ const content = readFileSync(filePath, "utf-8");
24
+ return JSON.parse(content);
25
+ }
26
+ catch {
27
+ return { items: [], updatedAt: new Date().toISOString() };
28
+ }
29
+ }
30
+ function saveTodos(todos) {
31
+ const filePath = getTodoFilePath();
32
+ ensureDir(filePath);
33
+ todos.updatedAt = new Date().toISOString();
34
+ writeFileSync(filePath, JSON.stringify(todos, null, 2), "utf-8");
35
+ }
36
+ export function addTodo(text, options) {
37
+ const todos = loadTodos();
38
+ const newItem = {
39
+ id: generateId(),
40
+ text: text.trim(),
41
+ completed: false,
42
+ createdAt: new Date().toISOString(),
43
+ priority: options?.priority ?? "medium",
44
+ tags: options?.tags ?? [],
45
+ };
46
+ todos.items.push(newItem);
47
+ saveTodos(todos);
48
+ return newItem;
49
+ }
50
+ export function completeTodo(idOrText) {
51
+ const todos = loadTodos();
52
+ const item = todos.items.find((t) => t.id === idOrText || t.text.toLowerCase() === idOrText.toLowerCase());
53
+ if (!item || item.completed)
54
+ return null;
55
+ item.completed = true;
56
+ item.completedAt = new Date().toISOString();
57
+ saveTodos(todos);
58
+ return item;
59
+ }
60
+ export function uncompleteTodo(idOrText) {
61
+ const todos = loadTodos();
62
+ const item = todos.items.find((t) => t.id === idOrText || t.text.toLowerCase() === idOrText.toLowerCase());
63
+ if (!item || !item.completed)
64
+ return null;
65
+ item.completed = false;
66
+ delete item.completedAt;
67
+ saveTodos(todos);
68
+ return item;
69
+ }
70
+ export function removeTodo(idOrText) {
71
+ const todos = loadTodos();
72
+ const index = todos.items.findIndex((t) => t.id === idOrText || t.text.toLowerCase() === idOrText.toLowerCase());
73
+ if (index === -1)
74
+ return null;
75
+ const [removed] = todos.items.splice(index, 1);
76
+ saveTodos(todos);
77
+ return removed;
78
+ }
79
+ export function clearCompleted() {
80
+ const todos = loadTodos();
81
+ const initialCount = todos.items.length;
82
+ todos.items = todos.items.filter((t) => !t.completed);
83
+ const removedCount = initialCount - todos.items.length;
84
+ if (removedCount > 0) {
85
+ saveTodos(todos);
86
+ }
87
+ return removedCount;
88
+ }
89
+ export function clearAll() {
90
+ saveTodos({ items: [], updatedAt: new Date().toISOString() });
91
+ }
92
+ export function listTodos(filter) {
93
+ const todos = loadTodos();
94
+ switch (filter) {
95
+ case "active":
96
+ return todos.items.filter((t) => !t.completed);
97
+ case "completed":
98
+ return todos.items.filter((t) => t.completed);
99
+ default:
100
+ return todos.items;
101
+ }
102
+ }
103
+ export function searchTodos(query) {
104
+ const todos = loadTodos();
105
+ const lowerQuery = query.toLowerCase();
106
+ return todos.items.filter((t) => t.text.toLowerCase().includes(lowerQuery) || t.tags.some((tag) => tag.toLowerCase().includes(lowerQuery)));
107
+ }
108
+ export function getStats() {
109
+ const todos = loadTodos();
110
+ return {
111
+ total: todos.items.length,
112
+ active: todos.items.filter((t) => !t.completed).length,
113
+ completed: todos.items.filter((t) => t.completed).length,
114
+ highPriority: todos.items.filter((t) => t.priority === "high" && !t.completed).length,
115
+ };
116
+ }
117
+ //# sourceMappingURL=todo-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"todo-manager.js","sourceRoot":"","sources":["../../src/core/todo-manager.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"fs\";\nimport { dirname, join } from \"path\";\nimport { getAgentDir } from \"../config.js\";\n\nexport interface TodoItem {\n\tid: string;\n\ttext: string;\n\tcompleted: boolean;\n\tcreatedAt: string;\n\tcompletedAt?: string;\n\tpriority: \"low\" | \"medium\" | \"high\";\n\ttags: string[];\n}\n\nexport interface TodoList {\n\titems: TodoItem[];\n\tupdatedAt: string;\n}\n\nconst TODO_FILE_NAME = \"todo.json\";\n\nfunction getTodoFilePath(): string {\n\treturn join(getAgentDir(), TODO_FILE_NAME);\n}\n\nfunction ensureDir(path: string): void {\n\tconst dir = dirname(path);\n\tif (!existsSync(dir)) {\n\t\tmkdirSync(dir, { recursive: true });\n\t}\n}\n\nfunction generateId(): string {\n\treturn `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;\n}\n\nexport function loadTodos(): TodoList {\n\tconst filePath = getTodoFilePath();\n\tif (!existsSync(filePath)) {\n\t\treturn { items: [], updatedAt: new Date().toISOString() };\n\t}\n\ttry {\n\t\tconst content = readFileSync(filePath, \"utf-8\");\n\t\treturn JSON.parse(content) as TodoList;\n\t} catch {\n\t\treturn { items: [], updatedAt: new Date().toISOString() };\n\t}\n}\n\nfunction saveTodos(todos: TodoList): void {\n\tconst filePath = getTodoFilePath();\n\tensureDir(filePath);\n\ttodos.updatedAt = new Date().toISOString();\n\twriteFileSync(filePath, JSON.stringify(todos, null, 2), \"utf-8\");\n}\n\nexport function addTodo(\n\ttext: string,\n\toptions?: {\n\t\tpriority?: \"low\" | \"medium\" | \"high\";\n\t\ttags?: string[];\n\t},\n): TodoItem {\n\tconst todos = loadTodos();\n\tconst newItem: TodoItem = {\n\t\tid: generateId(),\n\t\ttext: text.trim(),\n\t\tcompleted: false,\n\t\tcreatedAt: new Date().toISOString(),\n\t\tpriority: options?.priority ?? \"medium\",\n\t\ttags: options?.tags ?? [],\n\t};\n\ttodos.items.push(newItem);\n\tsaveTodos(todos);\n\treturn newItem;\n}\n\nexport function completeTodo(idOrText: string): TodoItem | null {\n\tconst todos = loadTodos();\n\tconst item = todos.items.find((t) => t.id === idOrText || t.text.toLowerCase() === idOrText.toLowerCase());\n\tif (!item || item.completed) return null;\n\titem.completed = true;\n\titem.completedAt = new Date().toISOString();\n\tsaveTodos(todos);\n\treturn item;\n}\n\nexport function uncompleteTodo(idOrText: string): TodoItem | null {\n\tconst todos = loadTodos();\n\tconst item = todos.items.find((t) => t.id === idOrText || t.text.toLowerCase() === idOrText.toLowerCase());\n\tif (!item || !item.completed) return null;\n\titem.completed = false;\n\tdelete item.completedAt;\n\tsaveTodos(todos);\n\treturn item;\n}\n\nexport function removeTodo(idOrText: string): TodoItem | null {\n\tconst todos = loadTodos();\n\tconst index = todos.items.findIndex((t) => t.id === idOrText || t.text.toLowerCase() === idOrText.toLowerCase());\n\tif (index === -1) return null;\n\tconst [removed] = todos.items.splice(index, 1);\n\tsaveTodos(todos);\n\treturn removed;\n}\n\nexport function clearCompleted(): number {\n\tconst todos = loadTodos();\n\tconst initialCount = todos.items.length;\n\ttodos.items = todos.items.filter((t) => !t.completed);\n\tconst removedCount = initialCount - todos.items.length;\n\tif (removedCount > 0) {\n\t\tsaveTodos(todos);\n\t}\n\treturn removedCount;\n}\n\nexport function clearAll(): void {\n\tsaveTodos({ items: [], updatedAt: new Date().toISOString() });\n}\n\nexport function listTodos(filter?: \"all\" | \"active\" | \"completed\"): TodoItem[] {\n\tconst todos = loadTodos();\n\tswitch (filter) {\n\t\tcase \"active\":\n\t\t\treturn todos.items.filter((t) => !t.completed);\n\t\tcase \"completed\":\n\t\t\treturn todos.items.filter((t) => t.completed);\n\t\tdefault:\n\t\t\treturn todos.items;\n\t}\n}\n\nexport function searchTodos(query: string): TodoItem[] {\n\tconst todos = loadTodos();\n\tconst lowerQuery = query.toLowerCase();\n\treturn todos.items.filter(\n\t\t(t) => t.text.toLowerCase().includes(lowerQuery) || t.tags.some((tag) => tag.toLowerCase().includes(lowerQuery)),\n\t);\n}\n\nexport function getStats(): {\n\ttotal: number;\n\tactive: number;\n\tcompleted: number;\n\thighPriority: number;\n} {\n\tconst todos = loadTodos();\n\treturn {\n\t\ttotal: todos.items.length,\n\t\tactive: todos.items.filter((t) => !t.completed).length,\n\t\tcompleted: todos.items.filter((t) => t.completed).length,\n\t\thighPriority: todos.items.filter((t) => t.priority === \"high\" && !t.completed).length,\n\t};\n}\n"]}
@@ -0,0 +1,42 @@
1
+ import type { AgentTool } from "@boxiaolanya2008/pi-agent-core";
2
+ import { type Static } from "@sinclair/typebox";
3
+ declare const BatchWriteSchema: import("@sinclair/typebox").TObject<{
4
+ operation: import("@sinclair/typebox").TLiteral<"batch_write">;
5
+ files: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
6
+ path: import("@sinclair/typebox").TString;
7
+ content: import("@sinclair/typebox").TString;
8
+ }>>;
9
+ options: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TObject<{
10
+ atomic: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
11
+ backup: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
12
+ overwrite: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
13
+ createDirs: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
14
+ encoding: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
15
+ }>>;
16
+ }>;
17
+ export type BatchWriteInput = Static<typeof BatchWriteSchema>;
18
+ export type BatchWriteFileResult = {
19
+ path: string;
20
+ status: "created" | "updated" | "skipped" | "failed";
21
+ bytes: number;
22
+ backupPath?: string;
23
+ error?: string;
24
+ };
25
+ export type BatchWriteResult = {
26
+ success: boolean;
27
+ total: number;
28
+ succeeded: number;
29
+ failed: number;
30
+ skipped: number;
31
+ files: BatchWriteFileResult[];
32
+ duration: number;
33
+ currentIndex?: number;
34
+ currentFile?: string;
35
+ };
36
+ export declare const batchWriteTool: AgentTool<typeof BatchWriteSchema>;
37
+ export declare function detectBatchWriteIntent(toolCalls: Array<{
38
+ name: string;
39
+ arguments: unknown;
40
+ }>): BatchWriteInput | null;
41
+ export {};
42
+ //# sourceMappingURL=batch-write.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batch-write.d.ts","sourceRoot":"","sources":["../../../src/core/tools/batch-write.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAA2B,MAAM,gCAAgC,CAAC;AACzF,OAAO,EAAE,KAAK,MAAM,EAAQ,MAAM,mBAAmB,CAAC;AAkBtD,QAAA,MAAM,gBAAgB;;;;;;;;;;;;;EAIpB,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC9D,MAAM,MAAM,oBAAoB,GAAG;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AACF,MAAM,MAAM,gBAAgB,GAAG;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,oBAAoB,EAAE,CAAC;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAiOF,eAAO,MAAM,cAAc,EAAE,SAAS,CAAC,OAAO,gBAAgB,CA0B7D,CAAC;AAEF,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC,GAAG,eAAe,GAAG,IAAI,CAmCrH","sourcesContent":["import type { AgentTool, AgentToolUpdateCallback } from \"@boxiaolanya2008/pi-agent-core\";\nimport { type Static, Type } from \"@sinclair/typebox\";\nimport { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from \"fs\";\nimport { homedir } from \"os\";\nimport { basename, dirname, resolve } from \"path\";\n\nconst BatchWriteFileSchema = Type.Object({\n\tpath: Type.String({ description: \"File path to write\" }),\n\tcontent: Type.String({ description: \"File content\" }),\n});\n\nconst BatchWriteOptionsSchema = Type.Object({\n\tatomic: Type.Optional(Type.Boolean({ description: \"Enable atomic write with rollback\", default: true })),\n\tbackup: Type.Optional(Type.Boolean({ description: \"Backup existing files\", default: true })),\n\toverwrite: Type.Optional(Type.Boolean({ description: \"Overwrite existing files\", default: true })),\n\tcreateDirs: Type.Optional(Type.Boolean({ description: \"Create parent directories\", default: true })),\n\tencoding: Type.Optional(Type.String({ description: \"File encoding\", default: \"utf-8\" })),\n});\n\nconst BatchWriteSchema = Type.Object({\n\toperation: Type.Literal(\"batch_write\"),\n\tfiles: Type.Array(BatchWriteFileSchema, { description: \"Files to write\" }),\n\toptions: Type.Optional(BatchWriteOptionsSchema),\n});\n\nexport type BatchWriteInput = Static<typeof BatchWriteSchema>;\nexport type BatchWriteFileResult = {\n\tpath: string;\n\tstatus: \"created\" | \"updated\" | \"skipped\" | \"failed\";\n\tbytes: number;\n\tbackupPath?: string;\n\terror?: string;\n};\nexport type BatchWriteResult = {\n\tsuccess: boolean;\n\ttotal: number;\n\tsucceeded: number;\n\tfailed: number;\n\tskipped: number;\n\tfiles: BatchWriteFileResult[];\n\tduration: number;\n\tcurrentIndex?: number;\n\tcurrentFile?: string;\n};\n\nfunction getBackupDir(): string {\n\tconst backupBase = resolve(homedir(), \".openvibe\", \"backups\");\n\tif (!existsSync(backupBase)) {\n\t\tmkdirSync(backupBase, { recursive: true });\n\t}\n\treturn backupBase;\n}\n\nfunction createBackup(filePath: string): string | null {\n\tif (!existsSync(filePath)) {\n\t\treturn null;\n\t}\n\n\tconst backupDir = getBackupDir();\n\tconst timestamp = Date.now();\n\tconst fileName = basename(filePath);\n\tconst backupPath = resolve(backupDir, `${fileName}.${timestamp}.bak`);\n\n\ttry {\n\t\tconst content = readFileSync(filePath);\n\t\twriteFileSync(backupPath, content);\n\t\treturn backupPath;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction restoreBackup(backupPath: string, originalPath: string): boolean {\n\ttry {\n\t\tif (!existsSync(backupPath)) {\n\t\t\treturn false;\n\t\t}\n\t\tconst content = readFileSync(backupPath);\n\t\twriteFileSync(originalPath, content);\n\t\tunlinkSync(backupPath);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction cleanupBackup(backupPath: string): void {\n\ttry {\n\t\tif (existsSync(backupPath)) {\n\t\t\tunlinkSync(backupPath);\n\t\t}\n\t} catch {}\n}\n\nfunction writeSingleFile(\n\tfilePath: string,\n\tcontent: string,\n\toptions: Required<Static<typeof BatchWriteOptionsSchema>>,\n): BatchWriteFileResult {\n\tconst absolutePath = resolve(filePath);\n\tconst parentDir = dirname(absolutePath);\n\n\ttry {\n\t\tconst fileExists = existsSync(absolutePath);\n\n\t\tif (fileExists && !options.overwrite) {\n\t\t\treturn {\n\t\t\t\tpath: absolutePath,\n\t\t\t\tstatus: \"skipped\",\n\t\t\t\tbytes: 0,\n\t\t\t};\n\t\t}\n\n\t\tif (!existsSync(parentDir)) {\n\t\t\tif (options.createDirs) {\n\t\t\t\tmkdirSync(parentDir, { recursive: true });\n\t\t\t} else {\n\t\t\t\treturn {\n\t\t\t\t\tpath: absolutePath,\n\t\t\t\t\tstatus: \"failed\",\n\t\t\t\t\tbytes: 0,\n\t\t\t\t\terror: `Parent directory does not exist: ${parentDir}`,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tlet backupPath: string | undefined;\n\n\t\tif (fileExists && options.backup && options.atomic) {\n\t\t\tconst backup = createBackup(absolutePath);\n\t\t\tif (backup) {\n\t\t\t\tbackupPath = backup;\n\t\t\t}\n\t\t}\n\n\t\twriteFileSync(absolutePath, content, { encoding: options.encoding as BufferEncoding });\n\t\tconst bytes = Buffer.byteLength(content, options.encoding as BufferEncoding);\n\n\t\tif (backupPath) {\n\t\t\tcleanupBackup(backupPath);\n\t\t}\n\n\t\treturn {\n\t\t\tpath: absolutePath,\n\t\t\tstatus: fileExists ? \"updated\" : \"created\",\n\t\t\tbytes,\n\t\t\tbackupPath,\n\t\t};\n\t} catch (error) {\n\t\treturn {\n\t\t\tpath: absolutePath,\n\t\t\tstatus: \"failed\",\n\t\t\tbytes: 0,\n\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t};\n\t}\n}\n\nfunction executeBatchWrite(\n\tinput: BatchWriteInput,\n\tonUpdate?: AgentToolUpdateCallback<BatchWriteResult>,\n): BatchWriteResult {\n\tconst startTime = Date.now();\n\tconst options: Required<Static<typeof BatchWriteOptionsSchema>> = {\n\t\tatomic: input.options?.atomic ?? true,\n\t\tbackup: input.options?.backup ?? true,\n\t\toverwrite: input.options?.overwrite ?? true,\n\t\tcreateDirs: input.options?.createDirs ?? true,\n\t\tencoding: input.options?.encoding ?? \"utf-8\",\n\t};\n\n\tconst results: BatchWriteFileResult[] = [];\n\tconst backups = new Map<string, string>();\n\n\tfor (const file of input.files) {\n\t\tconst absolutePath = resolve(file.path);\n\n\t\tif (existsSync(absolutePath) && options.backup && options.atomic) {\n\t\t\tconst backup = createBackup(absolutePath);\n\t\t\tif (backup) {\n\t\t\t\tbackups.set(absolutePath, backup);\n\t\t\t}\n\t\t}\n\t}\n\n\tfor (let i = 0; i < input.files.length; i++) {\n\t\tconst file = input.files[i];\n\t\tconst result = writeSingleFile(file.path, file.content, options);\n\t\tresults.push(result);\n\n\t\tif (result.status === \"created\" || result.status === \"updated\") {\n\t\t\tconst backup = backups.get(result.path);\n\t\t\tif (backup) {\n\t\t\t\tcleanupBackup(backup);\n\t\t\t\tbackups.delete(result.path);\n\t\t\t}\n\t\t}\n\n\t\tconst statusIcon =\n\t\t\tresult.status === \"created\"\n\t\t\t\t? \"+\"\n\t\t\t\t: result.status === \"updated\"\n\t\t\t\t\t? \"~\"\n\t\t\t\t\t: result.status === \"skipped\"\n\t\t\t\t\t\t? \"-\"\n\t\t\t\t\t\t: \"x\";\n\n\t\tonUpdate?.({\n\t\t\tcontent: [\n\t\t\t\t{\n\t\t\t\t\ttype: \"text\",\n\t\t\t\t\ttext: `[${statusIcon}] ${result.path} (${result.bytes} bytes)`,\n\t\t\t\t},\n\t\t\t],\n\t\t\tdetails: {\n\t\t\t\tsuccess: false,\n\t\t\t\ttotal: input.files.length,\n\t\t\t\tsucceeded: results.filter((r) => r.status === \"created\" || r.status === \"updated\").length,\n\t\t\t\tfailed: results.filter((r) => r.status === \"failed\").length,\n\t\t\t\tskipped: results.filter((r) => r.status === \"skipped\").length,\n\t\t\t\tfiles: results,\n\t\t\t\tduration: Date.now() - startTime,\n\t\t\t\tcurrentIndex: i,\n\t\t\t\tcurrentFile: result.path,\n\t\t\t},\n\t\t});\n\t}\n\n\tconst failedCount = results.filter((r) => r.status === \"failed\").length;\n\n\tif (failedCount > 0 && options.atomic) {\n\t\tfor (const [originalPath, backupPath] of backups) {\n\t\t\trestoreBackup(backupPath, originalPath);\n\t\t}\n\n\t\tfor (const result of results) {\n\t\t\tif (result.status === \"created\") {\n\t\t\t\ttry {\n\t\t\t\t\tif (existsSync(result.path)) {\n\t\t\t\t\t\tunlinkSync(result.path);\n\t\t\t\t\t}\n\t\t\t\t\tresult.status = \"failed\";\n\t\t\t\t\tresult.error = \"Rolled back due to batch failure\";\n\t\t\t\t} catch {}\n\t\t\t} else if (result.status === \"updated\") {\n\t\t\t\tconst backup = backups.get(result.path);\n\t\t\t\tif (backup) {\n\t\t\t\t\trestoreBackup(backup, result.path);\n\t\t\t\t\tresult.status = \"failed\";\n\t\t\t\t\tresult.error = \"Rolled back due to batch failure\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tconst duration = Date.now() - startTime;\n\n\treturn {\n\t\tsuccess: failedCount === 0,\n\t\ttotal: input.files.length,\n\t\tsucceeded: results.filter((r) => r.status === \"created\" || r.status === \"updated\").length,\n\t\tfailed: results.filter((r) => r.status === \"failed\").length,\n\t\tskipped: results.filter((r) => r.status === \"skipped\").length,\n\t\tfiles: results,\n\t\tduration,\n\t};\n}\n\nexport const batchWriteTool: AgentTool<typeof BatchWriteSchema> = {\n\tname: \"batch_write\",\n\tlabel: \"batch_write\",\n\tdescription:\n\t\t\"Batch write multiple files with atomic guarantees. Automatically handles directory creation, backup, and rollback on failure.\",\n\tparameters: BatchWriteSchema,\n\texecute: async (_id, input, _signal, onUpdate) => {\n\t\tconst result = executeBatchWrite(input, onUpdate);\n\n\t\tconst lines: string[] = [\n\t\t\t`Batch Write Complete`,\n\t\t\t`====================`,\n\t\t\t`Total: ${result.total} | Success: ${result.succeeded} | Failed: ${result.failed} | Skipped: ${result.skipped}`,\n\t\t\t`Duration: ${result.duration}ms`,\n\t\t];\n\n\t\treturn {\n\t\t\tcontent: [\n\t\t\t\t{\n\t\t\t\t\ttype: \"text\",\n\t\t\t\t\ttext: lines.join(\"\\n\"),\n\t\t\t\t},\n\t\t\t],\n\t\t\tdetails: result,\n\t\t};\n\t},\n};\n\nexport function detectBatchWriteIntent(toolCalls: Array<{ name: string; arguments: unknown }>): BatchWriteInput | null {\n\tconst writeCalls = toolCalls.filter(\n\t\t(c) => c.name === \"write\" || c.name === \"write_file\" || c.name === \"create_file\",\n\t);\n\n\tif (writeCalls.length < 2) {\n\t\treturn null;\n\t}\n\n\tconst files: Array<{ path: string; content: string }> = [];\n\n\tfor (const call of writeCalls) {\n\t\tconst args = call.arguments as { path?: string; file_path?: string; content?: string };\n\t\tconst path = args.path || args.file_path;\n\t\tconst content = args.content;\n\n\t\tif (path && content !== undefined) {\n\t\t\tfiles.push({ path, content });\n\t\t}\n\t}\n\n\tif (files.length < 2) {\n\t\treturn null;\n\t}\n\n\treturn {\n\t\toperation: \"batch_write\",\n\t\tfiles,\n\t\toptions: {\n\t\t\tatomic: true,\n\t\t\tbackup: true,\n\t\t\toverwrite: true,\n\t\t\tcreateDirs: true,\n\t\t},\n\t};\n}\n"]}