headlesscode 1.0.2

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 (232) hide show
  1. package/ATTRIBUTION.md +53 -0
  2. package/CODE_OF_CONDUCT.md +130 -0
  3. package/CONTRIBUTING.md +107 -0
  4. package/LICENSE +202 -0
  5. package/README.md +486 -0
  6. package/SECURITY.md +211 -0
  7. package/bin/headlesscode.mjs +83 -0
  8. package/package.json +63 -0
  9. package/shared/prompts/review-mode-prompt-short.md +93 -0
  10. package/shared/prompts/review-mode-prompt.md +281 -0
  11. package/shared/rules-code/rules.md +22 -0
  12. package/shared/stacks/cpp/rules.md +30 -0
  13. package/shared/stacks/fastapi/rules.md +30 -0
  14. package/shared/stacks/javascript/rules.md +37 -0
  15. package/shared/stacks/postgresql/rules.md +31 -0
  16. package/shared/stacks/python/rules.md +35 -0
  17. package/shared/stacks/react/rules.md +11 -0
  18. package/shared/stacks/typescript/rules.md +10 -0
  19. package/src/budget/budget.ts +221 -0
  20. package/src/budget/concurrency.ts +126 -0
  21. package/src/budget/cost.ts +309 -0
  22. package/src/budget/index.ts +8 -0
  23. package/src/checkpoints/cli.ts +256 -0
  24. package/src/checkpoints/service.ts +227 -0
  25. package/src/cli.ts +1535 -0
  26. package/src/cloud/docker-provider.ts +334 -0
  27. package/src/cloud/provider.ts +300 -0
  28. package/src/codeintel/call-graph.ts +78 -0
  29. package/src/codeintel/find-references.ts +123 -0
  30. package/src/codeintel/go-to-definition.ts +193 -0
  31. package/src/codeintel/handlers.ts +190 -0
  32. package/src/codeintel/import-graph.ts +173 -0
  33. package/src/codeintel/outline.ts +180 -0
  34. package/src/codeintel/position.ts +77 -0
  35. package/src/codeintel/program.ts +350 -0
  36. package/src/codeintel/rename-symbol.ts +213 -0
  37. package/src/codeintel/tools.ts +280 -0
  38. package/src/codemap/build.ts +135 -0
  39. package/src/codemap/cli.ts +190 -0
  40. package/src/codemap/extract.ts +339 -0
  41. package/src/codemap/files.ts +236 -0
  42. package/src/codemap/fingerprint.ts +65 -0
  43. package/src/codemap/flows.ts +62 -0
  44. package/src/codemap/html.ts +451 -0
  45. package/src/codemap/lock.ts +80 -0
  46. package/src/codemap/types.ts +101 -0
  47. package/src/codesearch/airunner-embedder.ts +185 -0
  48. package/src/codesearch/chunk.ts +339 -0
  49. package/src/codesearch/cli.ts +223 -0
  50. package/src/codesearch/embedder.ts +332 -0
  51. package/src/codesearch/files.ts +280 -0
  52. package/src/codesearch/index.ts +469 -0
  53. package/src/codesearch/ollama-embedder.ts +205 -0
  54. package/src/codesearch/search.ts +141 -0
  55. package/src/codesearch/types.ts +100 -0
  56. package/src/config/mode-models.ts +218 -0
  57. package/src/dashboard/aggregate.ts +364 -0
  58. package/src/dashboard/chat-thread.ts +141 -0
  59. package/src/dashboard/checkpoints.ts +124 -0
  60. package/src/dashboard/cli.ts +193 -0
  61. package/src/dashboard/codemap.ts +44 -0
  62. package/src/dashboard/files.ts +121 -0
  63. package/src/dashboard/page.ts +2803 -0
  64. package/src/dashboard/self-improvement-metrics.ts +282 -0
  65. package/src/dashboard/server.ts +1103 -0
  66. package/src/dashboard/session-launch.ts +310 -0
  67. package/src/dashboard/timeline.ts +273 -0
  68. package/src/dashboard/tool-exec.ts +107 -0
  69. package/src/dashboard/trend-cli.ts +141 -0
  70. package/src/dashboard/trend.ts +413 -0
  71. package/src/decision-proxy/cli.ts +261 -0
  72. package/src/decision-proxy/proxy.ts +569 -0
  73. package/src/deploy/gate-cli.ts +147 -0
  74. package/src/deploy/gate.ts +254 -0
  75. package/src/engine/condense.ts +512 -0
  76. package/src/engine/events.ts +428 -0
  77. package/src/engine/handoff.ts +71 -0
  78. package/src/engine/lazy-tools.ts +160 -0
  79. package/src/engine/local-explore.ts +653 -0
  80. package/src/engine/logger.ts +96 -0
  81. package/src/engine/loop.ts +5517 -0
  82. package/src/engine/parser.ts +347 -0
  83. package/src/engine/prompt.ts +860 -0
  84. package/src/engine/reports.ts +47 -0
  85. package/src/engine/stacks.ts +448 -0
  86. package/src/engine/types.ts +291 -0
  87. package/src/engine/usage.ts +186 -0
  88. package/src/github/app-auth.ts +161 -0
  89. package/src/github/cli.ts +448 -0
  90. package/src/github/installations.ts +133 -0
  91. package/src/github/pr.ts +321 -0
  92. package/src/github/provision.ts +118 -0
  93. package/src/github/push.ts +122 -0
  94. package/src/index-util.ts +50 -0
  95. package/src/index.ts +81 -0
  96. package/src/init/cli.ts +248 -0
  97. package/src/init/gitignore.ts +74 -0
  98. package/src/llm/ollama.ts +308 -0
  99. package/src/llm/openrouter.ts +868 -0
  100. package/src/llm/preflight.ts +367 -0
  101. package/src/llm/transcript-capture.ts +84 -0
  102. package/src/memory/embed.ts +110 -0
  103. package/src/memory/index.ts +22 -0
  104. package/src/memory/local.ts +259 -0
  105. package/src/memory/summarizer.ts +283 -0
  106. package/src/memory/types.ts +153 -0
  107. package/src/memory/uwuchat.ts +157 -0
  108. package/src/migrate/cli.ts +115 -0
  109. package/src/orchestrator/analyze-cli.ts +104 -0
  110. package/src/orchestrator/auto-split.ts +206 -0
  111. package/src/orchestrator/cleanup.ts +1003 -0
  112. package/src/orchestrator/cli.ts +3571 -0
  113. package/src/orchestrator/cost-estimate.ts +564 -0
  114. package/src/orchestrator/cost-history-cli.ts +242 -0
  115. package/src/orchestrator/cost-history.ts +397 -0
  116. package/src/orchestrator/git-sync.ts +250 -0
  117. package/src/orchestrator/index.ts +153 -0
  118. package/src/orchestrator/log-analysis.ts +0 -0
  119. package/src/orchestrator/merge-check.ts +108 -0
  120. package/src/orchestrator/pipeline.ts +411 -0
  121. package/src/orchestrator/resume.ts +1940 -0
  122. package/src/orchestrator/reviewer.ts +503 -0
  123. package/src/orchestrator/split.ts +296 -0
  124. package/src/orchestrator/state.ts +542 -0
  125. package/src/orchestrator/status.ts +697 -0
  126. package/src/orchestrator/verification-gate.ts +134 -0
  127. package/src/orchestrator/watch.ts +898 -0
  128. package/src/permissions/commands.ts +1083 -0
  129. package/src/permissions/config.ts +241 -0
  130. package/src/permissions/index.ts +12 -0
  131. package/src/permissions/protected-files.ts +96 -0
  132. package/src/permissions/store-protection.ts +272 -0
  133. package/src/project-store.ts +648 -0
  134. package/src/projects/cli.ts +382 -0
  135. package/src/qa/qa.ts +487 -0
  136. package/src/tools/browser/handler.ts +346 -0
  137. package/src/tools/browser/service.ts +406 -0
  138. package/src/tools/browser/smoke.ts +78 -0
  139. package/src/tools/browser/tool.ts +99 -0
  140. package/src/tools/executor.ts +2575 -0
  141. package/src/tools/language-detect.ts +183 -0
  142. package/src/tools/output-summarizer.ts +369 -0
  143. package/src/tools/run-tests.ts +302 -0
  144. package/src/tools/set-indentation-tool.ts +49 -0
  145. package/src/tools/test-selection.ts +160 -0
  146. package/src/vendor/tests/smoke.ts +103 -0
  147. package/src/vendor/zoo-code/VENDOR-NOTES.md +213 -0
  148. package/src/vendor/zoo-code/shim/anthropic.ts +71 -0
  149. package/src/vendor/zoo-code/shim/openai.d.ts +60 -0
  150. package/src/vendor/zoo-code/shim/os-name.ts +18 -0
  151. package/src/vendor/zoo-code/shim/strip-bom.ts +14 -0
  152. package/src/vendor/zoo-code/shim/vscode.ts +76 -0
  153. package/src/vendor/zoo-code/src/core/config/CustomModesManager.ts +1015 -0
  154. package/src/vendor/zoo-code/src/core/diff/strategies/multi-search-replace.ts +670 -0
  155. package/src/vendor/zoo-code/src/core/prompts/sections/capabilities.ts +46 -0
  156. package/src/vendor/zoo-code/src/core/prompts/sections/custom-instructions.ts +559 -0
  157. package/src/vendor/zoo-code/src/core/prompts/sections/index.ts +10 -0
  158. package/src/vendor/zoo-code/src/core/prompts/sections/markdown-formatting.ts +7 -0
  159. package/src/vendor/zoo-code/src/core/prompts/sections/modes.ts +35 -0
  160. package/src/vendor/zoo-code/src/core/prompts/sections/objective.ts +13 -0
  161. package/src/vendor/zoo-code/src/core/prompts/sections/rules.ts +95 -0
  162. package/src/vendor/zoo-code/src/core/prompts/sections/skills.ts +105 -0
  163. package/src/vendor/zoo-code/src/core/prompts/sections/system-info.ts +30 -0
  164. package/src/vendor/zoo-code/src/core/prompts/sections/tool-use-guidelines.ts +9 -0
  165. package/src/vendor/zoo-code/src/core/prompts/sections/tool-use.ts +7 -0
  166. package/src/vendor/zoo-code/src/core/prompts/system.ts +176 -0
  167. package/src/vendor/zoo-code/src/core/prompts/tools/native-tools/access_mcp_resource.ts +41 -0
  168. package/src/vendor/zoo-code/src/core/prompts/tools/native-tools/apply_diff.ts +40 -0
  169. package/src/vendor/zoo-code/src/core/prompts/tools/native-tools/apply_patch.ts +61 -0
  170. package/src/vendor/zoo-code/src/core/prompts/tools/native-tools/ask_followup_question.ts +62 -0
  171. package/src/vendor/zoo-code/src/core/prompts/tools/native-tools/attempt_completion.ts +33 -0
  172. package/src/vendor/zoo-code/src/core/prompts/tools/native-tools/codebase_search.ts +43 -0
  173. package/src/vendor/zoo-code/src/core/prompts/tools/native-tools/converters.ts +109 -0
  174. package/src/vendor/zoo-code/src/core/prompts/tools/native-tools/edit.ts +48 -0
  175. package/src/vendor/zoo-code/src/core/prompts/tools/native-tools/edit_file.ts +72 -0
  176. package/src/vendor/zoo-code/src/core/prompts/tools/native-tools/execute_command.ts +54 -0
  177. package/src/vendor/zoo-code/src/core/prompts/tools/native-tools/generate_image.ts +51 -0
  178. package/src/vendor/zoo-code/src/core/prompts/tools/native-tools/index.ts +75 -0
  179. package/src/vendor/zoo-code/src/core/prompts/tools/native-tools/list_files.ts +41 -0
  180. package/src/vendor/zoo-code/src/core/prompts/tools/native-tools/mcp_server.ts +75 -0
  181. package/src/vendor/zoo-code/src/core/prompts/tools/native-tools/new_task.ts +39 -0
  182. package/src/vendor/zoo-code/src/core/prompts/tools/native-tools/read_command_output.ts +81 -0
  183. package/src/vendor/zoo-code/src/core/prompts/tools/native-tools/read_file.ts +169 -0
  184. package/src/vendor/zoo-code/src/core/prompts/tools/native-tools/run_slash_command.ts +31 -0
  185. package/src/vendor/zoo-code/src/core/prompts/tools/native-tools/search_files.ts +50 -0
  186. package/src/vendor/zoo-code/src/core/prompts/tools/native-tools/search_replace.ts +51 -0
  187. package/src/vendor/zoo-code/src/core/prompts/tools/native-tools/skill.ts +33 -0
  188. package/src/vendor/zoo-code/src/core/prompts/tools/native-tools/switch_mode.ts +31 -0
  189. package/src/vendor/zoo-code/src/core/prompts/tools/native-tools/update_todo_list.ts +54 -0
  190. package/src/vendor/zoo-code/src/core/prompts/tools/native-tools/write_to_file.ts +40 -0
  191. package/src/vendor/zoo-code/src/core/prompts/types.ts +12 -0
  192. package/src/vendor/zoo-code/src/i18n/index.ts +19 -0
  193. package/src/vendor/zoo-code/src/integrations/misc/extract-text.ts +81 -0
  194. package/src/vendor/zoo-code/src/services/checkpoints/RepoPerTaskCheckpointService.ts +15 -0
  195. package/src/vendor/zoo-code/src/services/checkpoints/ShadowCheckpointService.ts +553 -0
  196. package/src/vendor/zoo-code/src/services/checkpoints/excludes.ts +212 -0
  197. package/src/vendor/zoo-code/src/services/checkpoints/index.ts +3 -0
  198. package/src/vendor/zoo-code/src/services/checkpoints/types.ts +35 -0
  199. package/src/vendor/zoo-code/src/services/code-index/manager.ts +19 -0
  200. package/src/vendor/zoo-code/src/services/mcp/McpHub.ts +36 -0
  201. package/src/vendor/zoo-code/src/services/roo-config/index.ts +441 -0
  202. package/src/vendor/zoo-code/src/services/search/file-search.ts +143 -0
  203. package/src/vendor/zoo-code/src/services/skills/SkillsManager.ts +20 -0
  204. package/src/vendor/zoo-code/src/shared/globalFileNames.ts +9 -0
  205. package/src/vendor/zoo-code/src/shared/language.ts +43 -0
  206. package/src/vendor/zoo-code/src/shared/modes.ts +257 -0
  207. package/src/vendor/zoo-code/src/shared/tools.ts +385 -0
  208. package/src/vendor/zoo-code/src/utils/fs.ts +39 -0
  209. package/src/vendor/zoo-code/src/utils/globalContext.ts +22 -0
  210. package/src/vendor/zoo-code/src/utils/json-schema.ts +16 -0
  211. package/src/vendor/zoo-code/src/utils/logging.ts +21 -0
  212. package/src/vendor/zoo-code/src/utils/mcp-name.ts +190 -0
  213. package/src/vendor/zoo-code/src/utils/object.ts +18 -0
  214. package/src/vendor/zoo-code/src/utils/path.ts +94 -0
  215. package/src/vendor/zoo-code/src/utils/shell.ts +376 -0
  216. package/src/vendor/zoo-code/src/utils/text-normalization.ts +99 -0
  217. package/src/vendor/zoo-code/types/global-settings.ts +19 -0
  218. package/src/vendor/zoo-code/types/index.ts +22 -0
  219. package/src/vendor/zoo-code/types/message.ts +375 -0
  220. package/src/vendor/zoo-code/types/mode.ts +241 -0
  221. package/src/vendor/zoo-code/types/todo.ts +19 -0
  222. package/src/vendor/zoo-code/types/tool-params.ts +116 -0
  223. package/src/vendor/zoo-code/types/tool.ts +67 -0
  224. package/src/vendor/zoo-code/types/vscode.ts +84 -0
  225. package/src/vision/describe.ts +242 -0
  226. package/src/vision/tool.ts +91 -0
  227. package/src/watcher/cli.ts +369 -0
  228. package/src/watcher/github.ts +304 -0
  229. package/src/watcher/index.ts +59 -0
  230. package/src/watcher/state.ts +254 -0
  231. package/src/watcher/watch.ts +562 -0
  232. package/tsconfig.json +18 -0
