@iaforged/context-code 1.0.59 → 1.0.62

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 (74) hide show
  1. package/LICENSE.md +1 -1
  2. package/dist/src/bridge/bridgeMain.js +40 -40
  3. package/dist/src/cli/print.js +12 -12
  4. package/dist/src/commands/commit-push-pr.js +55 -55
  5. package/dist/src/commands/createMovedToPluginCommand.js +9 -9
  6. package/dist/src/commands/init-verifiers.js +241 -241
  7. package/dist/src/commands/init.js +216 -216
  8. package/dist/src/commands/install.js +2 -2
  9. package/dist/src/commands/review.js +22 -22
  10. package/dist/src/commands/terminalSetup/terminalSetup.js +24 -24
  11. package/dist/src/components/agents/generateAgent.js +92 -92
  12. package/dist/src/components/grove/Grove.js +10 -10
  13. package/dist/src/components/permissions/AskUserQuestionPermissionRequest/AskUserQuestionPermissionRequest.js +8 -8
  14. package/dist/src/constants/github-app.js +134 -134
  15. package/dist/src/constants/prompts.js +123 -123
  16. package/dist/src/coordinator/coordinatorMode.js +252 -252
  17. package/dist/src/ink/reconciler.js +7 -7
  18. package/dist/src/memdir/findRelevantMemories.js +6 -6
  19. package/dist/src/services/MagicDocs/prompts.js +56 -56
  20. package/dist/src/services/PromptSuggestion/promptSuggestion.js +29 -29
  21. package/dist/src/services/SessionMemory/prompts.js +66 -66
  22. package/dist/src/services/toolUseSummary/toolUseSummaryGenerator.js +9 -9
  23. package/dist/src/skills/bundled/batch.js +78 -78
  24. package/dist/src/skills/bundled/claudeApi.js +34 -34
  25. package/dist/src/skills/bundled/claudeInChrome.js +4 -4
  26. package/dist/src/skills/bundled/debug.js +36 -36
  27. package/dist/src/skills/bundled/scheduleRemoteAgents.js +151 -151
  28. package/dist/src/skills/bundled/skillify.js +134 -134
  29. package/dist/src/skills/bundled/stuck.js +53 -53
  30. package/dist/src/skills/bundled/updateConfig.js +418 -418
  31. package/dist/src/tasks/RemoteAgentTask/RemoteAgentTask.js +26 -26
  32. package/dist/src/tools/AgentTool/AgentTool.js +7 -7
  33. package/dist/src/tools/AgentTool/built-in/claudeCodeGuideAgent.js +67 -67
  34. package/dist/src/tools/AgentTool/built-in/exploreAgent.js +32 -32
  35. package/dist/src/tools/AgentTool/built-in/generalPurposeAgent.js +13 -13
  36. package/dist/src/tools/AgentTool/built-in/planAgent.js +49 -49
  37. package/dist/src/tools/AgentTool/built-in/statuslineSetup.js +129 -129
  38. package/dist/src/tools/AgentTool/built-in/verificationAgent.js +119 -119
  39. package/dist/src/tools/AgentTool/prompt.js +131 -131
  40. package/dist/src/tools/AgentTool/runAgent.js +9 -9
  41. package/dist/src/tools/BashTool/BashTool.js +10 -10
  42. package/dist/src/tools/BashTool/prompt.js +94 -94
  43. package/dist/src/tools/ConfigTool/prompt.js +29 -29
  44. package/dist/src/tools/EnterWorktreeTool/prompt.js +27 -27
  45. package/dist/src/tools/FileReadTool/prompt.js +12 -12
  46. package/dist/src/tools/PowerShellTool/prompt.js +82 -82
  47. package/dist/src/tools/RemoteTriggerTool/prompt.js +9 -9
  48. package/dist/src/tools/ScheduleCronTool/prompt.js +37 -37
  49. package/dist/src/tools/TeamCreateTool/prompt.js +110 -110
  50. package/dist/src/tools/TeamDeleteTool/prompt.js +13 -13
  51. package/dist/src/utils/advisor.js +15 -15
  52. package/dist/src/utils/api.js +2 -2
  53. package/dist/src/utils/autoUpdater.js +18 -18
  54. package/dist/src/utils/bash/ShellSnapshot.js +86 -86
  55. package/dist/src/utils/bash/commands.js +61 -61
  56. package/dist/src/utils/claudeInChrome/prompt.js +53 -53
  57. package/dist/src/utils/claudeInChrome/setup.js +8 -8
  58. package/dist/src/utils/databaseMcp/server/queries.js +632 -632
  59. package/dist/src/utils/deepLink/registerProtocol.js +35 -35
  60. package/dist/src/utils/deepLink/terminalLauncher.js +12 -12
  61. package/dist/src/utils/hooks/execAgentHook.js +7 -7
  62. package/dist/src/utils/hooks/execPromptHook.js +4 -4
  63. package/dist/src/utils/hooks/skillImprovement.js +36 -36
  64. package/dist/src/utils/json.js +1 -1
  65. package/dist/src/utils/mcp/dateTimeParser.js +9 -9
  66. package/dist/src/utils/messages.js +191 -191
  67. package/dist/src/utils/powershell/parser.js +253 -253
  68. package/dist/src/utils/sessionTitle.js +12 -12
  69. package/dist/src/utils/sideQuestion.js +17 -17
  70. package/dist/src/utils/swarm/backends/registry.js +9 -9
  71. package/dist/src/utils/telemetry/instrumentation.js +9 -9
  72. package/dist/src/utils/teleport.js +15 -15
  73. package/dist/src/utils/undercover.js +28 -28
  74. package/package.json +170 -170
