mirror of
https://github.com/anthropics/claude-code.git
synced 2026-04-27 23:42:42 +00:00
Compare commits
2 Commits
bcherny-pa
...
github-api
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bc84d5711b | ||
|
|
555b6b5b8a |
@@ -42,9 +42,10 @@ RUN mkdir -p /workspace /home/node/.claude && \
|
|||||||
|
|
||||||
WORKDIR /workspace
|
WORKDIR /workspace
|
||||||
|
|
||||||
RUN wget https://github.com/dandavison/delta/releases/download/0.18.2/git-delta_0.18.2_arm64.deb && \
|
RUN ARCH=$(dpkg --print-architecture) && \
|
||||||
sudo dpkg -i git-delta_0.18.2_arm64.deb && \
|
wget "https://github.com/dandavison/delta/releases/download/0.18.2/git-delta_0.18.2_${ARCH}.deb" && \
|
||||||
rm git-delta_0.18.2_arm64.deb
|
sudo dpkg -i "git-delta_0.18.2_${ARCH}.deb" && \
|
||||||
|
rm "git-delta_0.18.2_${ARCH}.deb"
|
||||||
|
|
||||||
# Set up non-root user
|
# Set up non-root user
|
||||||
USER node
|
USER node
|
||||||
@@ -66,13 +67,12 @@ RUN sh -c "$(wget -O- https://github.com/deluan/zsh-in-docker/releases/download/
|
|||||||
-x
|
-x
|
||||||
|
|
||||||
# Install Claude
|
# Install Claude
|
||||||
# TODO(ben): Add this back in when we have a public release
|
RUN npm install -g @anthropic-ai/claude-code
|
||||||
# RUN npm install -g @anthropic-ai/claude-code
|
|
||||||
|
|
||||||
# Copy and set up firewall script
|
# Copy and set up scripts
|
||||||
COPY init-firewall.sh /usr/local/bin/
|
COPY init-firewall.sh cache-github-api.sh /usr/local/bin/
|
||||||
USER root
|
USER root
|
||||||
RUN chmod +x /usr/local/bin/init-firewall.sh && \
|
RUN chmod +x /usr/local/bin/init-firewall.sh /usr/local/bin/cache-github-api.sh && \
|
||||||
echo "node ALL=(root) NOPASSWD: /usr/local/bin/init-firewall.sh" > /etc/sudoers.d/node-firewall && \
|
echo "node ALL=(root) NOPASSWD: /usr/local/bin/init-firewall.sh" > /etc/sudoers.d/node-firewall && \
|
||||||
chmod 0440 /etc/sudoers.d/node-firewall
|
chmod 0440 /etc/sudoers.d/node-firewall
|
||||||
USER node
|
USER node
|
||||||
|
|||||||
109
.devcontainer/cache-github-api.sh
Executable file
109
.devcontainer/cache-github-api.sh
Executable file
@@ -0,0 +1,109 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Script to cache GitHub API data
|
||||||
|
# Used to prevent rate limiting during container builds
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
# Store cache in the home directory
|
||||||
|
CACHE_DIR="${HOME}/.github-meta-cache"
|
||||||
|
CACHE_FILE="${CACHE_DIR}/meta.json"
|
||||||
|
TIMESTAMP_FILE="${CACHE_DIR}/meta-timestamp.txt"
|
||||||
|
MAX_AGE_SECONDS=3600 # Cache expires after 1 hour
|
||||||
|
|
||||||
|
# Create cache directory if it doesn't exist
|
||||||
|
mkdir -p "${CACHE_DIR}"
|
||||||
|
|
||||||
|
# Function to get current timestamp
|
||||||
|
get_timestamp() {
|
||||||
|
date +%s
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to check if cache is valid
|
||||||
|
is_cache_valid() {
|
||||||
|
if [[ ! -f "${CACHE_FILE}" || ! -f "${TIMESTAMP_FILE}" ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
local cache_time=$(cat "${TIMESTAMP_FILE}")
|
||||||
|
local current_time=$(get_timestamp)
|
||||||
|
local age=$((current_time - cache_time))
|
||||||
|
|
||||||
|
if [[ ${age} -gt ${MAX_AGE_SECONDS} ]]; then
|
||||||
|
echo "Cache is expired (${age} seconds old)"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Using cached GitHub API data (${age} seconds old)"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to fetch data using authenticated gh cli
|
||||||
|
fetch_with_gh() {
|
||||||
|
echo "Attempting to fetch GitHub API data using authenticated gh CLI..."
|
||||||
|
if gh auth status &>/dev/null; then
|
||||||
|
gh api meta > "${CACHE_FILE}" &&
|
||||||
|
get_timestamp > "${TIMESTAMP_FILE}" &&
|
||||||
|
echo "Successfully fetched and cached GitHub API data using gh CLI"
|
||||||
|
return $?
|
||||||
|
else
|
||||||
|
echo "gh CLI not authenticated"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to fetch data using curl
|
||||||
|
fetch_with_curl() {
|
||||||
|
echo "Attempting to fetch GitHub API data using curl..."
|
||||||
|
# First try with GITHUB_TOKEN if available
|
||||||
|
if [[ -n "${GITHUB_TOKEN}" ]]; then
|
||||||
|
echo "Using GITHUB_TOKEN for authentication"
|
||||||
|
curl -s -H "Authorization: token ${GITHUB_TOKEN}" https://api.github.com/meta > "${CACHE_FILE}" &&
|
||||||
|
get_timestamp > "${TIMESTAMP_FILE}" &&
|
||||||
|
echo "Successfully fetched and cached GitHub API data using curl with token"
|
||||||
|
return $?
|
||||||
|
else
|
||||||
|
# Fall back to unauthenticated request
|
||||||
|
echo "No GITHUB_TOKEN found, making unauthenticated request (may be rate limited)"
|
||||||
|
curl -s https://api.github.com/meta > "${CACHE_FILE}"
|
||||||
|
|
||||||
|
# Check if the response indicates rate limiting
|
||||||
|
if grep -q "API rate limit exceeded" "${CACHE_FILE}"; then
|
||||||
|
echo "Rate limit exceeded for unauthenticated request"
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
get_timestamp > "${TIMESTAMP_FILE}"
|
||||||
|
echo "Successfully fetched and cached GitHub API data using curl without auth"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main logic
|
||||||
|
if is_cache_valid; then
|
||||||
|
echo "Using existing cache from $(cat ${TIMESTAMP_FILE})"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Try with gh CLI first
|
||||||
|
if ! fetch_with_gh; then
|
||||||
|
# Fall back to curl
|
||||||
|
if ! fetch_with_curl; then
|
||||||
|
# Both methods failed, check if we have an existing cache file
|
||||||
|
if [[ -f "${CACHE_FILE}" ]]; then
|
||||||
|
echo "Warning: Failed to update cache, using existing cached data (which may be expired)"
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo "Error: Failed to fetch GitHub API data and no cache exists"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Display a summary of the cached data
|
||||||
|
echo "GitHub API meta data cached successfully. Summary:"
|
||||||
|
jq -r '.domains.actions | length' "${CACHE_FILE}" > /dev/null 2>&1 &&
|
||||||
|
echo "- Actions domains: $(jq -r '.domains.actions | length' "${CACHE_FILE}")" ||
|
||||||
|
echo "- Could not parse actions domains from cache file"
|
||||||
|
|
||||||
|
exit 0
|
||||||
@@ -4,6 +4,9 @@
|
|||||||
"dockerfile": "Dockerfile",
|
"dockerfile": "Dockerfile",
|
||||||
"args": {
|
"args": {
|
||||||
"TZ": "${localEnv:TZ:America/Los_Angeles}"
|
"TZ": "${localEnv:TZ:America/Los_Angeles}"
|
||||||
|
},
|
||||||
|
"prebuild": {
|
||||||
|
"command": "bash -c '${localWorkspaceFolder}/.devcontainer/cache-github-api.sh || echo \"Warning: Failed to cache GitHub API data\"'"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"runArgs": [
|
"runArgs": [
|
||||||
@@ -39,7 +42,8 @@
|
|||||||
"remoteUser": "node",
|
"remoteUser": "node",
|
||||||
"mounts": [
|
"mounts": [
|
||||||
"source=claude-code-bashhistory,target=/commandhistory,type=volume",
|
"source=claude-code-bashhistory,target=/commandhistory,type=volume",
|
||||||
"source=claude-code-config,target=/home/node/.claude,type=volume"
|
"source=claude-code-config,target=/home/node/.claude,type=volume",
|
||||||
|
"type=bind,source=${localEnv:HOME}/.github-meta-cache,target=/github-meta-cache,consistency=cached"
|
||||||
],
|
],
|
||||||
"remoteEnv": {
|
"remoteEnv": {
|
||||||
"NODE_OPTIONS": "--max-old-space-size=4096",
|
"NODE_OPTIONS": "--max-old-space-size=4096",
|
||||||
|
|||||||
@@ -27,16 +27,20 @@ iptables -A OUTPUT -o lo -j ACCEPT
|
|||||||
# Create ipset with CIDR support
|
# Create ipset with CIDR support
|
||||||
ipset create allowed-domains hash:net
|
ipset create allowed-domains hash:net
|
||||||
|
|
||||||
# Fetch GitHub meta information and aggregate + add their IP ranges
|
# Use cached GitHub meta information from mounted volume
|
||||||
echo "Fetching GitHub IP ranges..."
|
CACHE_FILE="/github-meta-cache/meta.json"
|
||||||
gh_ranges=$(curl -s https://api.github.com/meta)
|
|
||||||
if [ -z "$gh_ranges" ]; then
|
|
||||||
echo "ERROR: Failed to fetch GitHub IP ranges"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! echo "$gh_ranges" | jq -e '.web and .api and .git' >/dev/null; then
|
echo "Using cached GitHub IP ranges..."
|
||||||
echo "ERROR: GitHub API response missing required fields"
|
if [ -f "${CACHE_FILE}" ]; then
|
||||||
|
gh_ranges=$(cat "${CACHE_FILE}")
|
||||||
|
|
||||||
|
# Verify the cached data is valid
|
||||||
|
if ! echo "$gh_ranges" | jq -e '.web and .api and .git' >/dev/null; then
|
||||||
|
echo "ERROR: Cached GitHub API data is invalid"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "ERROR: No cached GitHub IP ranges found"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
* text=auto eol=lf
|
||||||
|
*.sh text eol=lf
|
||||||
34
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
34
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Create a report to help us improve
|
||||||
|
title: '[BUG] '
|
||||||
|
labels: bug
|
||||||
|
assignees: ''
|
||||||
|
---
|
||||||
|
|
||||||
|
## Environment
|
||||||
|
- Platform (select one):
|
||||||
|
- [ ] Anthropic API
|
||||||
|
- [ ] AWS Bedrock
|
||||||
|
- [ ] Google Vertex AI
|
||||||
|
- [ ] Other: <!-- specify -->
|
||||||
|
- Claude CLI version: <!-- output of `claude --version` -->
|
||||||
|
- Operating System: <!-- e.g. macOS 14.3, Windows 11, Ubuntu 22.04 -->
|
||||||
|
- Terminal: <!-- e.g. iTerm2, Terminal App -->
|
||||||
|
|
||||||
|
## Bug Description
|
||||||
|
<!-- A clear and concise description of the bug -->
|
||||||
|
|
||||||
|
## Steps to Reproduce
|
||||||
|
1. <!-- First step -->
|
||||||
|
2. <!-- Second step -->
|
||||||
|
3. <!-- And so on... -->
|
||||||
|
|
||||||
|
## Expected Behavior
|
||||||
|
<!-- What you expected to happen -->
|
||||||
|
|
||||||
|
## Actual Behavior
|
||||||
|
<!-- What actually happened -->
|
||||||
|
|
||||||
|
## Additional Context
|
||||||
|
<!-- Add any other context about the problem here, such as screenshots, logs, etc. -->
|
||||||
31
README.md
31
README.md
@@ -1,6 +1,8 @@
|
|||||||
# Claude Code (Research Preview)
|
# Claude Code (Research Preview)
|
||||||
|
|
||||||

|
 [![npm]](https://www.npmjs.com/package/@anthropic-ai/claude-code)
|
||||||
|
|
||||||
|
[npm]: https://img.shields.io/npm/v/@anthropic-ai/claude-code.svg?style=flat-square
|
||||||
|
|
||||||
Claude Code is an agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster by executing routine tasks, explaining complex code, and handling git workflows - all through natural language commands.
|
Claude Code is an agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster by executing routine tasks, explaining complex code, and handling git workflows - all through natural language commands.
|
||||||
|
|
||||||
@@ -15,18 +17,21 @@ Some of its key capabilities include:
|
|||||||
|
|
||||||
## Get started
|
## Get started
|
||||||
|
|
||||||
<ol>
|
1. If you are new to Node.js and Node Package Manager (`npm`), then it is recommended that you configure an NPM prefix for your user.
|
||||||
<li>
|
Instructions on how to do this can be found [here](https://docs.anthropic.com/en/docs/agents-and-tools/claude-code/overview#recommended-create-a-new-user-writable-npm-prefix).
|
||||||
Run the following command in your terminal: <br />
|
|
||||||
<code>npm install -g @anthropic-ai/claude-code</code>
|
*Important* We recommend installing this package as a non-privileged user, not as an administrative user like `root`.
|
||||||
</li>
|
Installing as a non-privileged user helps maintain your system's security and stability.
|
||||||
<li>
|
|
||||||
Navigate to your project directory and run <code>claude</code>
|
2. Install Claude Code:
|
||||||
</li>
|
|
||||||
<li>
|
```sh
|
||||||
Complete the one-time OAuth process with your Anthropic Console account.
|
npm install -g @anthropic-ai/claude-code
|
||||||
</li>
|
```
|
||||||
</ol>
|
|
||||||
|
3. Navigate to your project directory and run <code>claude</code>.
|
||||||
|
|
||||||
|
4. Complete the one-time OAuth process with your Anthropic Console account.
|
||||||
|
|
||||||
### Research Preview
|
### Research Preview
|
||||||
|
|
||||||
|
|||||||
12
SECURITY.md
Normal file
12
SECURITY.md
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
# Security Policy
|
||||||
|
Thank you for helping us keep Claude Code secure!
|
||||||
|
|
||||||
|
## Reporting Security Issues
|
||||||
|
|
||||||
|
The security of our systems and user data is Anthropic's top priority. We appreciate the work of security researchers acting in good faith in identifying and reporting potential vulnerabilities.
|
||||||
|
|
||||||
|
Our security program is managed on HackerOne and we ask that any validated vulnerability in this functionality be reported through their [submission form](https://hackerone.com/anthropic-vdp/reports/new?type=team&report_type=vulnerability).
|
||||||
|
|
||||||
|
## Vulnerability Disclosure Program
|
||||||
|
|
||||||
|
Our Vulnerability Program Guidelines are defined on our [HackerOne program page](https://hackerone.com/anthropic-vdp).
|
||||||
Reference in New Issue
Block a user