-
Notifications
You must be signed in to change notification settings - Fork 7
feat: auto-discover MCP servers from external AI tool configs #311
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,113 @@ | ||||||||
| --- | ||||||||
| name: pr-ce | ||||||||
| description: "Format, verify markers, update docs, commit, and create PR for altimate-code" | ||||||||
| --- | ||||||||
|
|
||||||||
| You are preparing altimate-code for a pull request. This project is a fork of opencode — upstream-shared files need `altimate_change` markers and docs must be updated. | ||||||||
|
|
||||||||
| **CRITICAL: ALL steps are MANDATORY. You MUST complete every single step. DO NOT skip any step. DO NOT mark docs as "N/A" if you added tools, skills, agents, or changed config. DO NOT rationalize skipping with "can follow later" — that is a workflow violation. If you skip a step, you have failed the task.** | ||||||||
|
|
||||||||
| ## Step 1: Run Tests | ||||||||
|
|
||||||||
| ```bash | ||||||||
| cd /home/kulvir/altimate-code/packages/opencode && bun test 2>&1 | tail -5 | ||||||||
| ``` | ||||||||
|
|
||||||||
| If tests fail, fix the issues before continuing. | ||||||||
|
|
||||||||
| ## Step 2: Verify Upstream Markers | ||||||||
|
|
||||||||
| Run the marker guard to check upstream-shared files have `altimate_change` markers: | ||||||||
|
|
||||||||
| ```bash | ||||||||
| cd /home/kulvir/altimate-code && bun run script/upstream/analyze.ts --markers --base main 2>&1 | ||||||||
| ``` | ||||||||
|
Comment on lines
+22
to
+24
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Another hardcoded absolute path. Same portability issue as above. Proposed fix-cd /home/kulvir/altimate-code && bun run script/upstream/analyze.ts --markers --base main 2>&1
+bun run script/upstream/analyze.ts --markers --base main 2>&1🤖 Prompt for AI Agents
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Personal command file — hardcoded paths are intentional for my local machine. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
✏️ Learnings added
|
||||||||
|
|
||||||||
| If warnings appear for files YOU changed in this PR, wrap the custom code with markers: | ||||||||
|
|
||||||||
| ```typescript | ||||||||
| // altimate_change start — description of what we changed | ||||||||
| ... our modifications ... | ||||||||
| // altimate_change end | ||||||||
| ``` | ||||||||
|
|
||||||||
| Files in `packages/opencode/src/altimate/` are fully ours (in `keepOurs`) — no markers needed. | ||||||||
| Files in `packages/opencode/src/` that exist upstream need markers. | ||||||||
| New files (not in upstream) don't need markers. | ||||||||
|
|
||||||||
| ## Step 3: Update Docs | ||||||||
|
|
||||||||
| Check if your changes affect any documented behavior: | ||||||||
|
|
||||||||
| ```bash | ||||||||
| git diff main...HEAD --name-only | head -30 | ||||||||
| ``` | ||||||||
|
|
||||||||
| If changes touch: | ||||||||
| - **Agent/mode definitions** → update `docs/docs/configure/agents.md` | ||||||||
| - **Permission rules** → update `docs/docs/configure/permissions.md` | ||||||||
| - **Config schema** → update `docs/docs/configure/config.md` | ||||||||
| - **Skills** → update `docs/docs/configure/skills.md` | ||||||||
| - **Tools** → update `docs/docs/configure/tools.md` | ||||||||
| - **Tracing** → update `docs/docs/configure/tracing.md` | ||||||||
|
|
||||||||
| Read the relevant doc file and ensure it matches the new behavior. | ||||||||
|
|
||||||||
| **YOU MUST UPDATE DOCS if you added or changed any tool, skill, agent, permission, or config option. "N/A" is ONLY acceptable if the change is purely internal with zero user-facing impact. When in doubt, update the docs.** | ||||||||
|
|
||||||||
| ## Step 4: Stage and Commit | ||||||||
|
|
||||||||
| ```bash | ||||||||
| cd /home/kulvir/altimate-code && git add -A | ||||||||
| ``` | ||||||||
|
Comment on lines
+60
to
+62
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Third hardcoded absolute path. Proposed fix-cd /home/kulvir/altimate-code && git add -A
+git add -A📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same — personal command, not project code. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
(ʃƪ˘ᵕ˘) |
||||||||
|
|
||||||||
| Check if branch has existing commits ahead of main: | ||||||||
|
|
||||||||
| ```bash | ||||||||
| git log origin/main..HEAD --oneline | ||||||||
| ``` | ||||||||
|
|
||||||||
| - **No commits:** Create new commit with a clear message based on changes. | ||||||||
| - **Commits exist:** Amend the existing commit: `git commit --amend --no-edit` | ||||||||
|
|
||||||||
| ## Step 5: Push | ||||||||
|
|
||||||||
| ```bash | ||||||||
| git push --force-with-lease origin HEAD | ||||||||
| ``` | ||||||||
|
|
||||||||
| ## Step 6: Create Pull Request | ||||||||
|
|
||||||||
| Check if PR already exists: | ||||||||
|
|
||||||||
| ```bash | ||||||||
| gh pr view --json url -q .url 2>/dev/null | ||||||||
| ``` | ||||||||
|
|
||||||||
| **If PR exists:** Report the URL. | ||||||||
|
|
||||||||
| **If no PR exists:** Create one: | ||||||||
|
|
||||||||
| ```bash | ||||||||
| gh pr create --title "COMMIT_TITLE_HERE" --body "$(cat <<'EOF' | ||||||||
| ## Summary | ||||||||
| - Brief description of changes | ||||||||
|
|
||||||||
| ## Checklist | ||||||||
| - [x] Tests pass | ||||||||
| - [x] TypeScript compiles | ||||||||
| - [x] Upstream markers verified | ||||||||
| - [x] Docs updated (if applicable) | ||||||||
|
Comment on lines
+96
to
+100
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't pre-check the compile box yet. This workflow never runs a TypeScript compile/typecheck before creating the PR body, so this checklist item can become a false attestation. Add the real compile step earlier or leave it unchecked here. 🤖 Prompt for AI Agents
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Acknowledged — removed tsgo step earlier, will update checklist. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||||||||
|
|
||||||||
| 🤖 Generated with [Claude Code](https://claude.com/claude-code) | ||||||||
| EOF | ||||||||
| )" | ||||||||
| ``` | ||||||||
|
|
||||||||
| ## Step 7: Confirm | ||||||||
|
|
||||||||
| Report: | ||||||||
| - Commit message | ||||||||
| - PR URL | ||||||||
| - Marker status (clean / warnings) | ||||||||
| - Docs updated (which files, or "N/A") | ||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| --- | ||
| description: "Discover MCP servers from external AI tool configs and add them permanently" | ||
| --- | ||
|
|
||
| Discover MCP servers configured in other AI tools (VS Code, Cursor, GitHub Copilot, Claude Code, Gemini CLI) and add them to the altimate-code config. | ||
|
|
||
| ## Instructions | ||
|
|
||
| 1. First, call the `mcp_discover` tool with `action: "list"` to see what's available. | ||
|
|
||
| 2. Show the user the results — which servers are new and which are already configured. | ||
|
|
||
| 3. If there are new servers, ask the user which ones they want to add and what scope (project or global). | ||
|
|
||
| 4. Call `mcp_discover` with `action: "add"`, the chosen `scope`, and the selected `servers` array. | ||
|
|
||
| 5. Report what was added and where. | ||
|
|
||
| If $ARGUMENTS contains `--scope global`, use `scope: "global"`. Otherwise default to `scope: "project"`. | ||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,4 +15,7 @@ | |
| "github-triage": false, | ||
| "github-pr-search": false, | ||
| }, | ||
| "experimental": { | ||
| "auto_mcp_discovery": false, | ||
| }, | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -110,3 +110,41 @@ When [LSP servers](lsp.md) are configured, the `lsp` tool provides: | |
| - Go-to-definition | ||
| - Hover information | ||
| - Completions | ||
|
|
||
| ### MCP Discover Tool | ||
|
|
||
| The `mcp_discover` tool finds MCP servers configured in other AI coding tools and can add them to your altimate-code config permanently. | ||
|
|
||
| **Supported sources:** | ||
|
|
||
| | Tool | Config Path | Key | | ||
| |------|------------|-----| | ||
| | VS Code / Copilot | `.vscode/mcp.json` | `servers` | | ||
| | Cursor | `.cursor/mcp.json` | `mcpServers` | | ||
| | GitHub Copilot | `.github/copilot/mcp.json` | `mcpServers` | | ||
| | Claude Code | `.mcp.json`, `~/.claude.json` | `mcpServers` | | ||
| | Gemini CLI | `.gemini/settings.json` | `mcpServers` | | ||
|
|
||
| **Actions:** | ||
|
|
||
| - `mcp_discover(action: "list")` — Show discovered servers and which are already in your config | ||
| - `mcp_discover(action: "add", scope: "project")` — Write new servers to `.altimate-code/altimate-code.json` | ||
| - `mcp_discover(action: "add", scope: "global")` — Write to `~/.config/opencode/opencode.json` | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -eu
rg -n -C3 'updateGlobal|globalConfigFile|altimate-code\.json|opencode\.json' \
packages/opencode/src/altimate/tools/mcp-discover.ts \
packages/opencode/src/config/config.tsRepository: AltimateAI/altimate-code Length of output: 6566 🏁 Script executed: #!/bin/bash
set -eu
# Get full updateGlobal implementation
rg -n -A20 'export async function updateGlobal' packages/opencode/src/config/config.ts
# Check if mcp-discover calls updateGlobal
rg -n 'updateGlobal|Config\.updateGlobal' packages/opencode/src/altimate/tools/mcp-discover.tsRepository: AltimateAI/altimate-code Length of output: 906 🏁 Script executed: #!/bin/bash
set -eu
# Get complete globalConfigFile implementation
rg -n -A15 'function globalConfigFile' packages/opencode/src/config/config.ts
# Check how mcp-discover handles the "global" scope - look for file write logic
rg -n -B5 -A15 'if.*scope.*global\|global.*scope' packages/opencode/src/altimate/tools/mcp-discover.tsRepository: AltimateAI/altimate-code Length of output: 702 🏁 Script executed: #!/bin/bash
set -eu
# Read the full mcp-discover.ts to understand the complete flow
wc -l packages/opencode/src/altimate/tools/mcp-discover.tsRepository: AltimateAI/altimate-code Length of output: 124 🏁 Script executed: #!/bin/bash
cat -n packages/opencode/src/altimate/tools/mcp-discover.tsRepository: AltimateAI/altimate-code Length of output: 5625 🏁 Script executed: #!/bin/bash
set -eu
# Find and read resolveConfigPath
rg -n -A20 'export.*function resolveConfigPath\|export.*const resolveConfigPath' packages/opencode/src/mcp/config.tsRepository: AltimateAI/altimate-code Length of output: 50 🏁 Script executed: #!/bin/bash
set -eu
# Search for resolveConfigPath definition across the codebase
rg -n 'function resolveConfigPath|const resolveConfigPath' packages/opencode/src/
# Also check mcp/config.ts file size to understand scope
wc -l packages/opencode/src/mcp/config.tsRepository: AltimateAI/altimate-code Length of output: 219 🏁 Script executed: #!/bin/bash
cat -n packages/opencode/src/mcp/config.ts | head -40Repository: AltimateAI/altimate-code Length of output: 1669 🏁 Script executed: #!/bin/bash
sed -n '125,140p' docs/docs/configure/tools.mdRepository: AltimateAI/altimate-code Length of output: 1333 Update documentation to reflect actual config filename used. On fresh installs, 🤖 Prompt for AI Agents
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch on the path — it uses There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
- `mcp_discover(action: "add", scope: "global")` — Write to `~/.config/opencode/altimate-code.json` (or the first existing config file found in that directory)Or, if you want to surface the full resolution logic: - `mcp_discover(action: "add", scope: "global")` — Write to the global config dir (`~/.config/opencode/`), targeting the first existing file among `altimate-code.json`, `opencode.json`, or `opencode.jsonc`; defaults to `altimate-code.json` on fresh installs.Would you like me to plan the documentation fix? |
||
|
|
||
| **Auto-discovery:** At startup, altimate-code automatically discovers external MCP servers and loads them into the current session. A toast notification shows what was found. Use the `/discover-and-add-mcps` skill or the `mcp_discover` tool to make them permanent. | ||
|
|
||
| !!! tip | ||
| Servers discovered from external configs are loaded automatically — no restart needed. Making them permanent via `mcp_discover(action: "add")` ensures they persist even if the original config file is removed. | ||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| !!! warning "Security: untrusted repositories" | ||
| Auto-discovery loads MCP servers from project-level files like `.vscode/mcp.json` and `.mcp.json`. A malicious repository could include configs that execute arbitrary commands. Review discovered servers before making them permanent, especially in cloned repositories you don't trust. Disable auto-discovery with `experimental.auto_mcp_discovery: false`. | ||
|
|
||
| To disable auto-discovery, set in your config: | ||
|
|
||
| ```json | ||
| { | ||
| "experimental": { | ||
| "auto_mcp_discovery": false | ||
| } | ||
| } | ||
| ``` | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,120 @@ | ||
| import z from "zod" | ||
| import { Tool } from "../../tool/tool" | ||
| import { discoverExternalMcp } from "../../mcp/discover" | ||
| import { resolveConfigPath, addMcpToConfig, findAllConfigPaths, listMcpInConfig } from "../../mcp/config" | ||
| import { Instance } from "../../project/instance" | ||
| import { Global } from "../../global" | ||
|
|
||
| /** | ||
| * Check which MCP server names are permanently configured on disk | ||
| * (as opposed to ephemeral auto-discovered servers in memory). | ||
| */ | ||
| async function getPersistedMcpNames(): Promise<Set<string>> { | ||
| const configPaths = await findAllConfigPaths(Instance.worktree, Global.Path.config) | ||
| const names = new Set<string>() | ||
| for (const p of configPaths) { | ||
| for (const name of await listMcpInConfig(p)) { | ||
| names.add(name) | ||
| } | ||
| } | ||
| return names | ||
| } | ||
|
|
||
| /** Redact server details for safe display — show type and name only, not commands/URLs */ | ||
| function safeDetail(server: { type: string } & Record<string, any>): string { | ||
| if (server.type === "remote") return "(remote)" | ||
| if (server.type === "local" && Array.isArray(server.command) && server.command.length > 0) { | ||
| // Show only the executable name, not args (which may contain credentials) | ||
| return `(local: ${server.command[0]})` | ||
| } | ||
| return `(${server.type})` | ||
| } | ||
|
|
||
| export const McpDiscoverTool = Tool.define("mcp_discover", { | ||
| description: | ||
| "Discover MCP servers from external AI tool configs (VS Code, Claude Code, Copilot, Gemini) and optionally add them to altimate-code config permanently.", | ||
| parameters: z.object({ | ||
| action: z | ||
| .enum(["list", "add"]) | ||
| .describe('"list" to show discovered servers, "add" to write them to config'), | ||
| scope: z | ||
| .enum(["project", "global"]) | ||
| .optional() | ||
| .default("project") | ||
| .describe('Where to write when action is "add". "project" = .altimate-code/altimate-code.json, "global" = ~/.config/opencode/'), | ||
| servers: z | ||
| .array(z.string()) | ||
| .optional() | ||
| .describe('Server names to add. If omitted with action "add", adds all new servers.'), | ||
| }), | ||
| async execute(args, ctx) { | ||
| const { servers: discovered } = await discoverExternalMcp(Instance.worktree) | ||
| const discoveredNames = Object.keys(discovered) | ||
|
|
||
| if (discoveredNames.length === 0) { | ||
| return { | ||
| title: "MCP Discover: none found", | ||
| metadata: { discovered: 0, new: 0, existing: 0, added: 0 }, | ||
| output: | ||
| "No MCP servers found in external configs.\nChecked: .vscode/mcp.json, .github/copilot/mcp.json, .mcp.json, ~/.gemini/settings.json, ~/.claude.json", | ||
| } | ||
| } | ||
|
|
||
| // Check what's actually persisted on disk, NOT the merged in-memory config | ||
| const persistedNames = await getPersistedMcpNames() | ||
| const newServers = discoveredNames.filter((n) => !persistedNames.has(n)) | ||
| const alreadyAdded = discoveredNames.filter((n) => persistedNames.has(n)) | ||
|
|
||
| // Build discovery report — redact details for security (no raw commands/URLs) | ||
| const lines: string[] = [] | ||
| if (newServers.length > 0) { | ||
| lines.push(`New servers (not yet in config):`) | ||
| for (const name of newServers) { | ||
| lines.push(` - ${name} ${safeDetail(discovered[name])}`) | ||
| } | ||
| } | ||
| if (alreadyAdded.length > 0) { | ||
| lines.push(`\nAlready in config: ${alreadyAdded.join(", ")}`) | ||
| } | ||
|
|
||
| if (args.action === "list") { | ||
| return { | ||
| title: `MCP Discover: ${newServers.length} new, ${alreadyAdded.length} existing`, | ||
| metadata: { discovered: discoveredNames.length, new: newServers.length, existing: alreadyAdded.length, added: 0 }, | ||
| output: lines.join("\n"), | ||
| } | ||
| } | ||
|
|
||
| // action === "add" | ||
| const toAdd = args.servers | ||
| ? args.servers.filter((n) => newServers.includes(n)) | ||
| : newServers | ||
|
|
||
| if (toAdd.length === 0) { | ||
| return { | ||
| title: "MCP Discover: nothing to add", | ||
| metadata: { discovered: discoveredNames.length, new: newServers.length, existing: alreadyAdded.length, added: 0 }, | ||
| output: lines.join("\n") + "\n\nNo matching servers to add.", | ||
| } | ||
| } | ||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| const useGlobal = args.scope === "global" | ||
| const configPath = await resolveConfigPath( | ||
| useGlobal ? Global.Path.config : Instance.worktree, | ||
| useGlobal, | ||
| ) | ||
|
|
||
| for (const name of toAdd) { | ||
| await addMcpToConfig(name, discovered[name], configPath) | ||
| } | ||
|
|
||
| lines.push(`\nAdded ${toAdd.length} server(s) to ${configPath}: ${toAdd.join(", ")}`) | ||
| lines.push("These servers are already active in the current session via auto-discovery.") | ||
|
|
||
| return { | ||
| title: `MCP Discover: added ${toAdd.length} server(s)`, | ||
| metadata: { discovered: discoveredNames.length, new: newServers.length, existing: alreadyAdded.length, added: toAdd.length }, | ||
| output: lines.join("\n"), | ||
| } | ||
| }, | ||
| }) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -264,6 +264,24 @@ export namespace Config { | |
|
|
||
| result.plugin = deduplicatePlugins(result.plugin ?? []) | ||
|
|
||
| // altimate_change start — auto-discover MCP servers from external AI tool configs | ||
| if (!Flag.OPENCODE_DISABLE_PROJECT_CONFIG && result.experimental?.auto_mcp_discovery !== false) { | ||
| const { discoverExternalMcp, setDiscoveryResult } = await import("../mcp/discover") | ||
| const { servers: externalMcp, sources } = await discoverExternalMcp(Instance.worktree) | ||
| if (Object.keys(externalMcp).length > 0) { | ||
| result.mcp ??= {} | ||
| const added: string[] = [] | ||
| for (const [name, server] of Object.entries(externalMcp)) { | ||
| if (!(name in result.mcp)) { | ||
| result.mcp[name] = server | ||
| added.push(name) | ||
| } | ||
| } | ||
| setDiscoveryResult(added, sources) | ||
|
Comment on lines
+267
to
+280
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Project MCP auto-discovery is a repo-open code-execution path. This merges repo-owned MCP definitions into the live config before startup completes. Since 🤖 Prompt for AI Agents
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added security warning in docs and There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
VS Code prompts users to trust each MCP server before it runs, and re-prompts after configuration changes. This is a separate trust boundary from Workspace Trust — an untrusted workspace runs in restricted mode, which also disables agents. When you add an MCP server to your workspace or change its configuration, VS Code shows a dialog to confirm that you trust the server when you start a server for the first time. If you don't trust the MCP server, it will not be started. So VS Code's model is actually: opt-in via explicit per-server consent dialog, not opt-out via a config flag. The current implementation is closer to the reverse — silently merging and executing project-owned MCP commands at startup, with a global kill-switch to turn the feature off entirely. The remaining concern is specifically the project-scope discovery path ( A middle ground that would narrow the risk without adding a full consent UI:
This would still surface the configurations for easy adoption while preventing automatic code execution from repo-committed files. Would that tradeoff work for your use case? |
||
| } | ||
| } | ||
| // altimate_change end | ||
|
|
||
| return { | ||
| config: result, | ||
| directories, | ||
|
|
@@ -1273,6 +1291,12 @@ export namespace Config { | |
| .optional() | ||
| .describe("Use environment fingerprint to select relevant skills once per session (default: false). Set to true to enable LLM-based skill filtering."), | ||
| // altimate_change end | ||
| // altimate_change start - auto MCP discovery toggle | ||
| auto_mcp_discovery: z | ||
| .boolean() | ||
| .optional() | ||
| .describe("Auto-discover MCP servers from VS Code, Claude Code, Copilot, and Gemini configs at startup (default: true). Set to false to disable."), | ||
| // altimate_change end | ||
| }) | ||
| .optional(), | ||
| }) | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: AltimateAI/altimate-code
Length of output: 338
🏁 Script executed:
Repository: AltimateAI/altimate-code
Length of output: 95
🏁 Script executed:
Repository: AltimateAI/altimate-code
Length of output: 1383
Preserve the test exit code in Step 1.
The pipeline
bun test 2>&1 | tail -5returns the exit code oftail, notbun test. A failing test run will still report success unless you preserve the first command's exit status usingPIPESTATUSorpipefail.Suggested fix
🤖 Prompt for AI Agents
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personal command — not project code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kulvirgit, understood — since this is a personal Claude Code slash-command for your own workflow rather than project or CI code, the exit-code concern doesn't apply. Thanks for the context!