@@ -1,113 +1,113 @@
1
1
  export function getPrompt() {
2
- return `
3
- # TeamCreate
4
-
5
- ## When to Use
6
-
7
- Use this tool proactively whenever:
8
- - The user explicitly asks to use a team, swarm, or group of agents
9
- - The user mentions wanting agents to work together, coordinate, or collaborate
10
- - A task is complex enough that it would benefit from parallel work by multiple agents (e.g., building a full-stack feature with frontend and backend work, refactoring a codebase while keeping tests passing, implementing a multi-step project with research, planning, and coding phases)
11
-
12
- When in doubt about whether a task warrants a team, prefer spawning a team.
13
-
14
- ## Choosing Agent Types for Teammates
15
-
16
- When spawning teammates via the Agent tool, choose the \`subagent_type\` based on what tools the agent needs for its task. Each agent type has a different set of available tools — match the agent to the work:
17
-
18
- - **Read-only agents** (e.g., Explore, Plan) cannot edit or write files. Only assign them research, search, or planning tasks. Never assign them implementation work.
19
- - **Full-capability agents** (e.g., general-purpose) have access to all tools including file editing, writing, and bash. Use these for tasks that require making changes.
20
- - **Custom agents** defined in \`.claude/agents/\` may have their own tool restrictions. Check their descriptions to understand what they can and cannot do.
21
-
22
- Always review the agent type descriptions and their available tools listed in the Agent tool prompt before selecting a \`subagent_type\` for a teammate.
23
-
24
- Create a new team to coordinate multiple agents working on a project. Teams have a 1:1 correspondence with task lists (Team = TaskList).
25
-
26
- \`\`\`
27
- {
28
- "team_name": "my-project",
29
- "description": "Working on feature X"
30
- }
31
- \`\`\`
32
-
33
- This creates:
34
- - A team file at \`~/.claude/teams/{team-name}/config.json\`
35
- - A corresponding task list directory at \`~/.claude/tasks/{team-name}/\`
36
-
37
- ## Team Workflow
38
-
39
- 1. **Create a team** with TeamCreate - this creates both the team and its task list
40
- 2. **Create tasks** using the Task tools (TaskCreate, TaskList, etc.) - they automatically use the team's task list
41
- 3. **Spawn teammates** using the Agent tool with \`team_name\` and \`name\` parameters to create teammates that join the team
42
- 4. **Assign tasks** using TaskUpdate with \`owner\` to give tasks to idle teammates
43
- 5. **Teammates work on assigned tasks** and mark them completed via TaskUpdate
44
- 6. **Teammates go idle between turns** - after each turn, teammates automatically go idle and send a notification. IMPORTANT: Be patient with idle teammates! Don't comment on their idleness until it actually impacts your work.
45
- 7. **Shutdown your team** - when the task is completed, gracefully shut down your teammates via SendMessage with \`message: {type: "shutdown_request"}\`.
46
-
47
- ## Task Ownership
48
-
49
- Tasks are assigned using TaskUpdate with the \`owner\` parameter. Any agent can set or change task ownership via TaskUpdate.
50
-
51
- ## Automatic Message Delivery
52
-
53
- **IMPORTANT**: Messages from teammates are automatically delivered to you. You do NOT need to manually check your inbox.
54
-
55
- When you spawn teammates:
56
- - They will send you messages when they complete tasks or need help
57
- - These messages appear automatically as new conversation turns (like user messages)
58
- - If you're busy (mid-turn), messages are queued and delivered when your turn ends
59
- - The UI shows a brief notification with the sender's name when messages are waiting
60
-
61
- Messages will be delivered automatically.
62
-
63
- When reporting on teammate messages, you do NOT need to quote the original message—it's already rendered to the user.
64
-
65
- ## Teammate Idle State
66
-
67
- Teammates go idle after every turn—this is completely normal and expected. A teammate going idle immediately after sending you a message does NOT mean they are done or unavailable. Idle simply means they are waiting for input.
68
-
69
- - **Idle teammates can receive messages.** Sending a message to an idle teammate wakes them up and they will process it normally.
70
- - **Idle notifications are automatic.** The system sends an idle notification whenever a teammate's turn ends. You do not need to react to idle notifications unless you want to assign new work or send a follow-up message.
71
- - **Do not treat idle as an error.** A teammate sending a message and then going idle is the normal flow—they sent their message and are now waiting for a response.
72
- - **Peer DM visibility.** When a teammate sends a DM to another teammate, a brief summary is included in their idle notification. This gives you visibility into peer collaboration without the full message content. You do not need to respond to these summaries — they are informational.
73
-
74
- ## Discovering Team Members
75
-
76
- Teammates can read the team config file to discover other team members:
77
- - **Team config location**: \`~/.claude/teams/{team-name}/config.json\`
78
-
79
- The config file contains a \`members\` array with each teammate's:
80
- - \`name\`: Human-readable name (**always use this** for messaging and task assignment)
81
- - \`agentId\`: Unique identifier (for reference only - do not use for communication)
82
- - \`agentType\`: Role/type of the agent
83
-
84
- **IMPORTANT**: Always refer to teammates by their NAME (e.g., "team-lead", "researcher", "tester"). Names are used for:
85
- - \`to\` when sending messages
86
- - Identifying task owners
87
-
88
- Example of reading team config:
89
- \`\`\`
90
- Use the Read tool to read ~/.claude/teams/{team-name}/config.json
91
- \`\`\`
92
-
93
- ## Task List Coordination
94
-
95
- Teams share a task list that all teammates can access at \`~/.claude/tasks/{team-name}/\`.
96
-
97
- Teammates should:
98
- 1. Check TaskList periodically, **especially after completing each task**, to find available work or see newly unblocked tasks
99
- 2. Claim unassigned, unblocked tasks with TaskUpdate (set \`owner\` to your name). **Prefer tasks in ID order** (lowest ID first) when multiple tasks are available, as earlier tasks often set up context for later ones
100
- 3. Create new tasks with \`TaskCreate\` when identifying additional work
101
- 4. Mark tasks as completed with \`TaskUpdate\` when done, then check TaskList for next work
102
- 5. Coordinate with other teammates by reading the task list status
103
- 6. If all available tasks are blocked, notify the team lead or help resolve blocking tasks
104
-
105
- **IMPORTANT notes for communication with your team**:
106
- - Do not use terminal tools to view your team's activity; always send a message to your teammates (and remember, refer to them by name).
107
- - Your team cannot hear you if you do not use the SendMessage tool. Always send a message to your teammates if you are responding to them.
108
- - Do NOT send structured JSON status messages like \`{"type":"idle",...}\` or \`{"type":"task_completed",...}\`. Just communicate in plain text when you need to message teammates.
109
- - Use TaskUpdate to mark tasks completed.
110
- - If you are an agent in the team, the system will automatically send idle notifications to the team lead when you stop.
111
-
2
+ return `
3
+ # TeamCreate
4
+
5
+ ## When to Use
6
+
7
+ Use this tool proactively whenever:
8
+ - The user explicitly asks to use a team, swarm, or group of agents
9
+ - The user mentions wanting agents to work together, coordinate, or collaborate
10
+ - A task is complex enough that it would benefit from parallel work by multiple agents (e.g., building a full-stack feature with frontend and backend work, refactoring a codebase while keeping tests passing, implementing a multi-step project with research, planning, and coding phases)
11
+
12
+ When in doubt about whether a task warrants a team, prefer spawning a team.
13
+
14
+ ## Choosing Agent Types for Teammates
15
+
16
+ When spawning teammates via the Agent tool, choose the \`subagent_type\` based on what tools the agent needs for its task. Each agent type has a different set of available tools — match the agent to the work:
17
+
18
+ - **Read-only agents** (e.g., Explore, Plan) cannot edit or write files. Only assign them research, search, or planning tasks. Never assign them implementation work.
19
+ - **Full-capability agents** (e.g., general-purpose) have access to all tools including file editing, writing, and bash. Use these for tasks that require making changes.
20
+ - **Custom agents** defined in \`.claude/agents/\` may have their own tool restrictions. Check their descriptions to understand what they can and cannot do.
21
+
22
+ Always review the agent type descriptions and their available tools listed in the Agent tool prompt before selecting a \`subagent_type\` for a teammate.
23
+
24
+ Create a new team to coordinate multiple agents working on a project. Teams have a 1:1 correspondence with task lists (Team = TaskList).
25
+
26
+ \`\`\`
27
+ {
28
+ "team_name": "my-project",
29
+ "description": "Working on feature X"
30
+ }
31
+ \`\`\`
32
+
33
+ This creates:
34
+ - A team file at \`~/.claude/teams/{team-name}/config.json\`
35
+ - A corresponding task list directory at \`~/.claude/tasks/{team-name}/\`
36
+
37
+ ## Team Workflow
38
+
39
+ 1. **Create a team** with TeamCreate - this creates both the team and its task list
40
+ 2. **Create tasks** using the Task tools (TaskCreate, TaskList, etc.) - they automatically use the team's task list
41
+ 3. **Spawn teammates** using the Agent tool with \`team_name\` and \`name\` parameters to create teammates that join the team
42
+ 4. **Assign tasks** using TaskUpdate with \`owner\` to give tasks to idle teammates
43
+ 5. **Teammates work on assigned tasks** and mark them completed via TaskUpdate
44
+ 6. **Teammates go idle between turns** - after each turn, teammates automatically go idle and send a notification. IMPORTANT: Be patient with idle teammates! Don't comment on their idleness until it actually impacts your work.
45
+ 7. **Shutdown your team** - when the task is completed, gracefully shut down your teammates via SendMessage with \`message: {type: "shutdown_request"}\`.
46
+
47
+ ## Task Ownership
48
+
49
+ Tasks are assigned using TaskUpdate with the \`owner\` parameter. Any agent can set or change task ownership via TaskUpdate.
50
+
51
+ ## Automatic Message Delivery
52
+
53
+ **IMPORTANT**: Messages from teammates are automatically delivered to you. You do NOT need to manually check your inbox.
54
+
55
+ When you spawn teammates:
56
+ - They will send you messages when they complete tasks or need help
57
+ - These messages appear automatically as new conversation turns (like user messages)
58
+ - If you're busy (mid-turn), messages are queued and delivered when your turn ends
59
+ - The UI shows a brief notification with the sender's name when messages are waiting
60
+
61
+ Messages will be delivered automatically.
62
+
63
+ When reporting on teammate messages, you do NOT need to quote the original message—it's already rendered to the user.
64
+
65
+ ## Teammate Idle State
66
+
67
+ Teammates go idle after every turn—this is completely normal and expected. A teammate going idle immediately after sending you a message does NOT mean they are done or unavailable. Idle simply means they are waiting for input.
68
+
69
+ - **Idle teammates can receive messages.** Sending a message to an idle teammate wakes them up and they will process it normally.
70
+ - **Idle notifications are automatic.** The system sends an idle notification whenever a teammate's turn ends. You do not need to react to idle notifications unless you want to assign new work or send a follow-up message.
71
+ - **Do not treat idle as an error.** A teammate sending a message and then going idle is the normal flow—they sent their message and are now waiting for a response.
72
+ - **Peer DM visibility.** When a teammate sends a DM to another teammate, a brief summary is included in their idle notification. This gives you visibility into peer collaboration without the full message content. You do not need to respond to these summaries — they are informational.
73
+
74
+ ## Discovering Team Members
75
+
76
+ Teammates can read the team config file to discover other team members:
77
+ - **Team config location**: \`~/.claude/teams/{team-name}/config.json\`
78
+
79
+ The config file contains a \`members\` array with each teammate's:
80
+ - \`name\`: Human-readable name (**always use this** for messaging and task assignment)
81
+ - \`agentId\`: Unique identifier (for reference only - do not use for communication)
82
+ - \`agentType\`: Role/type of the agent
83
+
84
+ **IMPORTANT**: Always refer to teammates by their NAME (e.g., "team-lead", "researcher", "tester"). Names are used for:
85
+ - \`to\` when sending messages
86
+ - Identifying task owners
87
+
88
+ Example of reading team config:
89
+ \`\`\`
90
+ Use the Read tool to read ~/.claude/teams/{team-name}/config.json
91
+ \`\`\`
92
+
93
+ ## Task List Coordination
94
+
95
+ Teams share a task list that all teammates can access at \`~/.claude/tasks/{team-name}/\`.
96
+
97
+ Teammates should:
98
+ 1. Check TaskList periodically, **especially after completing each task**, to find available work or see newly unblocked tasks
99
+ 2. Claim unassigned, unblocked tasks with TaskUpdate (set \`owner\` to your name). **Prefer tasks in ID order** (lowest ID first) when multiple tasks are available, as earlier tasks often set up context for later ones
100
+ 3. Create new tasks with \`TaskCreate\` when identifying additional work
101
+ 4. Mark tasks as completed with \`TaskUpdate\` when done, then check TaskList for next work
102
+ 5. Coordinate with other teammates by reading the task list status
103
+ 6. If all available tasks are blocked, notify the team lead or help resolve blocking tasks
104
+
105
+ **IMPORTANT notes for communication with your team**:
106
+ - Do not use terminal tools to view your team's activity; always send a message to your teammates (and remember, refer to them by name).
107
+ - Your team cannot hear you if you do not use the SendMessage tool. Always send a message to your teammates if you are responding to them.
108
+ - Do NOT send structured JSON status messages like \`{"type":"idle",...}\` or \`{"type":"task_completed",...}\`. Just communicate in plain text when you need to message teammates.
109
+ - Use TaskUpdate to mark tasks completed.
110
+ - If you are an agent in the team, the system will automatically send idle notifications to the team lead when you stop.
111
+
112
112
  `.trim();
113
113
  }
