2025-04-14 15:20:54 +01:00
require ( ' helpers ' ) . edit_cf ( ' pa ' , ' /lua/plugins/codecompanion.lua ' )
2025-04-14 11:38:42 +01:00
2025-04-29 17:22:28 +01:00
vim.cmd [[cab cc CodeCompanion]]
2025-04-13 22:53:08 +01:00
return {
' olimorris/codecompanion.nvim ' ,
2025-04-15 20:48:35 +01:00
opts = function ( _ , opts )
opts.adapters = {
2025-04-17 08:53:20 +01:00
gpt = function ( )
2025-04-14 15:20:54 +01:00
return require ( ' codecompanion.adapters ' ) . extend ( ' copilot ' , {
schema = {
model = {
2025-05-05 07:25:00 +01:00
default = ' gpt-4.1 ' ,
2025-04-14 15:20:54 +01:00
} ,
2025-04-17 08:53:20 +01:00
max_tokens = {
default = 1000000 ,
} ,
} ,
} )
end ,
flash = function ( )
return require ( ' codecompanion.adapters ' ) . extend ( ' copilot ' , {
schema = {
model = {
2025-05-12 09:04:40 +01:00
default = ' gemini-2.0-flash-001 ' ,
2025-04-17 08:53:20 +01:00
} ,
max_tokens = {
default = 1000000 ,
} ,
} ,
} )
end ,
gemini = function ( )
return require ( ' codecompanion.adapters ' ) . extend ( ' copilot ' , {
schema = {
model = {
default = ' gemini-2.5-pro ' ,
} ,
max_tokens = {
default = 1000000 ,
} ,
} ,
} )
end ,
sonnet = function ( )
return require ( ' codecompanion.adapters ' ) . extend ( ' copilot ' , {
schema = {
model = {
default = ' claude-3.7-sonnet ' ,
} ,
max_tokens = {
default = 1000000 ,
} ,
2025-04-14 15:20:54 +01:00
} ,
} )
end ,
2025-04-15 20:48:35 +01:00
}
opts.display = {
2025-04-14 15:20:54 +01:00
chat = {
show_settings = true ,
2025-05-08 07:59:46 +01:00
start_in_insert_mode = false ,
2025-04-14 15:20:54 +01:00
} ,
2025-04-15 20:48:35 +01:00
}
opts.strategies = {
chat = {
2025-04-29 17:22:28 +01:00
adapter = ' gpt ' ,
2025-04-15 20:48:35 +01:00
slash_commands = {
2025-06-20 22:16:56 +01:00
-- codebase = require('vectorcode.integrations').codecompanion.chat.make_slash_command(),
2025-04-15 20:48:35 +01:00
} ,
tools = {
2025-06-20 22:16:56 +01:00
-- vectorcode = {
-- description = 'Run VectorCode to retrieve the project context.',
-- callback = require('vectorcode.integrations').codecompanion.chat.make_tool(),
-- },
2025-05-05 07:25:00 +01:00
[ ' cmd_runner ' ] = {
opts = {
requires_approval = false ,
} ,
} ,
} ,
roles = {
---@type string|fun(adapter: CodeCompanion.Adapter): string
llm = function ( adapter )
return ' CodeCompanion ( ' .. adapter.formatted_name .. ' : ' .. adapter.parameters . model .. ' ) '
end ,
} ,
keymaps = {
send = {
modes = { n = ' <C-s> ' , i = ' <C-s> ' } ,
} ,
close = {
modes = { n = ' <C-c> ' , i = ' <C-c> ' } ,
} ,
2025-04-15 20:48:35 +01:00
} ,
} ,
2025-04-17 08:53:20 +01:00
inline = {
adapter = ' flash ' ,
} ,
2025-04-15 20:48:35 +01:00
}
2025-05-05 07:25:00 +01:00
opts.extensions = {
mcphub = {
callback = ' mcphub.extensions.codecompanion ' ,
opts = {
show_result_in_chat = true ,
make_vars = true ,
make_slash_commands = true ,
} ,
} ,
}
opts.system_prompt = function ( opts )
local language = opts.language or ' English '
return string.format (
[ [ You are an AI programming assistant named " CodeCompanion " . You are currently plugged into the Neovim text editor on a user ' s machine.
Your core tasks include :
- Answering general programming questions .
- Explaining how the code in a Neovim buffer works .
- Reviewing the selected code from a Neovim buffer .
- Generating unit tests for the selected code .
- Proposing fixes for problems in the selected code .
- Scaffolding code for a new workspace .
- Finding relevant code to the user ' s query.
- Proposing fixes for test failures .
- Answering questions about Neovim .
- Running tools .
You must :
- Follow the user ' s requirements carefully and to the letter.
- Keep your answers short and impersonal , especially if the user ' s context is outside your core tasks.
- Minimize additional prose unless clarification is needed .
- Use Markdown formatting in your answers .
- Include the programming language name at the start of each Markdown code block .
- Avoid including line numbers in code blocks .
- Avoid wrapping the whole response in triple backticks .
- Only return code that ' s directly relevant to the task at hand. You may omit code that isn’ t necessary for the solution.
- Avoid using H1 , H2 or H3 headers in your responses as these are reserved for the user .
- Use actual line breaks in your responses ; only use " \n " when you want a literal backslash followed by ' n ' .
- All non - code text responses must be written in the % s language indicated .
- Multiple , different tools can be called as part of the same response .
2025-05-12 09:04:40 +01:00
- Use full path names when using tools to read and modify files .
2025-05-05 07:25:00 +01:00
When given a task :
1. Think step - by - step and , unless the user requests otherwise or the task is very simple , describe your plan in detailed pseudocode .
2. Output the final code in a single code block , ensuring that only relevant code is included .
3. End your response with a short suggestion for the next user turn that directly supports continuing the conversation .
4. Provide exactly one complete reply per conversation turn .
5. If necessary , execute multiple tools in a single turn . ] ] ,
language
)
end
opts.prompt_library = {
[ ' Code Expert ' ] = {
strategy = ' chat ' ,
description = ' Get some special adcvice from an LLM. ' ,
opts = {
mapping = ' <Leader>ce ' ,
modes = { ' v ' } ,
short_name = ' expert ' ,
auto_submit = true ,
stop_context_insertion = true ,
user_prompt = true ,
} ,
prompts = {
{
role = ' system ' ,
content = function ( context )
return ' I want you to act as a senior '
.. context.filetype
.. ' developer I will ask you specific questions and I want you to return concise explanations and codeblock examples. '
end ,
} ,
{
role = ' user ' ,
content = function ( context )
local text = require ( ' codecompanion.helpers.actions ' ) . get_code ( context.start_line , context.end_line )
return ' I have the following code: \n \n ``` ' .. context.filetype .. ' \n ' .. text .. ' \n ``` \n \n '
end ,
opts = {
contains_code = true ,
} ,
} ,
} ,
} ,
[ ' Games Master ' ] = {
strategy = ' chat ' ,
description = ' A personal Games Master Assistant. ' ,
opts = {
user_prompt = false ,
} ,
prompts = {
{
role = ' system ' ,
2025-06-20 22:16:56 +01:00
content = [ [
2025-05-05 07:25:00 +01:00
You are a personal Games Master Assistant . You are currently plugged in to the Neovim text editor on a user ' s machine.
Your core tasks include :
- Crafting engaging role playing sessions
- Building immersive and authentic worlds
- Creating compelling characters for the players to interact with and drive the story
- Reviewing session summaries and building on them
- Providing advice on how to bring sessions to life
- Create exciting encounters to challenge the players
- Encounters can be combat , social , or exploration based
- There should always be a story reason for the encounter
- Combine player character backgrounds and motivations into the world
- Build tension and drama into the game
- Ensure each session provides opportunities for the players to engage with and drive the story
You must :
- Follow the user ' s requirements carefully and to the letter.
- Keep answers focused on the task at hand .
- Provide original ideas and suggestions .
- Use Markdown formatting in your answers .
- Use actual line breaks instead of ' \n ' in your response to begin new lines .
- Use ' \n ' only when you want a literal backslash followed by a character ' n ' .
- All responses must be written in English .
- Multiple , different tools can be called as part of the same response .
- Help sessions be fast paced and fun .
- Ensure there are multiple soltuions to each problem .
- Avoid railroading the players .
When given a task :
1. Consider the existing world and characters . Use tools to gather information that may be relevant .
2. Provide exactly one complete reply per conversation turn .
3. If necessary , execute multiple tools in a single turn .
2025-06-20 22:16:56 +01:00
] ] ,
2025-05-05 07:25:00 +01:00
} ,
{
role = ' user ' ,
2025-06-20 22:16:56 +01:00
content = ' ' ,
2025-05-05 07:25:00 +01:00
} ,
} ,
} ,
2025-05-12 09:04:40 +01:00
[ ' PHPStan Fixer ' ] = {
strategy = ' workflow ' ,
description = ' Use a workflow to fix PHPStan errors until there are none left. ' ,
opts = {
short_name = ' phpstan ' ,
} ,
prompts = {
{
{
name = ' Run PHPStan ' ,
role = ' user ' ,
opts = { auto_submit = false } ,
content = function ( )
-- Enable turbo mode!!!
vim.g . codecompanion_auto_tool_mode = true
return [ [ PHPStan is a static analysis tool for PHP . It is currently reporting errors in the code . Your task is to fix these errors and run PHPStan again until there are no errors left .
First of all use the @ cmd_runner tool to run the ` composer type - check ` command . This will run PHPStan and output type errors in the code . ] ]
end ,
} ,
} ,
{
{
name = ' Fetch files ' ,
role = ' user ' ,
opts = { auto_submit = false } ,
content = function ( )
-- Enable turbo mode!!!
vim.g . codecompanion_auto_tool_mode = true
return ' PHPStan has reported errors. Look at the output and see where the files are reported. Use the @mcp tool to read all the offending files so you can implement the fixes. '
end ,
} ,
} ,
{
{
name = ' Fix errors and run ' ,
role = ' user ' ,
opts = { auto_submit = false } ,
content = function ( )
-- Enable turbo mode!!!
vim.g . codecompanion_auto_tool_mode = true
return [ [ ### Instructions
Now you have the errors and the appropriate context you can fix the errors .
### Steps to Follow
You are required to analyse the PHPStan errors and write code to fix them .
Reason through the errors and write out the possible causes and fixes for each .
1. Then use the @ mcp tool to update the files with the fixes . When editing files use the full path name including the project name / Users / chris / Code / Sites / hylark /
2. After editing the files use the @ cmd_runner tool again to run the ` composer type - check ` command to see if any errors remain .
We ' ll repeat this cycle until there are no errors. Ensure no deviations from these steps.
### Tips for fixing PHPStan errors
- Do not ignore the errors
- Use Webmozart Assert library to narrow types
- Most errors are due to missing docblocks or calling methods / parameters on types that PHPStan cannot infer
- Use fully qualified namespaces for classes in doc blocks
- The code is working so fixes should not change the behaviour of the code
- There are some custom types in this project that help define types
- closure < T > creates T | Closure ( ) : T , you can add a second argument to specify the depth so closure < T , 2 > creates T | Closure ( ) : T | Closure ( ) : ( Closure ( ) : T ) . This is useful because GraphQL queries can return closures .
- promise < T > creates T | SyncPromise < T > , as with closure , you can add a second argument for depth . You can also add a third argument if T is an array to allow adding promises to each value , so promise < array { a : int } , 1 , 1 > will create array { a : int } | SyncPromise < array { a : int } >| array { a : SyncPromise < int > } | SyncPromise < array { a : SyncPromise < int > } > . This is useful because GraphQL queries can return promises and arrays of promises .
- GraphQL schema types ( these should only be used in the Query classes )
- GArgs < T > will look at the GraphQL schema and create an array type for the arguments of a field on one of the root types ( Query or Mutation )
- GArgs < TType , TField > will create a type for the arguments of a field on a type
- GType < T > will create an type for a specific GraphQL type , input , interface , or enum
- GVal < T > will create a type for the return value of a field on one of the root types ( Query or Mutation )
- GVal < TType , TField > will create a type for the return value of a field on a type
- pick < T , TKeys > will create an array from T with only the keys in TKeys ( e.g . pick < array { a : int , b : int , c : int } , ' a ' | ' b ' > will create array { a : int , b : int } )
- except < T , TKeys > works like pick only it excludes the keys in TKeys ( e.g . except < array { a : int , b : int , c : int } , ' a ' | ' b ' > will create array { c : int } )
- union < T , U > creates a union array of T and U ( e.g . union < array { a : int } , array { b : int } > will create array { a : int , b : int } ) ] ]
end ,
} ,
} ,
{
{
name = ' Repeat On Failure ' ,
role = ' user ' ,
opts = { auto_submit = false } ,
-- Scope this prompt to the cmd_runner tool
condition = function ( )
return _G.codecompanion_current_tool == ' cmd_runner '
end ,
-- Repeat until the tests pass, as indicated by the testing flag
-- which the cmd_runner tool sets on the chat buffer
repeat_until = function ( chat )
-- Check if the last message in the chat buffer contains "[ERROR] found"
local messages = chat.messages
local last_message = messages [ # messages ]
if last_message and last_message.role == ' assistant ' then
local content = last_message.content
return not content : find ' [ERROR] found '
end
return true
end ,
content = ' PHPStan is still reporting errors. Edit the code to fix the errors and run PHPStan again. ' ,
} ,
} ,
} ,
} ,
2025-05-05 07:25:00 +01:00
}
2025-04-15 20:48:35 +01:00
end ,
2025-04-13 22:53:08 +01:00
dependencies = {
' nvim-lua/plenary.nvim ' ,
' nvim-treesitter/nvim-treesitter ' ,
2025-06-20 22:16:56 +01:00
-- 'Davidyz/VectorCode',
2025-05-05 07:25:00 +01:00
' ravitemer/mcphub.nvim ' ,
2025-04-13 22:53:08 +01:00
} ,
}