@iaforged/context-code 1.0.77 → 1.0.79

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 (121) hide show
  1. package/README.md +68 -68
  2. package/cli.js +8515 -8515
  3. package/context-bootstrap.js +27 -27
  4. package/dist/src/bootstrap/state.js +3 -0
  5. package/dist/src/bridge/bridgeMain.js +40 -40
  6. package/dist/src/cli/print.js +12 -12
  7. package/dist/src/commands/agent/agent.js +8 -0
  8. package/dist/src/commands/commit-push-pr.js +55 -55
  9. package/dist/src/commands/createMovedToPluginCommand.js +9 -9
  10. package/dist/src/commands/init-verifiers.js +238 -238
  11. package/dist/src/commands/init.js +216 -216
  12. package/dist/src/commands/install.js +2 -2
  13. package/dist/src/commands/login/login.js +24 -10
  14. package/dist/src/commands/orchestrate/index.js +1 -1
  15. package/dist/src/commands/orchestrate/orchestrate.js +110 -24
  16. package/dist/src/commands/profile/profile.js +15 -1
  17. package/dist/src/commands/provider/index.js +1 -1
  18. package/dist/src/commands/provider/provider.js +34 -1
  19. package/dist/src/commands/review.js +22 -22
  20. package/dist/src/commands/run/index.js +2 -2
  21. package/dist/src/commands/run/run.js +63 -61
  22. package/dist/src/commands/team/index.js +1 -1
  23. package/dist/src/commands/team/team.js +84 -76
  24. package/dist/src/commands/team-auto/teamAuto.js +89 -29
  25. package/dist/src/commands/terminalSetup/terminalSetup.js +24 -24
  26. package/dist/src/commands/usage/index.js +7 -0
  27. package/dist/src/commands/usage/usage.js +5 -0
  28. package/dist/src/commands/workspace/workspace.js +39 -31
  29. package/dist/src/commands.js +0 -2
  30. package/dist/src/components/ConsoleOAuthFlow.js +92 -14
  31. package/dist/src/components/ModelPicker.js +2 -0
  32. package/dist/src/components/agents/generateAgent.js +92 -92
  33. package/dist/src/components/grove/Grove.js +10 -10
  34. package/dist/src/components/permissions/AskUserQuestionPermissionRequest/AskUserQuestionPermissionRequest.js +8 -8
  35. package/dist/src/constants/geminiOAuth.js +13 -0
  36. package/dist/src/constants/github-app.js +134 -134
  37. package/dist/src/constants/prompts.js +123 -123
  38. package/dist/src/coordinator/coordinatorMode.js +252 -252
  39. package/dist/src/hooks/useTypeahead.js +7 -7
  40. package/dist/src/ink/reconciler.js +7 -7
  41. package/dist/src/main.js +5 -5
  42. package/dist/src/memdir/findRelevantMemories.js +6 -6
  43. package/dist/src/services/MagicDocs/prompts.js +56 -56
  44. package/dist/src/services/PromptSuggestion/promptSuggestion.js +29 -29
  45. package/dist/src/services/SessionMemory/prompts.js +66 -66
  46. package/dist/src/services/api/openai.js +584 -21
  47. package/dist/src/services/limits/adapters/ollama.js +3 -3
  48. package/dist/src/services/oauth/geminiCli.js +107 -0
  49. package/dist/src/services/orchestration/execution/AgentTaskExecutor.js +5 -3
  50. package/dist/src/services/orchestration/execution/OrchestrationExecutionRuntime.js +18 -18
  51. package/dist/src/services/orchestration/global/reporting.js +2 -2
  52. package/dist/src/services/toolUseSummary/toolUseSummaryGenerator.js +9 -9
  53. package/dist/src/skills/bundled/batch.js +78 -78
  54. package/dist/src/skills/bundled/claudeApi.js +34 -34
  55. package/dist/src/skills/bundled/claudeInChrome.js +4 -4
  56. package/dist/src/skills/bundled/debug.js +36 -36
  57. package/dist/src/skills/bundled/scheduleRemoteAgents.js +151 -151
  58. package/dist/src/skills/bundled/skillify.js +132 -132
  59. package/dist/src/skills/bundled/stuck.js +53 -53
  60. package/dist/src/skills/bundled/updateConfig.js +418 -418
  61. package/dist/src/tasks/RemoteAgentTask/RemoteAgentTask.js +26 -26
  62. package/dist/src/tools/AgentTool/AgentTool.js +7 -7
  63. package/dist/src/tools/AgentTool/built-in/claudeCodeGuideAgent.js +67 -67
  64. package/dist/src/tools/AgentTool/built-in/exploreAgent.js +32 -32
  65. package/dist/src/tools/AgentTool/built-in/generalPurposeAgent.js +13 -13
  66. package/dist/src/tools/AgentTool/built-in/planAgent.js +49 -49
  67. package/dist/src/tools/AgentTool/built-in/statuslineSetup.js +129 -129
  68. package/dist/src/tools/AgentTool/built-in/verificationAgent.js +119 -119
  69. package/dist/src/tools/AgentTool/prompt.js +131 -131
  70. package/dist/src/tools/AgentTool/runAgent.js +9 -9
  71. package/dist/src/tools/BashTool/BashTool.js +10 -10
  72. package/dist/src/tools/BashTool/prompt.js +94 -94
  73. package/dist/src/tools/ConfigTool/prompt.js +29 -29
  74. package/dist/src/tools/EnterWorktreeTool/prompt.js +27 -27
  75. package/dist/src/tools/FileReadTool/prompt.js +12 -12
  76. package/dist/src/tools/PowerShellTool/prompt.js +82 -82
  77. package/dist/src/tools/RemoteTriggerTool/prompt.js +9 -9
  78. package/dist/src/tools/ScheduleCronTool/prompt.js +37 -37
  79. package/dist/src/tools/TeamCreateTool/prompt.js +110 -110
  80. package/dist/src/tools/TeamDeleteTool/prompt.js +13 -13
  81. package/dist/src/utils/advisor.js +15 -15
  82. package/dist/src/utils/api.js +2 -2
  83. package/dist/src/utils/auth.js +207 -2
  84. package/dist/src/utils/autoUpdater.js +18 -18
  85. package/dist/src/utils/bash/ShellSnapshot.js +86 -86
  86. package/dist/src/utils/bash/commands.js +61 -61
  87. package/dist/src/utils/claudeInChrome/prompt.js +53 -53
  88. package/dist/src/utils/claudeInChrome/setup.js +8 -8
  89. package/dist/src/utils/databaseMcp/server/queries.js +632 -632
  90. package/dist/src/utils/deepLink/registerProtocol.js +35 -35
  91. package/dist/src/utils/deepLink/terminalLauncher.js +12 -12
  92. package/dist/src/utils/hooks/execAgentHook.js +7 -7
  93. package/dist/src/utils/hooks/execPromptHook.js +4 -4
  94. package/dist/src/utils/hooks/skillImprovement.js +36 -36
  95. package/dist/src/utils/logoV2Utils.js +1 -1
  96. package/dist/src/utils/mcp/dateTimeParser.js +9 -9
  97. package/dist/src/utils/messages.js +191 -191
  98. package/dist/src/utils/model/model.js +18 -0
  99. package/dist/src/utils/model/modelOptions.js +51 -1
  100. package/dist/src/utils/model/modelStrings.js +5 -1
  101. package/dist/src/utils/model/modelSupportOverrides.js +3 -0
  102. package/dist/src/utils/model/providerBaseUrls.js +6 -1
  103. package/dist/src/utils/model/providerCatalog.js +64 -28
  104. package/dist/src/utils/model/providerModels.js +88 -17
  105. package/dist/src/utils/model/providerProfiles.js +8 -0
  106. package/dist/src/utils/model/providerProfilesDb.js +578 -393
  107. package/dist/src/utils/model/providerSwitch.js +12 -0
  108. package/dist/src/utils/model/providerWorkspaces.js +2 -0
  109. package/dist/src/utils/model/providers.js +65 -2
  110. package/dist/src/utils/orchestration/store/providerWorkspaceStore.js +3 -1
  111. package/dist/src/utils/orchestration/store/runStore.js +47 -47
  112. package/dist/src/utils/orchestration/store/teamStore.js +61 -61
  113. package/dist/src/utils/powershell/parser.js +253 -253
  114. package/dist/src/utils/sessionTitle.js +12 -12
  115. package/dist/src/utils/sideQuestion.js +17 -17
  116. package/dist/src/utils/status.js +1 -1
  117. package/dist/src/utils/swarm/backends/registry.js +9 -9
  118. package/dist/src/utils/telemetry/instrumentation.js +9 -9
  119. package/dist/src/utils/teleport.js +15 -15
  120. package/dist/src/utils/undercover.js +28 -28
  121. package/package.json +1 -1