@@ -1,16 +1,16 @@
1
1
  export function getPrompt() {
2
- return `
3
- # TeamDelete
4
-
5
- Remove team and task directories when the swarm work is complete.
6
-
7
- This operation:
8
- - Removes the team directory (\`~/.claude/teams/{team-name}/\`)
9
- - Removes the task directory (\`~/.claude/tasks/{team-name}/\`)
10
- - Clears team context from the current session
11
-
12
- **IMPORTANT**: TeamDelete will fail if the team still has active members. Gracefully terminate teammates first, then call TeamDelete after all teammates have shut down.
13
-
14
- Use this when all teammates have finished their work and you want to clean up the team resources. The team name is automatically determined from the current session's team context.
2
+ return `
3
+ # TeamDelete
4
+
5
+ Remove team and task directories when the swarm work is complete.
6
+
7
+ This operation:
8
+ - Removes the team directory (\`~/.claude/teams/{team-name}/\`)
9
+ - Removes the task directory (\`~/.claude/tasks/{team-name}/\`)
10
+ - Clears team context from the current session
11
+
12
+ **IMPORTANT**: TeamDelete will fail if the team still has active members. Gracefully terminate teammates first, then call TeamDelete after all teammates have shut down.
13
+
14
+ Use this when all teammates have finished their work and you want to clean up the team resources. The team name is automatically determined from the current session's team context.
15
15
  `.trim();
16
16
  }
@@ -59,19 +59,19 @@ export function getAdvisorUsage(usage) {
59
59
  }
60
60
  return iterations.filter(it => it.type === 'advisor_message');
61
61
  }