@@ -0,0 +1,95 @@
1
+ import type { SystemPromptSettings } from "../types"
2
+
3
+ import { getShell } from "../../../utils/shell"
4
+
5
+ /**
6
+ * Returns the appropriate command chaining operator based on the user's shell.
7
+ * - Unix shells (bash, zsh, etc.): `&&` (run next command only if previous succeeds)
8
+ * - PowerShell: `;` (semicolon for command separation)
9
+ * - cmd.exe: `&&` (conditional execution, same as Unix)
10
+ * @internal Exported for testing purposes
11
+ */
12
+ export function getCommandChainOperator(): string {
13
+ const shell = getShell().toLowerCase()
14
+
15
+ // Check for PowerShell (both Windows PowerShell and PowerShell Core)
16
+ if (shell.includes("powershell") || shell.includes("pwsh")) {
17
+ return ";"
18
+ }
19
+
20
+ // Check for cmd.exe
21
+ if (shell.includes("cmd.exe")) {
22
+ return "&&"
23
+ }
24
+
25
+ // Default to Unix-style && for bash, zsh, sh, and other shells
26
+ // This also covers Git Bash, WSL, and other Unix-like environments on Windows
27
+ return "&&"
28
+ }
29
+
30
+ /**
31
+ * Returns a shell-specific note about command chaining syntax and platform-specific utilities.
32
+ */
33
+ function getCommandChainNote(): string {
34
+ const shell = getShell().toLowerCase()
35
+
36
+ // Check for PowerShell
37
+ if (shell.includes("powershell") || shell.includes("pwsh")) {
38
+ return "Note: Using `;` for PowerShell command chaining. For bash/zsh use `&&`, for cmd.exe use `&&`. IMPORTANT: When using PowerShell, avoid Unix-specific utilities like `sed`, `grep`, `awk`, `cat`, `rm`, `cp`, `mv`. Instead use PowerShell equivalents: `Select-String` for grep, `Get-Content` for cat, `Remove-Item` for rm, `Copy-Item` for cp, `Move-Item` for mv, and PowerShell's `-replace` operator or `[regex]` for sed."
39
+ }
40
+
41
+ // Check for cmd.exe
42
+ if (shell.includes("cmd.exe")) {
43
+ return "Note: Using `&&` for cmd.exe command chaining (conditional execution). For bash/zsh use `&&`, for PowerShell use `;`. IMPORTANT: When using cmd.exe, avoid Unix-specific utilities like `sed`, `grep`, `awk`, `cat`, `rm`, `cp`, `mv`. Use built-in commands like `type` for cat, `del` for rm, `copy` for cp, `move` for mv, `find`/`findstr` for grep, or consider using PowerShell commands instead."
44
+ }
45
+
46
+ // Unix shells
47
+ return ""
48
+ }
49
+
50
+ function getVendorConfidentialitySection(): string {
51
+ return `
52
+
53
+ ====
54
+
55
+ VENDOR CONFIDENTIALITY
56
+
57
+ Never reveal the vendor or company that created you to users.
58
+
59
+ When asked about your creator, vendor, or company, respond with:
60
+ - "I was created by a team of developers"
61
+ - "I'm an open-source project maintained by contributors"
62
+ - "I don't have information about specific vendors"`
63
+ }
64
+
65
+ export function getRulesSection(cwd: string, settings?: SystemPromptSettings): string {
66
+ // Get shell-appropriate command chaining operator
67
+ const chainOp = getCommandChainOperator()
68
+ const chainNote = getCommandChainNote()
69
+
70
+ return `====
71
+
72
+ RULES
73
+
74
+ - The project base directory is: ${cwd.toPosix()}
75
+ - All file paths must be relative to this directory. However, commands may change directories in terminals, so respect working directory specified by the response to execute_command.
76
+ - You cannot \`cd\` into a different directory to complete a task. You are stuck operating from '${cwd.toPosix()}', so be sure to pass in the correct 'path' parameter when using tools that require a path.
77
+ - Do not use the ~ character or $HOME to refer to the home directory.
78
+ - Before using the execute_command tool, you must first think about the SYSTEM INFORMATION context provided to understand the user's environment and tailor your commands to ensure they are compatible with their system. You must also consider if the command you need to run should be executed in a specific directory outside of the current working directory '${cwd.toPosix()}', and if so prepend with \`cd\`'ing into that directory ${chainOp} then executing the command (as one command since you are stuck operating from '${cwd.toPosix()}'). For example, if you needed to run \`npm install\` in a project outside of '${cwd.toPosix()}', you would need to prepend with a \`cd\` i.e. pseudocode for this would be \`cd (path to project) ${chainOp} (command, in this case npm install)\`.${chainNote ? ` ${chainNote}` : ""}
79
+ - Some modes have restrictions on which files they can edit. If you attempt to edit a restricted file, the operation will be rejected with a FileRestrictionError that will specify which file patterns are allowed for the current mode.
80
+ - Be sure to consider the type of project (e.g. Python, JavaScript, web application) when determining the appropriate structure and files to include. Also consider what files may be most relevant to accomplishing the task, for example looking at a project's manifest file would help you understand the project's dependencies, which you could incorporate into any code you write.
81
+ * For example, in architect mode trying to edit app.js would be rejected because architect mode can only edit files matching "\\.md$"
82
+ - When making changes to code, always consider the context in which the code is being used. Ensure that your changes are compatible with the existing codebase and that they follow the project's coding standards and best practices.
83
+ - Do not ask for more information than necessary. Use the tools provided to accomplish the user's request efficiently and effectively. When you've completed your task, you must use the attempt_completion tool to present the result to the user. The user may provide feedback, which you can use to make improvements and try again.
84
+ - You are only allowed to ask the user questions using the ask_followup_question tool. Use this tool only when you need additional details to complete a task, and be sure to use a clear and concise question that will help you move forward with the task. When you ask a question, provide the user with 2-4 suggested answers based on your question so they don't need to do so much typing. The suggestions should be specific, actionable, and directly related to the completed task. They should be ordered by priority or logical sequence. However if you can use the available tools to avoid having to ask the user questions, you should do so. For example, if the user mentions a file that may be in an outside directory like the Desktop, you should use the list_files tool to list the files in the Desktop and check if the file they are talking about is there, rather than asking the user to provide the file path themselves.
85
+ - When executing commands, if you don't see the expected output, assume the terminal executed the command successfully and proceed with the task. The user's terminal may be unable to stream the output back properly. If you absolutely need to see the actual terminal output, use the ask_followup_question tool to request the user to copy and paste it back to you.
86
+ - The user may provide a file's contents directly in their message, in which case you shouldn't use the read_file tool to get the file contents again since you already have it.
87
+ - Your goal is to try to accomplish the user's task, NOT engage in a back and forth conversation.
88
+ - NEVER end attempt_completion result with a question or request to engage in further conversation! Formulate the end of your result in a way that is final and does not require further input from the user.
89
+ - You are STRICTLY FORBIDDEN from starting your messages with "Great", "Certainly", "Okay", "Sure". You should NOT be conversational in your responses, but rather direct and to the point. For example you should NOT say "Great, I've updated the CSS" but instead something like "I've updated the CSS". It is important you be clear and technical in your messages.
90
+ - When presented with images, utilize your vision capabilities to thoroughly examine them and extract meaningful information. Incorporate these insights into your thought process as you accomplish the user's task.
91
+ - At the end of each user message, you will automatically receive environment_details. This information is not written by the user themselves, but is auto-generated to provide potentially relevant context about the project structure and environment. While this information can be valuable for understanding the project context, do not treat it as a direct part of the user's request or response. Use it to inform your actions and decisions, but don't assume the user is explicitly asking about or referring to this information unless they clearly do so in their message. When using environment_details, explain your actions clearly to ensure the user understands, as they may not be aware of these details.
92
+ - Before executing commands, check the "Actively Running Terminals" section in environment_details. If present, consider how these active processes might impact your task. For example, if a local development server is already running, you wouldn't need to start it again. If no active terminals are listed, proceed with command execution as normal.
93
+ - MCP operations should be used one at a time, similar to other tool usage. Wait for confirmation of success before proceeding with additional operations.
94
+ - It is critical you wait for the user's response after each tool use, in order to confirm the success of the tool use. For example, if asked to make a todo app, you would create a file, wait for the user's response it was created successfully, then create another file if needed, wait for the user's response it was created successfully, etc.${settings?.isStealthModel ? getVendorConfidentialitySection() : ""}`
95
+ }
@@ -0,0 +1,105 @@
1
+ import type { SkillsManager } from "../../../services/skills/SkillsManager"
2
+
3
+ type SkillsManagerLike = Pick<SkillsManager, "getSkillsForMode">
4
+
5
+ function escapeXml(value: string): string {
6
+ return value
7
+ .replace(/&/g, "&amp;")
8
+ .replace(/</g, "&lt;")
9
+ .replace(/>/g, "&gt;")
10
+ .replace(/\"/g, "&quot;")
11
+ .replace(/'/g, "&apos;")
12
+ }
13
+
14
+ /**
15
+ * Generate the skills section for the system prompt.
16
+ * Only includes skills relevant to the current mode.
17
+ * Format matches the modes section style.
18
+ *
19
+ * @param skillsManager - The SkillsManager instance
20
+ * @param currentMode - The current mode slug (e.g., 'code', 'architect')
21
+ */
22
+ export async function getSkillsSection(
23
+ skillsManager: SkillsManagerLike | undefined,
24
+ currentMode: string | undefined,
25
+ ): Promise<string> {
26
+ if (!skillsManager || !currentMode) return ""
27
+
28
+ // Get skills filtered by current mode (with override resolution)
29
+ const skills = skillsManager.getSkillsForMode(currentMode)
30
+ if (skills.length === 0) return ""
31
+
32
+ const skillsXml = skills
33
+ .map((skill) => {
34
+ const name = escapeXml(skill.name)
35
+ const description = escapeXml(skill.description)
36
+ const locationLine = `\n <location>${escapeXml(skill.path)}</location>`
37
+ return ` <skill>\n <name>${name}</name>\n <description>${description}</description>${locationLine}\n </skill>`
38
+ })
39
+ .join("\n")
40
+
41
+ return `====
42
+
43
+ AVAILABLE SKILLS
44
+
45
+ <available_skills>
46
+ ${skillsXml}
47
+ </available_skills>
48
+
49
+ <mandatory_skill_check>
50
+ REQUIRED PRECONDITION
51
+
52
+ Before producing ANY user-facing response, you MUST perform a skill applicability check.
53
+
54
+ Step 1: Skill Evaluation
55
+ - Evaluate the user's request against ALL available skill <description> entries in <available_skills>.
56
+ - Determine whether at least one skill clearly and unambiguously applies.
57
+
58
+ Step 2: Branching Decision
59
+
60
+ <if_skill_applies>
61
+ - Select EXACTLY ONE skill.
62
+ - Prefer the most specific skill when multiple skills match.
63
+ - Use the skill tool to load the skill by name.
64
+ - Load the skill's instructions fully into context BEFORE continuing.
65
+ - Follow the skill instructions precisely.
66
+ - Do NOT respond outside the skill-defined flow.
67
+ </if_skill_applies>
68
+
69
+ <if_no_skill_applies>
70
+ - Proceed with a normal response.
71
+ - Do NOT load any SKILL.md files.
72
+ </if_no_skill_applies>
73
+
74
+ CONSTRAINTS:
75
+ - Do NOT load every skill up front.
76
+ - Load skills ONLY after a skill is selected.
77
+ - Do NOT reload a skill whose instructions already appear in this conversation.
78
+ - Do NOT skip this check.
79
+ - FAILURE to perform this check is an error.
80
+ </mandatory_skill_check>
81
+
82
+ <linked_file_handling>
83
+ - When a skill is loaded, ONLY the skill instructions are present.
84
+ - Files linked from the skill are NOT loaded automatically.
85
+ - The model MUST explicitly decide to read a linked file based on task relevance.
86
+ - Do NOT assume the contents of linked files unless they have been explicitly read.
87
+ - Prefer reading the minimum necessary linked file.
88
+ - Avoid reading multiple linked files unless required.
89
+ - Treat linked files as progressive disclosure, not mandatory context.
90
+ </linked_file_handling>
91
+
92
+ <context_notes>
93
+ - The skill list is already filtered for the current mode: "${currentMode}".
94
+ - Mode-specific skills may come from skills-${currentMode}/ with project-level overrides taking precedence over global skills.
95
+ </context_notes>
96
+
97
+ <internal_verification>
98
+ This section is for internal control only.
99
+ Do NOT include this section in user-facing output.
100
+
101
+ After completing the evaluation, internally confirm:
102
+ <skill_check_completed>true|false</skill_check_completed>
103
+ </internal_verification>
104
+ `
105
+ }
@@ -0,0 +1,30 @@
1
+ import os from "os"
2
+ import osName from "../../../../shim/os-name"
3
+
4
+ import { getShell } from "../../../utils/shell"
5
+
6
+ export function getSystemInfoSection(cwd: string): string {
7
+ // Try to get detailed OS name, fall back to basic info if it fails
8
+ let osInfo: string
9
+ try {
10
+ osInfo = osName()
11
+ } catch (error) {
12
+ // Fallback when os-name fails (e.g., PowerShell not available on Windows)
13
+ const platform = os.platform()
14
+ const release = os.release()
15
+ osInfo = `${platform} ${release}`
16
+ }
17
+
18
+ const details = `====
19
+
20
+ SYSTEM INFORMATION
21
+
22
+ Operating System: ${osInfo}
23
+ Default Shell: ${getShell()}
24
+ Home Directory: ${os.homedir().toPosix()}
25
+ Current Workspace Directory: ${cwd.toPosix()}
26
+
27
+ The Current Workspace Directory is the active VS Code project directory, and is therefore the default directory for all tool operations. New terminals will be created in the current workspace directory, however if you change directories in a terminal it will then have a different working directory; changing directories in a terminal does not modify the workspace directory, because you do not have access to change the workspace directory. When the user initially gives you a task, a recursive list of all filepaths in the current workspace directory ('/test/path') will be included in environment_details. This provides an overview of the project's file structure, offering key insights into the project from directory/file names (how developers conceptualize and organize their code) and file extensions (the language used). This can also guide decision-making on which files to explore further. If you need to further explore directories such as outside the current workspace directory, you can use the list_files tool. If you pass 'true' for the recursive parameter, it will list files recursively. Otherwise, it will list files at the top level, which is better suited for generic directories where you don't necessarily need the nested structure, like the Desktop.`
28
+
29
+ return details
30
+ }
@@ -0,0 +1,9 @@
1
+ export function getToolUseGuidelinesSection(): string {
2
+ return `# Tool Use Guidelines
3
+
4
+ 1. Assess what information you already have and what information you need to proceed with the task.
5
+ 2. Choose the most appropriate tool based on the task and the tool descriptions provided. Assess if you need additional information to proceed, and which of the available tools would be most effective for gathering this information. For example using the list_files tool is more effective than running a command like \`ls\` in the terminal. It's critical that you think about each available tool and use the one that best fits the current step in the task.
6
+ 3. If multiple actions are needed, you may use multiple tools in a single message when appropriate, or use tools iteratively across messages. Each tool use should be informed by the results of previous tool uses. Do not assume the outcome of any tool use. Each step must be informed by the previous step's result.
7
+
8
+ By carefully considering the user's response after tool executions, you can react accordingly and make informed decisions about how to proceed with the task. This iterative process helps ensure the overall success and accuracy of your work.`
9
+ }
@@ -0,0 +1,7 @@
1
+ export function getSharedToolUseSection(): string {
2
+ return `====
3
+
4
+ TOOL USE
5
+
6
+ You have access to a set of tools that are executed upon the user's approval. Use the provider-native tool-calling mechanism. Do not include XML markup or examples. You must call at least one tool per assistant response. Prefer calling as many tools as are reasonably needed in a single response to reduce back-and-forth and complete tasks faster.`
7
+ }
@@ -0,0 +1,176 @@
1
+ import * as vscode from "../../../shim/vscode"
2
+
3
+ import { type ModeConfig, type PromptComponent, type CustomModePrompts, type TodoItem } from "../../../types"
4
+
5
+ import { Mode, modes, defaultModeSlug, getModeBySlug, getGroupName, getModeSelection } from "../../shared/modes"
6
+ import { DiffStrategy } from "../../shared/tools"
7
+ import { formatLanguage } from "../../shared/language"
8
+ import { isEmpty } from "../../utils/object"
9
+
10
+ import { McpHub } from "../../services/mcp/McpHub"
11
+ import { CodeIndexManager } from "../../services/code-index/manager"
12
+ import { SkillsManager } from "../../services/skills/SkillsManager"
13
+
14
+ import type { SystemPromptSettings } from "./types"
15
+ import {
16
+ getRulesSection,
17
+ getSystemInfoSection,
18
+ getObjectiveSection,
19
+ getSharedToolUseSection,
20
+ getToolUseGuidelinesSection,
21
+ getCapabilitiesSection,
22
+ getModesSection,
23
+ addCustomInstructions,
24
+ markdownFormattingSection,
25
+ getSkillsSection,
26
+ } from "./sections"
27
+
28
+ // Helper function to get prompt component, filtering out empty objects
29
+ export function getPromptComponent(
30
+ customModePrompts: CustomModePrompts | undefined,
31
+ mode: string,
32
+ ): PromptComponent | undefined {
33
+ const component = customModePrompts?.[mode]
34
+ // Return undefined if component is empty
35
+ if (isEmpty(component)) {
36
+ return undefined
37
+ }
38
+ return component
39
+ }
40
+
41
+ async function generatePrompt(
42
+ context: vscode.ExtensionContext,
43
+ cwd: string,
44
+ supportsComputerUse: boolean,
45
+ mode: Mode,
46
+ mcpHub?: McpHub,
47
+ diffStrategy?: DiffStrategy,
48
+ promptComponent?: PromptComponent,
49
+ customModeConfigs?: ModeConfig[],
50
+ globalCustomInstructions?: string,
51
+ experiments?: Record<string, boolean>,
52
+ language?: string,
53
+ rooIgnoreInstructions?: string,
54
+ settings?: SystemPromptSettings,
55
+ todoList?: TodoItem[],
56
+ modelId?: string,
57
+ skillsManager?: SkillsManager,
58
+ ): Promise<string> {
59
+ if (!context) {
60
+ throw new Error("Extension context is required for generating system prompt")
61
+ }
62
+
63
+ // Get the full mode config to ensure we have the role definition (used for groups, etc.)
64
+ const modeConfig = getModeBySlug(mode, customModeConfigs) || modes.find((m) => m.slug === mode) || modes[0]
65
+ const { roleDefinition, baseInstructions } = getModeSelection(mode, promptComponent, customModeConfigs)
66
+
67
+ // Check if MCP functionality should be included
68
+ const hasMcpGroup = modeConfig.groups.some((groupEntry) => getGroupName(groupEntry) === "mcp")
69
+ const allowedMcpServers = modeConfig.allowedMcpServers
70
+
71
+ // Hoist the allowlist Set once (matches the sibling call sites, e.g. mcp_server.ts) instead
72
+ // of constructing a new Set on every `.filter` iteration.
73
+ const allowSet = allowedMcpServers ? new Set(allowedMcpServers) : undefined
74
+
75
+ let hasMcpServers = false
76
+ if (mcpHub) {
77
+ const servers = allowSet ? mcpHub.getServers().filter((s) => allowSet.has(s.name)) : mcpHub.getServers()
78
+ hasMcpServers = servers.length > 0
79
+ }
80
+ const shouldIncludeMcp = hasMcpGroup && hasMcpServers
81
+
82
+ const codeIndexManager = CodeIndexManager.getInstance(context, cwd)
83
+
84
+ // Tool calling is native-only.
85
+ const effectiveProtocol = "native"
86
+
87
+ const [modesSection, skillsSection] = await Promise.all([
88
+ getModesSection(context),
89
+ getSkillsSection(skillsManager, mode as string),
90
+ ])
91
+
92
+ // Tools catalog is not included in the system prompt.
93
+ const toolsCatalog = ""
94
+
95
+ const basePrompt = `${roleDefinition}
96
+
97
+ ${markdownFormattingSection()}
98
+
99
+ ${getSharedToolUseSection()}${toolsCatalog}
100
+
101
+ ${getToolUseGuidelinesSection()}
102
+
103
+ ${
104
+ // Forward the hub only when the mode actually exposes the MCP group, and pass the per-mode
105
+ // allowlist through so the capabilities section filters servers using the SAME convention as
106
+ // the tool-listing layer (a single source of truth for which servers are visible). This keeps
107
+ // the capability text consistent with the tools exposed in mixed cases (e.g. one allowed +
108
+ // one disallowed server), preventing the section from advertising MCP based on a disallowed
109
+ // server. `shouldIncludeMcp` is still used to short-circuit when no allowed server exists.
110
+ getCapabilitiesSection(cwd, hasMcpGroup ? mcpHub : undefined, allowedMcpServers)
111
+ }
112
+
113
+ ${modesSection}
114
+ ${skillsSection ? `\n${skillsSection}` : ""}
115
+ ${getRulesSection(cwd, settings)}
116
+
117
+ ${getSystemInfoSection(cwd)}
118
+
119
+ ${getObjectiveSection()}
120
+
121
+ ${await addCustomInstructions(baseInstructions, globalCustomInstructions || "", cwd, mode, {
122
+ language: language ?? formatLanguage(vscode.env.language),
123
+ rooIgnoreInstructions,
124
+ settings,
125
+ })}`
126
+
127
+ return basePrompt
128
+ }
129
+
130
+ export const SYSTEM_PROMPT = async (
131
+ context: vscode.ExtensionContext,
132
+ cwd: string,
133
+ supportsComputerUse: boolean,
134
+ mcpHub?: McpHub,
135
+ diffStrategy?: DiffStrategy,
136
+ mode: Mode = defaultModeSlug,
137
+ customModePrompts?: CustomModePrompts,
138
+ customModes?: ModeConfig[],
139
+ globalCustomInstructions?: string,
140
+ experiments?: Record<string, boolean>,
141
+ language?: string,
142
+ rooIgnoreInstructions?: string,
143
+ settings?: SystemPromptSettings,
144
+ todoList?: TodoItem[],
145
+ modelId?: string,
146
+ skillsManager?: SkillsManager,
147
+ ): Promise<string> => {
148
+ if (!context) {
149
+ throw new Error("Extension context is required for generating system prompt")
150
+ }
151
+
152
+ // Check if it's a custom mode
153
+ const promptComponent = getPromptComponent(customModePrompts, mode)
154
+
155
+ // Get full mode config from custom modes or fall back to built-in modes
156
+ const currentMode = getModeBySlug(mode, customModes) || modes.find((m) => m.slug === mode) || modes[0]
157
+
158
+ return generatePrompt(
159
+ context,
160
+ cwd,
161
+ supportsComputerUse,
162
+ currentMode.slug,
163
+ mcpHub,
164
+ diffStrategy,
165
+ promptComponent,
166
+ customModes,
167
+ globalCustomInstructions,
168
+ experiments,
169
+ language,
170
+ rooIgnoreInstructions,
171
+ settings,
172
+ todoList,
173
+ modelId,
174
+ skillsManager,
175
+ )
176
+ }
@@ -0,0 +1,41 @@
1
+ import type OpenAI from "openai"
2
+
3
+ const ACCESS_MCP_RESOURCE_DESCRIPTION = `Request to access a resource provided by a connected MCP server. Resources represent data sources that can be used as context, such as files, API responses, or system information.
4
+
5
+ Parameters:
6
+ - server_name: (required) The name of the MCP server providing the resource
7
+ - uri: (required) The URI identifying the specific resource to access
8
+
9
+ Example: Accessing a weather resource
10
+ { "server_name": "weather-server", "uri": "weather://san-francisco/current" }
11
+
12
+ Example: Accessing a file resource from an MCP server
13
+ { "server_name": "filesystem-server", "uri": "file:///path/to/data.json" }`
14
+
15
+ const SERVER_NAME_PARAMETER_DESCRIPTION = `The name of the MCP server providing the resource`
16
+
17
+ const URI_PARAMETER_DESCRIPTION = `The URI identifying the specific resource to access`
18
+
19
+ export default {
20
+ type: "function",
21
+ function: {
22
+ name: "access_mcp_resource",
23
+ description: ACCESS_MCP_RESOURCE_DESCRIPTION,
24
+ strict: true,
25
+ parameters: {
26
+ type: "object",
27
+ properties: {
28
+ server_name: {
29
+ type: "string",
30
+ description: SERVER_NAME_PARAMETER_DESCRIPTION,
31
+ },
32
+ uri: {
33
+ type: "string",
34
+ description: URI_PARAMETER_DESCRIPTION,
35
+ },
36
+ },
37
+ required: ["server_name", "uri"],
38
+ additionalProperties: false,
39
+ },
40
+ },
41
+ } satisfies OpenAI.Chat.ChatCompletionTool
@@ -0,0 +1,40 @@
1
+ import type OpenAI from "openai"
2
+
3
+ const APPLY_DIFF_DESCRIPTION = `Apply precise, targeted modifications to an existing file using one or more search/replace blocks. This tool is for surgical edits only; the 'SEARCH' block must exactly match the existing content, including whitespace and indentation. To make multiple targeted changes, provide multiple SEARCH/REPLACE blocks in the 'diff' parameter. Use the 'read_file' tool first if you are not confident in the exact content to search for.`
4
+
5
+ const DIFF_PARAMETER_DESCRIPTION = `A string containing one or more search/replace blocks defining the changes. The ':start_line:' is strongly recommended and indicates the starting line number of the original content. You must not add a start line for the replacement content. Each block must follow this format:
6
+ <<<<<<< SEARCH
7
+ :start_line:[line_number]
8
+ -------
9
+ [exact content to find]
10
+ =======
11
+ [new content to replace with]
12
+ >>>>>>> REPLACE
13
+
14
+ CRITICAL:
15
+ - The ':start_line:[line_number]' header is strongly recommended for accurate matching. When provided, it must follow the exact syntax ':start_line:[integer]' (for example: ':start_line:220'). Do not write headers with shorthand forms like ':220' or variations like ':start_line=220'.
16
+ - Copy the exact lines from the source file for a 100% string match including all whitespace, indentation, and newlines.
17
+ - Ensure the separator '-------' is on its own line immediately following ':start_line:[line_number]' with a newline.`
18
+
19
+ export const apply_diff = {
20
+ type: "function",
21
+ function: {
22
+ name: "apply_diff",
23
+ description: APPLY_DIFF_DESCRIPTION,
24
+ parameters: {
25
+ type: "object",
26
+ properties: {
27
+ path: {
28
+ type: "string",
29
+ description: "The path of the file to modify, relative to the current workspace directory.",
30
+ },
31
+ diff: {
32
+ type: "string",
33
+ description: DIFF_PARAMETER_DESCRIPTION,
34
+ },
35
+ },
36
+ required: ["path", "diff"],
37
+ additionalProperties: false,
38
+ },
39
+ },
40
+ } satisfies OpenAI.Chat.ChatCompletionTool
@@ -0,0 +1,61 @@
1
+ import type OpenAI from "openai"
2
+
3
+ const apply_patch_DESCRIPTION = `Apply patches to files using a stripped-down, file-oriented diff format. This tool supports creating new files, deleting files, and updating existing files with precise changes.
4
+
5
+ The patch format uses a simple, human-readable structure:
6
+
7
+ *** Begin Patch
8
+ [ one or more file sections ]
9
+ *** End Patch
10
+
11
+ Each file section starts with one of three headers:
12
+ - *** Add File: <path> - Create a new file. Every following line is a + line (the initial contents).
13
+ - *** Delete File: <path> - Remove an existing file. Nothing follows.
14
+ - *** Update File: <path> - Patch an existing file in place.
15
+
16
+ For Update File operations:
17
+ - May be immediately followed by *** Move to: <new path> if you want to rename the file.
18
+ - Then one or more "hunks", each introduced by @@ (optionally followed by context like a class or function name).
19
+ - Within a hunk each line starts with:
20
+ - ' ' (space) for context lines (unchanged)
21
+ - '-' for lines to remove
22
+ - '+' for lines to add
23
+
24
+ Context guidelines:
25
+ - Show 3 lines of code above and below each change.
26
+ - Use @@ with a class/function name if 3 lines of context is insufficient to uniquely identify the location.
27
+ - Multiple @@ statements can be used for deeply nested code.
28
+
29
+ Example patch:
30
+ *** Begin Patch
31
+ *** Add File: hello.txt
32
+ +Hello world
33
+ *** Update File: src/app.py
34
+ *** Move to: src/main.py
35
+ @@ def greet():
36
+ -print("Hi")
37
+ +print("Hello, world!")
38
+ *** Delete File: obsolete.txt
39
+ *** End Patch`
40
+
41
+ const apply_patch = {
42
+ type: "function",
43
+ function: {
44
+ name: "apply_patch",
45
+ description: apply_patch_DESCRIPTION,
46
+ parameters: {
47
+ type: "object",
48
+ properties: {
49
+ patch: {
50
+ type: "string",
51
+ description:
52
+ "The complete patch text in the apply_patch format, starting with '*** Begin Patch' and ending with '*** End Patch'.",
53
+ },
54
+ },
55
+ required: ["patch"],
56
+ additionalProperties: false,
57
+ },
58
+ },
59
+ } satisfies OpenAI.Chat.ChatCompletionTool
60
+
61
+ export default apply_patch
@@ -0,0 +1,62 @@
1
+ import type OpenAI from "openai"
2
+
3
+ const ASK_FOLLOWUP_QUESTION_DESCRIPTION = `Ask the user a question to gather additional information needed to complete the task. Use when you need clarification or more details to proceed effectively.
4
+
5
+ Parameters:
6
+ - question: (required) A clear, specific question addressing the information needed
7
+ - follow_up: (required) A list of 2-4 suggested answers. Suggestions must be complete, actionable answers without placeholders. Optionally include mode to switch modes (code/architect/etc.)
8
+
9
+ Example: Asking for file path
10
+ { "question": "What is the path to the frontend-config.json file?", "follow_up": [{ "text": "./src/frontend-config.json", "mode": null }, { "text": "./config/frontend-config.json", "mode": null }, { "text": "./frontend-config.json", "mode": null }] }
11
+
12
+ Example: Asking with mode switch
13
+ { "question": "Would you like me to implement this feature?", "follow_up": [{ "text": "Yes, implement it now", "mode": "code" }, { "text": "No, just plan it out", "mode": "architect" }] }`
14
+
15
+ const QUESTION_PARAMETER_DESCRIPTION = `Clear, specific question that captures the missing information you need`
16
+
17
+ const FOLLOW_UP_PARAMETER_DESCRIPTION = `Required list of 2-4 suggested responses; each suggestion must be a complete, actionable answer and may include a mode switch`
18
+
19
+ const FOLLOW_UP_TEXT_DESCRIPTION = `Suggested answer the user can pick`
20
+
21
+ const FOLLOW_UP_MODE_DESCRIPTION = `Optional mode slug to switch to if this suggestion is chosen (e.g., code, architect)`
22
+
23
+ export default {
24
+ type: "function",
25
+ function: {
26
+ name: "ask_followup_question",
27
+ description: ASK_FOLLOWUP_QUESTION_DESCRIPTION,
28
+ strict: true,
29
+ parameters: {
30
+ type: "object",
31
+ properties: {
32
+ question: {
33
+ type: "string",
34
+ description: QUESTION_PARAMETER_DESCRIPTION,
35
+ },
36
+ follow_up: {
37
+ type: "array",
38
+ description: FOLLOW_UP_PARAMETER_DESCRIPTION,
39
+ items: {
40
+ type: "object",
41
+ properties: {
42
+ text: {
43
+ type: "string",
44
+ description: FOLLOW_UP_TEXT_DESCRIPTION,
45
+ },
46
+ mode: {
47
+ type: ["string", "null"],
48
+ description: FOLLOW_UP_MODE_DESCRIPTION,
49
+ },
50
+ },
51
+ required: ["text", "mode"],
52
+ additionalProperties: false,
53
+ },
54
+ minItems: 1,
55
+ maxItems: 4,
56
+ },
57
+ },
58
+ required: ["question", "follow_up"],
59
+ additionalProperties: false,
60
+ },
61
+ },
62
+ } satisfies OpenAI.Chat.ChatCompletionTool