@@ -1,27 +1,27 @@
1
- #!/usr/bin/env node
2
- import { existsSync } from 'fs'
3
- import { homedir } from 'os'
4
- import { dirname, join } from 'path'
5
- import { fileURLToPath, pathToFileURL } from 'url'
6
-
7
- const __dirname = dirname(fileURLToPath(import.meta.url))
8
-
9
- if (!process.env.CLAUDE_CONFIG_DIR) {
10
- process.env.CLAUDE_CONFIG_DIR = join(homedir(), '.context')
11
- }
12
-
13
- const isBun = typeof Bun !== 'undefined'
14
- const bundledCli = join(__dirname, 'cli.js')
15
- const distCli = join(__dirname, 'dist', 'src', 'entrypoints', 'cli.js')
16
-
17
- // cli.js es un bundle de Bun — solo usarlo si realmente corremos en Bun
18
- if (isBun && existsSync(bundledCli)) {
19
- await import(pathToFileURL(bundledCli).href)
20
- } else if (existsSync(distCli)) {
21
- await import(pathToFileURL(distCli).href)
22
- } else {
23
- throw new Error(
24
- 'Context Code: no se encontró ningún punto de entrada.\n' +
25
- 'Reinstala el paquete: npm i -g @iaforged/context-code'
26
- )
27
- }
1
+ #!/usr/bin/env node
2
+ import { existsSync } from 'fs'
3
+ import { homedir } from 'os'
4
+ import { dirname, join } from 'path'
5
+ import { fileURLToPath, pathToFileURL } from 'url'
6
+
7
+ const __dirname = dirname(fileURLToPath(import.meta.url))
8
+
9
+ if (!process.env.CLAUDE_CONFIG_DIR) {
10
+ process.env.CLAUDE_CONFIG_DIR = join(homedir(), '.context')
11
+ }
12
+
13
+ const isBun = typeof Bun !== 'undefined'
14
+ const bundledCli = join(__dirname, 'cli.js')
15
+ const distCli = join(__dirname, 'dist', 'src', 'entrypoints', 'cli.js')
16
+
17
+ // cli.js es un bundle de Bun — solo usarlo si realmente corremos en Bun
18
+ if (isBun && existsSync(bundledCli)) {
19
+ await import(pathToFileURL(bundledCli).href)
20
+ } else if (existsSync(distCli)) {
21
+ await import(pathToFileURL(distCli).href)
22
+ } else {
23
+ throw new Error(
24
+ 'Context Code: no se encontró ningún punto de entrada.\n' +
25
+ 'Reinstala el paquete: npm i -g @iaforged/context-code'
26
+ )
27
+ }
@@ -580,6 +580,9 @@ export function getModelStrings() {
580
580
  export function setModelStrings(modelStrings) {
581
581
  STATE.modelStrings = modelStrings;
582
582
  }
583
+ export function clearModelStrings() {
584
+ STATE.modelStrings = null;
585
+ }
583
586
  // Test utility function to reset model strings for re-initialization.
584
587
  // Separate from setModelStrings because we only want to accept 'null' in tests.
585
588
  export function resetModelStringsForTestingOnly() {
@@ -1410,56 +1410,56 @@ async function printHelp() {
1410
1410
  const modes = EXTERNAL_PERMISSION_MODES.join(', ');
1411
1411
  const showServer = await isMultiSessionSpawnEnabled();
1412
1412
  const serverOptions = showServer
1413
- ? ` --spawn <mode> Spawn mode: same-dir, worktree, session
1414
- (default: same-dir)
1415
- --capacity <N> Max concurrent sessions in worktree or
1416
- same-dir mode (default: ${SPAWN_SESSIONS_DEFAULT})
1417
- --[no-]create-session-in-dir Pre-create a session in the current
1418
- directory; in worktree mode this session
1419
- stays in cwd while on-demand sessions get
1420
- isolated worktrees (default: on)
1413
+ ? ` --spawn <mode> Spawn mode: same-dir, worktree, session
1414
+ (default: same-dir)
1415
+ --capacity <N> Max concurrent sessions in worktree or
1416
+ same-dir mode (default: ${SPAWN_SESSIONS_DEFAULT})
1417
+ --[no-]create-session-in-dir Pre-create a session in the current
1418
+ directory; in worktree mode this session
1419
+ stays in cwd while on-demand sessions get
1420
+ isolated worktrees (default: on)
1421
1421
  `
1422
1422
  : '';
1423
1423
  const serverDescription = showServer
1424
- ? `
1425
- Remote Control runs as a persistent server that accepts multiple concurrent
1426
- sessions in the current directory. One session is pre-created on start so
1427
- you have somewhere to type immediately. Use --spawn=worktree to isolate
1428
- each on-demand session in its own git worktree, or --spawn=session for
1429
- the classic single-session mode (exits when that session ends). Press 'w'
1430
- during runtime to toggle between same-dir and worktree.
1424
+ ? `
1425
+ Remote Control runs as a persistent server that accepts multiple concurrent
1426
+ sessions in the current directory. One session is pre-created on start so
1427
+ you have somewhere to type immediately. Use --spawn=worktree to isolate
1428
+ each on-demand session in its own git worktree, or --spawn=session for
1429
+ the classic single-session mode (exits when that session ends). Press 'w'
1430
+ during runtime to toggle between same-dir and worktree.
1431
1431
  `
1432
1432
  : '';
1433
1433
  const serverNote = showServer
1434
- ? ` - Worktree mode requires a git repository or WorktreeCreate/WorktreeRemove hooks
1434
+ ? ` - Worktree mode requires a git repository or WorktreeCreate/WorktreeRemove hooks
1435
1435
  `
1436
1436
  : '';
1437
- const help = `
1438
- Remote Control - Connect your local environment to claude.ai/code
1439
-
1440
- USAGE
1441
- claude remote-control [options]
1442
- OPTIONS
1443
- --name <name> Name for the session (shown in claude.ai/code)
1437
+ const help = `
1438
+ Remote Control - Connect your local environment to claude.ai/code
1439
+
1440
+ USAGE
1441
+ claude remote-control [options]
1442
+ OPTIONS
1443
+ --name <name> Name for the session (shown in claude.ai/code)
1444
1444
  ${feature('KAIROS')
1445
- ? ` -c, --continue Resume the last session in this directory
1446
- --session-id <id> Resume a specific session by ID (cannot be
1447
- used with spawn flags or --continue)
1445
+ ? ` -c, --continue Resume the last session in this directory
1446
+ --session-id <id> Resume a specific session by ID (cannot be
1447
+ used with spawn flags or --continue)
1448
1448
  `
1449
- : ''} --permission-mode <mode> Permission mode for spawned sessions
1450
- (${modes})
1451
- --debug-file <path> Write debug logs to file
1452
- -v, --verbose Enable verbose output
1453
- -h, --help Show this help
1454
- ${serverOptions}
1455
- DESCRIPTION
1456
- Remote Control allows you to control sessions on your local device from
1457
- claude.ai/code (https://claude.ai/code). Run this command in the
1458
- directory you want to work in, then connect from the Claude app or web.
1459
- ${serverDescription}
1460
- NOTES
1461
- - You must be logged in with a Claude account that has a subscription
1462
- - Run \`claude\` first in the directory to accept the workspace trust dialog
1449
+ : ''} --permission-mode <mode> Permission mode for spawned sessions
1450
+ (${modes})
1451
+ --debug-file <path> Write debug logs to file
1452
+ -v, --verbose Enable verbose output
1453
+ -h, --help Show this help
1454
+ ${serverOptions}
1455
+ DESCRIPTION
1456
+ Remote Control allows you to control sessions on your local device from
1457
+ claude.ai/code (https://claude.ai/code). Run this command in the
1458
+ directory you want to work in, then connect from the Claude app or web.
1459
+ ${serverDescription}
1460
+ NOTES
1461
+ - You must be logged in with a Claude account that has a subscription
1462
+ - Run \`claude\` first in the directory to accept the workspace trust dialog
1463
1463
  ${serverNote}`;
1464
1464
  // biome-ignore lint/suspicious/noConsole: intentional help output
1465
1465
  console.log(help);
@@ -152,18 +152,18 @@ const extractMemoriesModule = feature('EXTRACT_MEMORIES')
152
152
  ? require('../services/extractMemories/extractMemories.js')
153
153
  : null;
154
154
  /* eslint-enable @typescript-eslint/no-require-imports */
155
- const SHUTDOWN_TEAM_PROMPT = `<system-reminder>
156
- You are running in non-interactive mode and cannot return a response to the user until your team is shut down.
157
-
158
- You MUST shut down your team before preparing your final response:
159
- 1. Use requestShutdown to ask each team member to shut down gracefully
160
- 2. Wait for shutdown approvals
161
- 3. Use the cleanup operation to clean up the team
162
- 4. Only then provide your final response to the user
163
-
164
- The user cannot receive your response until the team is completely shut down.
165
- </system-reminder>
166
-
155
+ const SHUTDOWN_TEAM_PROMPT = `<system-reminder>
156
+ You are running in non-interactive mode and cannot return a response to the user until your team is shut down.
157
+
158
+ You MUST shut down your team before preparing your final response:
159
+ 1. Use requestShutdown to ask each team member to shut down gracefully
160
+ 2. Wait for shutdown approvals
161
+ 3. Use the cleanup operation to clean up the team
162
+ 4. Only then provide your final response to the user
163
+
164
+ The user cannot receive your response until the team is completely shut down.
165
+ </system-reminder>
166
+
167
167
  Shut down your team and prepare your final response for the user.`;
168
168
  // Track message UUIDs received during the current session runtime
169
169
  const MAX_RECEIVED_UUIDS = 10_000;
@@ -14,6 +14,14 @@ function normalizeProviderInput(rawProvider) {
14
14
  case 'ollama_cloud':
15
15
  case 'ollamacloud':
16
16
  return 'ollama-cloud';
17
+ case 'gemini':
18
+ case 'gemini-api-key':
19
+ case 'google-ai':
20
+ return 'gemini-api';
21
+ case 'gemini-google':
22
+ case 'google':
23
+ case 'google-oauth':
24
+ return 'gemini-google';
17
25
  default:
18
26
  return rawProvider.trim().toLowerCase();
19
27
  }
@@ -26,14 +26,14 @@ function getPromptContent(defaultBranch, prAttribution) {
26
26
  let prefix = '';
27
27
  let reviewerArg = ' and `--reviewer anthropics/claude-code`';
28
28
  let addReviewerArg = ' (and add `--add-reviewer anthropics/claude-code`)';
29
- let changelogSection = `
30
-
31
- ## Changelog
32
- <!-- CHANGELOG:START -->
33
- [If this PR contains user-facing changes, add a changelog entry here. Otherwise, remove this section.]
29
+ let changelogSection = `
30
+
31
+ ## Changelog
32
+ <!-- CHANGELOG:START -->
33
+ [If this PR contains user-facing changes, add a changelog entry here. Otherwise, remove this section.]
34
34
  <!-- CHANGELOG:END -->`;
35
- let slackStep = `
36
-
35
+ let slackStep = `
36
+
37
37
  5. After creating/updating the PR, check if the user's CLAUDE.md mentions posting to Slack channels. If it does, use ToolSearch to search for "slack send message" tools. If ToolSearch finds a Slack tool, ask the user if they'd like you to post the PR URL to the relevant Slack channel. Only post if the user confirms. If ToolSearch returns no results or errors, skip this step silently—do not mention the failure, do not attempt workarounds, and do not try alternative approaches.`;
38
38
  if (process.env.USER_TYPE === 'ant' && isUndercover()) {
39
39
  prefix = getUndercoverInstructions() + '\n';
@@ -42,54 +42,54 @@ function getPromptContent(defaultBranch, prAttribution) {
42
42
  changelogSection = '';
43
43
  slackStep = '';
44
44
  }
45
- return `${prefix}## Context
46
-
47
- - \`SAFEUSER\`: ${safeUser}
48
- - \`whoami\`: ${username}
49
- - \`git status\`: !\`git status\`
50
- - \`git diff HEAD\`: !\`git diff HEAD\`
51
- - \`git branch --show-current\`: !\`git branch --show-current\`
52
- - \`git diff ${defaultBranch}...HEAD\`: !\`git diff ${defaultBranch}...HEAD\`
53
- - \`gh pr view --json number 2>/dev/null || true\`: !\`gh pr view --json number 2>/dev/null || true\`
54
-
55
- ## Git Safety Protocol
56
-
57
- - NEVER update the git config
58
- - NEVER run destructive/irreversible git commands (like push --force, hard reset, etc) unless the user explicitly requests them
59
- - NEVER skip hooks (--no-verify, --no-gpg-sign, etc) unless the user explicitly requests it
60
- - NEVER run force push to main/master, warn the user if they request it
61
- - Do not commit files that likely contain secrets (.env, credentials.json, etc)
62
- - Never use git commands with the -i flag (like git rebase -i or git add -i) since they require interactive input which is not supported
63
-
64
- ## Your task
65
-
66
- Analyze all changes that will be included in the pull request, making sure to look at all relevant commits (NOT just the latest commit, but ALL commits that will be included in the pull request from the git diff ${defaultBranch}...HEAD output above).
67
-
68
- Based on the above changes:
69
- 1. Create a new branch if on ${defaultBranch} (use SAFEUSER from context above for the branch name prefix, falling back to whoami if SAFEUSER is empty, e.g., \`username/feature-name\`)
70
- 2. Create a single commit with an appropriate message using heredoc syntax${commitAttribution ? `, ending with the attribution text shown in the example below` : ''}:
71
- \`\`\`
72
- git commit -m "$(cat <<'EOF'
73
- Commit message here.${commitAttribution ? `\n\n${commitAttribution}` : ''}
74
- EOF
75
- )"
76
- \`\`\`
77
- 3. Push the branch to origin
78
- 4. If a PR already exists for this branch (check the gh pr view output above), update the PR title and body using \`gh pr edit\` to reflect the current diff${addReviewerArg}. Otherwise, create a pull request using \`gh pr create\` with heredoc syntax for the body${reviewerArg}.
79
- - IMPORTANT: Keep PR titles short (under 70 characters). Use the body for details.
80
- \`\`\`
81
- gh pr create --title "Short, descriptive title" --body "$(cat <<'EOF'
82
- ## Summary
83
- <1-3 bullet points>
84
-
85
- ## Test plan
86
- [Bulleted markdown checklist of TODOs for testing the pull request...]${changelogSection}${effectivePrAttribution ? `\n\n${effectivePrAttribution}` : ''}
87
- EOF
88
- )"
89
- \`\`\`
90
-
91
- You have the capability to call multiple tools in a single response. You MUST do all of the above in a single message.${slackStep}
92
-
45
+ return `${prefix}## Context
46
+
47
+ - \`SAFEUSER\`: ${safeUser}
48
+ - \`whoami\`: ${username}
49
+ - \`git status\`: !\`git status\`
50
+ - \`git diff HEAD\`: !\`git diff HEAD\`
51
+ - \`git branch --show-current\`: !\`git branch --show-current\`
52
+ - \`git diff ${defaultBranch}...HEAD\`: !\`git diff ${defaultBranch}...HEAD\`
53
+ - \`gh pr view --json number 2>/dev/null || true\`: !\`gh pr view --json number 2>/dev/null || true\`
54
+
55
+ ## Git Safety Protocol
56
+
57
+ - NEVER update the git config
58
+ - NEVER run destructive/irreversible git commands (like push --force, hard reset, etc) unless the user explicitly requests them
59
+ - NEVER skip hooks (--no-verify, --no-gpg-sign, etc) unless the user explicitly requests it
60
+ - NEVER run force push to main/master, warn the user if they request it
61
+ - Do not commit files that likely contain secrets (.env, credentials.json, etc)
62
+ - Never use git commands with the -i flag (like git rebase -i or git add -i) since they require interactive input which is not supported
63
+
64
+ ## Your task
65
+
66
+ Analyze all changes that will be included in the pull request, making sure to look at all relevant commits (NOT just the latest commit, but ALL commits that will be included in the pull request from the git diff ${defaultBranch}...HEAD output above).
67
+
68
+ Based on the above changes:
69
+ 1. Create a new branch if on ${defaultBranch} (use SAFEUSER from context above for the branch name prefix, falling back to whoami if SAFEUSER is empty, e.g., \`username/feature-name\`)
70
+ 2. Create a single commit with an appropriate message using heredoc syntax${commitAttribution ? `, ending with the attribution text shown in the example below` : ''}:
71
+ \`\`\`
72
+ git commit -m "$(cat <<'EOF'
73
+ Commit message here.${commitAttribution ? `\n\n${commitAttribution}` : ''}
74
+ EOF
75
+ )"
76
+ \`\`\`
77
+ 3. Push the branch to origin
78
+ 4. If a PR already exists for this branch (check the gh pr view output above), update the PR title and body using \`gh pr edit\` to reflect the current diff${addReviewerArg}. Otherwise, create a pull request using \`gh pr create\` with heredoc syntax for the body${reviewerArg}.
79
+ - IMPORTANT: Keep PR titles short (under 70 characters). Use the body for details.
80
+ \`\`\`
81
+ gh pr create --title "Short, descriptive title" --body "$(cat <<'EOF'
82
+ ## Summary
83
+ <1-3 bullet points>
84
+
85
+ ## Test plan
86
+ [Bulleted markdown checklist of TODOs for testing the pull request...]${changelogSection}${effectivePrAttribution ? `\n\n${effectivePrAttribution}` : ''}
87
+ EOF
88
+ )"
89
+ \`\`\`
90
+
91
+ You have the capability to call multiple tools in a single response. You MUST do all of the above in a single message.${slackStep}
92
+
93
93
  Return the PR URL when you're done, so the user can see it.`;
94
94
  }
95
95
  const command = {
@@ -14,15 +14,15 @@ export function createMovedToPluginCommand({ name, description, progressMessage,
14
14
  return [
15
15
  {
16
16
  type: 'text',
17
- text: `This command has been moved to a plugin. Tell the user:
18
-
19
- 1. To install the plugin, run:
20
- claude plugin install ${pluginName}@claude-code-marketplace
21
-
22
- 2. After installation, use /${pluginName}:${pluginCommand} to run this command
23
-
24
- 3. For more information, see: https://github.com/anthropics/claude-code-marketplace/blob/main/${pluginName}/README.md
25
-
17
+ text: `This command has been moved to a plugin. Tell the user:
18
+
19
+ 1. To install the plugin, run:
20
+ claude plugin install ${pluginName}@claude-code-marketplace
21
+
22
+ 2. After installation, use /${pluginName}:${pluginCommand} to run this command
23
+
24
+ 3. For more information, see: https://github.com/anthropics/claude-code-marketplace/blob/main/${pluginName}/README.md
25
+
26
26
  Do not attempt to run the command. Simply inform the user about the plugin installation.`,
27
27
  },
28
28
  ];