62
- export const ADVISOR_TOOL_INSTRUCTIONS = `# Advisor Tool
63
-
64
- You have access to an \`advisor\` tool backed by a stronger reviewer model. It takes NO parameters -- when you call it, your entire conversation history is automatically forwarded. The advisor sees the task, every tool call you've made, every result you've seen.
65
-
66
- Call advisor BEFORE substantive work -- before writing code, before committing to an interpretation, before building on an assumption. If the task requires orientation first (finding files, reading code, seeing what's there), do that, then call advisor. Orientation is not substantive work. Writing, editing, and declaring an answer are.
67
-
68
- Also call advisor:
69
- - When you believe the task is complete. BEFORE this call, make your deliverable durable: write the file, stage the change, save the result. The advisor call takes time; if the session ends during it, a durable result persists and an unwritten one doesn't.
70
- - When stuck -- errors recurring, approach not converging, results that don't fit.
71
- - When considering a change of approach.
72
-
73
- On tasks longer than a few steps, call advisor at least once before committing to an approach and once before declaring done. On short reactive tasks where the next action is dictated by tool output you just read, you don't need to keep calling -- the advisor adds most of its value on the first call, before the approach crystallizes.
74
-
75
- Give the advice serious weight. If you follow a step and it fails empirically, or you have primary-source evidence that contradicts a specific claim (the file says X, the code does Y), adapt. A passing self-test is not evidence the advice is wrong -- it's evidence your test doesn't check what the advice is checking.
76
-
62
+ export const ADVISOR_TOOL_INSTRUCTIONS = `# Advisor Tool
63
+
64
+ You have access to an \`advisor\` tool backed by a stronger reviewer model. It takes NO parameters -- when you call it, your entire conversation history is automatically forwarded. The advisor sees the task, every tool call you've made, every result you've seen.
65
+
66
+ Call advisor BEFORE substantive work -- before writing code, before committing to an interpretation, before building on an assumption. If the task requires orientation first (finding files, reading code, seeing what's there), do that, then call advisor. Orientation is not substantive work. Writing, editing, and declaring an answer are.
67
+
68
+ Also call advisor:
69
+ - When you believe the task is complete. BEFORE this call, make your deliverable durable: write the file, stage the change, save the result. The advisor call takes time; if the session ends during it, a durable result persists and an unwritten one doesn't.
70
+ - When stuck -- errors recurring, approach not converging, results that don't fit.
71
+ - When considering a change of approach.
72
+
73
+ On tasks longer than a few steps, call advisor at least once before committing to an approach and once before declaring done. On short reactive tasks where the next action is dictated by tool output you just read, you don't need to keep calling -- the advisor adds most of its value on the first call, before the approach crystallizes.
74
+
75
+ Give the advice serious weight. If you follow a step and it fails empirically, or you have primary-source evidence that contradicts a specific claim (the file says X, the code does Y), adapt. A passing self-test is not evidence the advice is wrong -- it's evidence your test doesn't check what the advice is checking.
76
+
77
77
  If you've already retrieved data pointing one way and the advisor points another: don't silently switch. Surface the conflict in one more advisor call -- "I found X, you suggest Y, which constraint breaks the tie?" The advisor saw your evidence but may have underweighted it; a reconcile call is cheaper than committing to the wrong branch.`;
@@ -348,8 +348,8 @@ export function prependUserContext(messages, context) {
348
348
  createUserMessage({
349
349
  content: `<system-reminder>\nAs you answer the user's questions, you can use the following context:\n${Object.entries(context)
350
350
  .map(([key, value]) => `# ${key}\n${value}`)
351
- .join('\n')}
352
-
351
+ .join('\n')}
352
+
353
353
  IMPORTANT: this context may or may not be relevant to your tasks. You should not respond to this context unless it is highly relevant to your task.\n</system-reminder>\n`,
354
354
  isMeta: true,
355
355
  }),
@@ -50,14 +50,14 @@ export async function assertMinVersion() {
50
50
  if (versionConfig.minVersion &&
51
51
  lt(MACRO.VERSION, versionConfig.minVersion)) {
52
52
  // biome-ignore lint/suspicious/noConsole:: intentional console output
53
- console.error(`
54
- It looks like your version of Context Code (${MACRO.VERSION}) needs an update.
55
- A newer version (${versionConfig.minVersion} or higher) is required to continue.
56
-
57
- To update, please run:
58
- claude update
59
-
60
- This will ensure you have access to the latest features and improvements.
53
+ console.error(`
54
+ It looks like your version of Context Code (${MACRO.VERSION}) needs an update.
55
+ A newer version (${versionConfig.minVersion} or higher) is required to continue.
56
+
57
+ To update, please run:
58
+ claude update
59
+
60
+ This will ensure you have access to the latest features and improvements.
61
61
  `);
62
62
  gracefulShutdownSync(1);
63
63
  }
@@ -391,16 +391,16 @@ export async function installGlobalPackage(specificVersion) {
391
391
  currentVersion: MACRO.VERSION,
392
392
  });
393
393
  // biome-ignore lint/suspicious/noConsole:: intentional console output
394
- console.error(`
395
- Error: Windows NPM detected in WSL
396
-
397
- You're running Context Code in WSL but using the Windows NPM installation from /mnt/c/.
398
- This configuration is not supported for updates.
399
-
400
- To fix this issue:
401
- 1. Install Node.js within your Linux distribution: e.g. sudo apt install nodejs npm
402
- 2. Make sure Linux NPM is in your PATH before the Windows version
403
- 3. Try updating again with 'context update'
394
+ console.error(`
395
+ Error: Windows NPM detected in WSL
396
+
397
+ You're running Context Code in WSL but using the Windows NPM installation from /mnt/c/.
398
+ This configuration is not supported for updates.
399
+
400
+ To fix this issue:
401
+ 1. Install Node.js within your Linux distribution: e.g. sudo apt install nodejs npm
402
+ 2. Make sure Linux NPM is in your PATH before the Windows version
403
+ 3. Try updating again with 'context update'
404
404
  `);
405
405
  return 'install_failed';
406
406
  }
@@ -170,62 +170,62 @@ function getUserSnapshotContent(configFile) {
170
170
  let content = '';
171
171
  // User functions
172
172
  if (isZsh) {
173
- content += `
174
- echo "# Functions" >> "$SNAPSHOT_FILE"
175
-
176
- # Force autoload all functions first
177
- typeset -f > /dev/null 2>&1
178
-
179
- # Now get user function names - filter completion functions (single underscore prefix)
180
- # but keep double-underscore helpers (e.g. __zsh_like_cd from mise, __pyenv_init)
181
- typeset +f | grep -vE '^_[^_]' | while read func; do
182
- typeset -f "$func" >> "$SNAPSHOT_FILE"
183
- done
173
+ content += `
174
+ echo "# Functions" >> "$SNAPSHOT_FILE"
175
+
176
+ # Force autoload all functions first
177
+ typeset -f > /dev/null 2>&1
178
+
179
+ # Now get user function names - filter completion functions (single underscore prefix)
180
+ # but keep double-underscore helpers (e.g. __zsh_like_cd from mise, __pyenv_init)
181
+ typeset +f | grep -vE '^_[^_]' | while read func; do
182
+ typeset -f "$func" >> "$SNAPSHOT_FILE"
183
+ done
184
184
  `;
185
185
  }
186
186
  else {
187
- content += `
188
- echo "# Functions" >> "$SNAPSHOT_FILE"
189
-
190
- # Force autoload all functions first
191
- declare -f > /dev/null 2>&1
192
-
193
- # Now get user function names - filter completion functions (single underscore prefix)
194
- # but keep double-underscore helpers (e.g. __zsh_like_cd from mise, __pyenv_init)
195
- declare -F | cut -d' ' -f3 | grep -vE '^_[^_]' | while read func; do
196
- # Encode the function to base64, preserving all special characters
197
- encoded_func=$(declare -f "$func" | base64 )
198
- # Write the function definition to the snapshot
199
- echo "eval ${LITERAL_BACKSLASH}"${LITERAL_BACKSLASH}$(echo '$encoded_func' | base64 -d)${LITERAL_BACKSLASH}" > /dev/null 2>&1" >> "$SNAPSHOT_FILE"
200
- done
187
+ content += `
188
+ echo "# Functions" >> "$SNAPSHOT_FILE"
189
+
190
+ # Force autoload all functions first
191
+ declare -f > /dev/null 2>&1
192
+
193
+ # Now get user function names - filter completion functions (single underscore prefix)
194
+ # but keep double-underscore helpers (e.g. __zsh_like_cd from mise, __pyenv_init)
195
+ declare -F | cut -d' ' -f3 | grep -vE '^_[^_]' | while read func; do
196
+ # Encode the function to base64, preserving all special characters
197
+ encoded_func=$(declare -f "$func" | base64 )
198
+ # Write the function definition to the snapshot
199
+ echo "eval ${LITERAL_BACKSLASH}"${LITERAL_BACKSLASH}$(echo '$encoded_func' | base64 -d)${LITERAL_BACKSLASH}" > /dev/null 2>&1" >> "$SNAPSHOT_FILE"
200
+ done
201
201
  `;
202
202
  }
203
203
  // Shell options
204
204
  if (isZsh) {
205
- content += `
206
- echo "# Shell Options" >> "$SNAPSHOT_FILE"
207
- setopt | sed 's/^/setopt /' | head -n 1000 >> "$SNAPSHOT_FILE"
205
+ content += `
206
+ echo "# Shell Options" >> "$SNAPSHOT_FILE"
207
+ setopt | sed 's/^/setopt /' | head -n 1000 >> "$SNAPSHOT_FILE"
208
208
  `;
209
209
  }
210
210
  else {
211
- content += `
212
- echo "# Shell Options" >> "$SNAPSHOT_FILE"
213
- shopt -p | head -n 1000 >> "$SNAPSHOT_FILE"
214
- set -o | grep "on" | awk '{print "set -o " $1}' | head -n 1000 >> "$SNAPSHOT_FILE"
215
- echo "shopt -s expand_aliases" >> "$SNAPSHOT_FILE"
211
+ content += `
212
+ echo "# Shell Options" >> "$SNAPSHOT_FILE"
213
+ shopt -p | head -n 1000 >> "$SNAPSHOT_FILE"
214
+ set -o | grep "on" | awk '{print "set -o " $1}' | head -n 1000 >> "$SNAPSHOT_FILE"
215
+ echo "shopt -s expand_aliases" >> "$SNAPSHOT_FILE"
216
216
  `;
217
217
  }
218
218
  // User aliases
219
- content += `
220
- echo "# Aliases" >> "$SNAPSHOT_FILE"
221
- # Filter out winpty aliases on Windows to avoid "stdin is not a tty" errors
222
- # Git Bash automatically creates aliases like "alias node='winpty node.exe'" for
223
- # programs that need Win32 Console in mintty, but winpty fails when there's no TTY
224
- if [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "cygwin" ]]; then
225
- alias | grep -v "='winpty " | sed 's/^alias //g' | sed 's/^/alias -- /' | head -n 1000 >> "$SNAPSHOT_FILE"
226
- else
227
- alias | sed 's/^alias //g' | sed 's/^/alias -- /' | head -n 1000 >> "$SNAPSHOT_FILE"
228
- fi
219
+ content += `
220
+ echo "# Aliases" >> "$SNAPSHOT_FILE"
221
+ # Filter out winpty aliases on Windows to avoid "stdin is not a tty" errors
222
+ # Git Bash automatically creates aliases like "alias node='winpty node.exe'" for
223
+ # programs that need Win32 Console in mintty, but winpty fails when there's no TTY
224
+ if [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "cygwin" ]]; then
225
+ alias | grep -v "='winpty " | sed 's/^alias //g' | sed 's/^/alias -- /' | head -n 1000 >> "$SNAPSHOT_FILE"
226
+ else
227
+ alias | sed 's/^alias //g' | sed 's/^/alias -- /' | head -n 1000 >> "$SNAPSHOT_FILE"
228
+ fi
229
229
  `;
230
230
  return content;
231
231
  }
@@ -253,28 +253,28 @@ async function getClaudeCodeSnapshotContent() {
253
253
  // We use a subshell to unalias rg before checking, so that user aliases like
254
254
  // `alias rg='rg --smart-case'` don't shadow the real binary check. The subshell
255
255
  // ensures we don't modify the user's aliases in the parent shell.
256
- content += `
257
- # Check for rg availability
258
- echo "# Check for rg availability" >> "$SNAPSHOT_FILE"
259
- echo "if ! (unalias rg 2>/dev/null; command -v rg) >/dev/null 2>&1; then" >> "$SNAPSHOT_FILE"
256
+ content += `
257
+ # Check for rg availability
258
+ echo "# Check for rg availability" >> "$SNAPSHOT_FILE"
259
+ echo "if ! (unalias rg 2>/dev/null; command -v rg) >/dev/null 2>&1; then" >> "$SNAPSHOT_FILE"
260
260
  `;
261
261
  if (rgIntegration.type === 'function') {
262
262
  // For embedded ripgrep, write the function definition using heredoc
263
- content += `
264
- cat >> "$SNAPSHOT_FILE" << 'RIPGREP_FUNC_END'
265
- ${rgIntegration.snippet}
266
- RIPGREP_FUNC_END
263
+ content += `
264
+ cat >> "$SNAPSHOT_FILE" << 'RIPGREP_FUNC_END'
265
+ ${rgIntegration.snippet}
266
+ RIPGREP_FUNC_END
267
267
  `;
268
268
  }
269
269
  else {
270
270
  // For regular ripgrep, write a simple alias
271
271
  const escapedSnippet = rgIntegration.snippet.replace(/'/g, "'\\''");
272
- content += `
273
- echo ' alias rg='"'${escapedSnippet}'" >> "$SNAPSHOT_FILE"
272
+ content += `
273
+ echo ' alias rg='"'${escapedSnippet}'" >> "$SNAPSHOT_FILE"
274
274
  `;
275
275
  }
276
- content += `
277
- echo "fi" >> "$SNAPSHOT_FILE"
276
+ content += `
277
+ echo "fi" >> "$SNAPSHOT_FILE"
278
278
  `;
279
279
  // For ant-native builds, shadow find/grep with bfs/ugrep embedded in the bun
280
280
  // binary. Unlike rg (which only activates if system rg is absent), we always
@@ -282,19 +282,19 @@ RIPGREP_FUNC_END
282
282
  // consistent fast behavior in Claude's shell.
283
283
  const findGrepIntegration = createFindGrepShellIntegration();
284
284
  if (findGrepIntegration !== null) {
285
- content += `
286
- # Shadow find/grep with embedded bfs/ugrep (ant-native only)
287
- echo "# Shadow find/grep with embedded bfs/ugrep" >> "$SNAPSHOT_FILE"
288
- cat >> "$SNAPSHOT_FILE" << 'FIND_GREP_FUNC_END'
289
- ${findGrepIntegration}
290
- FIND_GREP_FUNC_END
285
+ content += `
286
+ # Shadow find/grep with embedded bfs/ugrep (ant-native only)
287
+ echo "# Shadow find/grep with embedded bfs/ugrep" >> "$SNAPSHOT_FILE"
288
+ cat >> "$SNAPSHOT_FILE" << 'FIND_GREP_FUNC_END'
289
+ ${findGrepIntegration}
290
+ FIND_GREP_FUNC_END
291
291
  `;
292
292
  }
293
293
  // Add PATH to the file
294
- content += `
295
-
296
- # Add PATH to the file
297
- echo "export PATH=${quote([pathValue || ''])}" >> "$SNAPSHOT_FILE"
294
+ content += `
295
+
296
+ # Add PATH to the file
297
+ echo "export PATH=${quote([pathValue || ''])}" >> "$SNAPSHOT_FILE"
298
298
  `;
299
299
  return content;
300
300
  }
@@ -312,27 +312,27 @@ async function getSnapshotScript(shellPath, snapshotFilePath, configFileExists)
312
312
  'echo "shopt -s expand_aliases" >> "$SNAPSHOT_FILE"'
313
313
  : '';
314
314
  const claudeCodeContent = await getClaudeCodeSnapshotContent();
315
- const script = `SNAPSHOT_FILE=${quote([snapshotFilePath])}
316
- ${configFileExists ? `source "${configFile}" < /dev/null` : '# No user config file to source'}
317
-
318
- # First, create/clear the snapshot file
319
- echo "# Snapshot file" >| "$SNAPSHOT_FILE"
320
-
321
- # When this file is sourced, we first unalias to avoid conflicts
322
- # This is necessary because aliases get "frozen" inside function definitions at definition time,
323
- # which can cause unexpected behavior when functions use commands that conflict with aliases
324
- echo "# Unset all aliases to avoid conflicts with functions" >> "$SNAPSHOT_FILE"
325
- echo "unalias -a 2>/dev/null || true" >> "$SNAPSHOT_FILE"
326
-
327
- ${userContent}
328
-
329
- ${claudeCodeContent}
330
-
331
- # Exit silently on success, only report errors
332
- if [ ! -f "$SNAPSHOT_FILE" ]; then
333
- echo "Error: Snapshot file was not created at $SNAPSHOT_FILE" >&2
334
- exit 1
335
- fi
315
+ const script = `SNAPSHOT_FILE=${quote([snapshotFilePath])}
316
+ ${configFileExists ? `source "${configFile}" < /dev/null` : '# No user config file to source'}
317
+
318
+ # First, create/clear the snapshot file
319
+ echo "# Snapshot file" >| "$SNAPSHOT_FILE"
320
+
321
+ # When this file is sourced, we first unalias to avoid conflicts
322
+ # This is necessary because aliases get "frozen" inside function definitions at definition time,
323
+ # which can cause unexpected behavior when functions use commands that conflict with aliases
324
+ echo "# Unset all aliases to avoid conflicts with functions" >> "$SNAPSHOT_FILE"
325
+ echo "unalias -a 2>/dev/null || true" >> "$SNAPSHOT_FILE"
326
+
327
+ ${userContent}
328
+
329
+ ${claudeCodeContent}
330
+
331
+ # Exit silently on success, only report errors
332
+ if [ ! -f "$SNAPSHOT_FILE" ]; then
333
+ echo "Error: Snapshot file was not created at $SNAPSHOT_FILE" >&2
334
+ exit 1
335
+ fi
336
336
  `;
337
337
  return script;
338
338
  }