mirror of
https://github.com/anthropics/claude-code.git
synced 2026-05-03 03:32:45 +00:00
Compare commits
22 Commits
ashwin/tas
...
dalton/rea
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5a2442227a | ||
|
|
f5dd15ac7e | ||
|
|
c0a28eede9 | ||
|
|
81f65bea8a | ||
|
|
dc8f77c7ef | ||
|
|
786259a00c | ||
|
|
8e679e75f7 | ||
|
|
87560460bc | ||
|
|
07e13937b2 | ||
|
|
55988caadf | ||
|
|
8beb9b0c76 | ||
|
|
4607d83fa8 | ||
|
|
70d5361861 | ||
|
|
c792b7d4c7 | ||
|
|
5f52517c0b | ||
|
|
cc09d58e8e | ||
|
|
d820a4dbd7 | ||
|
|
2b46e47360 | ||
|
|
c58a7da257 | ||
|
|
6d79459b16 | ||
|
|
20ba9a34a5 | ||
|
|
10a1f7dab9 |
@@ -65,8 +65,8 @@ ENV PATH=$PATH:/usr/local/share/npm-global/bin
|
|||||||
ENV SHELL=/bin/zsh
|
ENV SHELL=/bin/zsh
|
||||||
|
|
||||||
# Set the default editor and visual
|
# Set the default editor and visual
|
||||||
ENV EDITOR nano
|
ENV EDITOR=nano
|
||||||
ENV VISUAL nano
|
ENV VISUAL=nano
|
||||||
|
|
||||||
# Default powerline10k theme
|
# Default powerline10k theme
|
||||||
ARG ZSH_IN_DOCKER_VERSION=1.2.0
|
ARG ZSH_IN_DOCKER_VERSION=1.2.0
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
"customizations": {
|
"customizations": {
|
||||||
"vscode": {
|
"vscode": {
|
||||||
"extensions": [
|
"extensions": [
|
||||||
|
"anthropic.claude-code",
|
||||||
"dbaeumer.vscode-eslint",
|
"dbaeumer.vscode-eslint",
|
||||||
"esbenp.prettier-vscode",
|
"esbenp.prettier-vscode",
|
||||||
"eamodio.gitlens"
|
"eamodio.gitlens"
|
||||||
@@ -51,5 +52,6 @@
|
|||||||
},
|
},
|
||||||
"workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind,consistency=delegated",
|
"workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind,consistency=delegated",
|
||||||
"workspaceFolder": "/workspace",
|
"workspaceFolder": "/workspace",
|
||||||
"postCreateCommand": "sudo /usr/local/bin/init-firewall.sh"
|
"postStartCommand": "sudo /usr/local/bin/init-firewall.sh",
|
||||||
|
"waitFor": "postStartCommand"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,7 +69,10 @@ for domain in \
|
|||||||
"api.anthropic.com" \
|
"api.anthropic.com" \
|
||||||
"sentry.io" \
|
"sentry.io" \
|
||||||
"statsig.anthropic.com" \
|
"statsig.anthropic.com" \
|
||||||
"statsig.com"; do
|
"statsig.com" \
|
||||||
|
"marketplace.visualstudio.com" \
|
||||||
|
"vscode.blob.core.windows.net" \
|
||||||
|
"update.code.visualstudio.com"; do
|
||||||
echo "Resolving $domain..."
|
echo "Resolving $domain..."
|
||||||
ips=$(dig +noall +answer A "$domain" | awk '$4 == "A" {print $5}')
|
ips=$(dig +noall +answer A "$domain" | awk '$4 == "A" {print $5}')
|
||||||
if [ -z "$ips" ]; then
|
if [ -z "$ips" ]; then
|
||||||
@@ -113,6 +116,9 @@ iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
|
|||||||
# Then allow only specific outbound traffic to allowed domains
|
# Then allow only specific outbound traffic to allowed domains
|
||||||
iptables -A OUTPUT -m set --match-set allowed-domains dst -j ACCEPT
|
iptables -A OUTPUT -m set --match-set allowed-domains dst -j ACCEPT
|
||||||
|
|
||||||
|
# Explicitly REJECT all other outbound traffic for immediate feedback
|
||||||
|
iptables -A OUTPUT -j REJECT --reject-with icmp-admin-prohibited
|
||||||
|
|
||||||
echo "Firewall configuration complete"
|
echo "Firewall configuration complete"
|
||||||
echo "Verifying firewall rules..."
|
echo "Verifying firewall rules..."
|
||||||
if curl --connect-timeout 5 https://example.com >/dev/null 2>&1; then
|
if curl --connect-timeout 5 https://example.com >/dev/null 2>&1; then
|
||||||
|
|||||||
59
.github/workflows/issue-notify.yml
vendored
Normal file
59
.github/workflows/issue-notify.yml
vendored
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
name: Issue Notification
|
||||||
|
|
||||||
|
on:
|
||||||
|
issues:
|
||||||
|
types: [opened]
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
issues: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
notify:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 5
|
||||||
|
steps:
|
||||||
|
- name: Send notification
|
||||||
|
env:
|
||||||
|
ISSUE_NUMBER: ${{ github.event.issue.number }}
|
||||||
|
ISSUE_TITLE: ${{ github.event.issue.title }}
|
||||||
|
ISSUE_BODY: ${{ github.event.issue.body }}
|
||||||
|
ISSUE_AUTHOR: ${{ github.event.issue.user.login }}
|
||||||
|
ISSUE_LABELS: ${{ toJSON(github.event.issue.labels) }}
|
||||||
|
ISSUE_URL: ${{ github.event.issue.html_url }}
|
||||||
|
ISSUE_CREATED_AT: ${{ github.event.issue.created_at }}
|
||||||
|
REPOSITORY: ${{ github.repository }}
|
||||||
|
DISPATCH_TOKEN: ${{ secrets.CROSS_REPO_TOKEN_CLAUDE_CODE }}
|
||||||
|
DISPATCH_ENDPOINT: ${{ secrets.DISPATCH_ENDPOINT }}
|
||||||
|
run: |
|
||||||
|
if [ -z "$DISPATCH_TOKEN" ] || [ -z "$DISPATCH_ENDPOINT" ]; then
|
||||||
|
echo "Dispatch configuration not complete, skipping notification"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Prepare payload with issue metadata
|
||||||
|
PAYLOAD=$(cat <<EOF
|
||||||
|
{
|
||||||
|
"event_type": "issue_event",
|
||||||
|
"client_payload": {
|
||||||
|
"source_repo": "$REPOSITORY",
|
||||||
|
"issue_number": "$ISSUE_NUMBER",
|
||||||
|
"issue_title": $(echo "$ISSUE_TITLE" | jq -Rs .),
|
||||||
|
"issue_body": $(echo "$ISSUE_BODY" | jq -Rs .),
|
||||||
|
"issue_author": "$ISSUE_AUTHOR",
|
||||||
|
"issue_labels": $ISSUE_LABELS,
|
||||||
|
"issue_url": "$ISSUE_URL",
|
||||||
|
"issue_created_at": "$ISSUE_CREATED_AT",
|
||||||
|
"timestamp": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
)
|
||||||
|
|
||||||
|
# Send notification to configured endpoint
|
||||||
|
curl -X POST \
|
||||||
|
-H "Accept: application/vnd.github.v3+json" \
|
||||||
|
-H "Authorization: token $DISPATCH_TOKEN" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
"$DISPATCH_ENDPOINT" \
|
||||||
|
-d "$PAYLOAD" \
|
||||||
|
--fail-with-body || echo "Notification sent"
|
||||||
2
.github/workflows/log-issue-events.yml
vendored
2
.github/workflows/log-issue-events.yml
vendored
@@ -2,7 +2,7 @@ name: Log Issue Events to Statsig
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
issues:
|
issues:
|
||||||
types: [opened]
|
types: [opened, closed]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
log-to-statsig:
|
log-to-statsig:
|
||||||
|
|||||||
20
CHANGELOG.md
20
CHANGELOG.md
@@ -1,5 +1,25 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 1.0.97
|
||||||
|
|
||||||
|
- Settings: /doctor now validates permission rule syntax and suggests corrections
|
||||||
|
|
||||||
|
## 1.0.94
|
||||||
|
|
||||||
|
- Vertex: add support for global endpoints for supported models
|
||||||
|
- /memory command now allows direct editing of all imported memory files
|
||||||
|
- SDK: Add custom tools as callbacks
|
||||||
|
- Added /todos command to list current todo items
|
||||||
|
|
||||||
|
## 1.0.93
|
||||||
|
|
||||||
|
- Windows: Add alt + v shortcut for pasting images from clipboard
|
||||||
|
- Support NO_PROXY environment variable to bypass proxy for specified hostnames and IPs
|
||||||
|
|
||||||
|
## 1.0.90
|
||||||
|
|
||||||
|
- Settings file changes take effect immediately - no restart required
|
||||||
|
|
||||||
## 1.0.88
|
## 1.0.88
|
||||||
|
|
||||||
- Fixed issue causing "OAuth authentication is currently not supported"
|
- Fixed issue causing "OAuth authentication is currently not supported"
|
||||||
|
|||||||
@@ -34,9 +34,7 @@ When you use Claude Code, we collect feedback, which includes usage data (such a
|
|||||||
|
|
||||||
### How we use your data
|
### How we use your data
|
||||||
|
|
||||||
We may use feedback to improve our products and services, but we will not train generative models using your feedback from Claude Code. Given their potentially sensitive nature, we store user feedback transcripts for only 30 days.
|
See our [data usage policies](https://docs.anthropic.com/en/docs/claude-code/data-usage).
|
||||||
|
|
||||||
If you choose to send us feedback about Claude Code, such as transcripts of your usage, Anthropic may use that feedback to debug related issues and improve Claude Code's functionality (e.g., to reduce the risk of similar bugs occurring in the future).
|
|
||||||
|
|
||||||
### Privacy safeguards
|
### Privacy safeguards
|
||||||
|
|
||||||
|
|||||||
@@ -40,14 +40,18 @@ Write-Host "Using backend: $($Backend)"
|
|||||||
# --- Prerequisite Check ---
|
# --- Prerequisite Check ---
|
||||||
Write-Host "Checking for required commands..."
|
Write-Host "Checking for required commands..."
|
||||||
try {
|
try {
|
||||||
Get-Command $Backend -ErrorAction Stop | Out-Null
|
if (-not (Get-Command $Backend -ErrorAction SilentlyContinue)) {
|
||||||
|
throw "Required command '$($Backend)' not found."
|
||||||
|
}
|
||||||
Write-Host "- $($Backend) command found."
|
Write-Host "- $($Backend) command found."
|
||||||
Get-Command devcontainer -ErrorAction Stop | Out-Null
|
if (-not (Get-Command devcontainer -ErrorAction SilentlyContinue)) {
|
||||||
|
throw "Required command 'devcontainer' not found."
|
||||||
|
}
|
||||||
Write-Host "- devcontainer command found."
|
Write-Host "- devcontainer command found."
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
Write-Error "A required command is not installed or not in your PATH."
|
Write-Error "A required command is not installed or not in your PATH. $($_.Exception.Message)"
|
||||||
Write-Error "Please ensure '$($_.Exception.Message.Split(':')[0])' and 'devcontainer' are installed and accessible."
|
Write-Error "Please ensure both '$Backend' and 'devcontainer' are installed and accessible in your system's PATH."
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -82,46 +82,61 @@ Usage:
|
|||||||
Environment Variables:
|
Environment Variables:
|
||||||
GITHUB_TOKEN - GitHub personal access token with repo and actions permissions (required)
|
GITHUB_TOKEN - GitHub personal access token with repo and actions permissions (required)
|
||||||
DRY_RUN - Set to "false" to actually trigger workflows (default: true for safety)
|
DRY_RUN - Set to "false" to actually trigger workflows (default: true for safety)
|
||||||
DAYS_BACK - How many days back to look for old issues (default: 90)`);
|
MAX_ISSUE_NUMBER - Only process issues with numbers less than this value (default: 4050)`);
|
||||||
}
|
}
|
||||||
console.log("[DEBUG] GitHub token found");
|
console.log("[DEBUG] GitHub token found");
|
||||||
|
|
||||||
const owner = "anthropics";
|
const owner = "anthropics";
|
||||||
const repo = "claude-code";
|
const repo = "claude-code";
|
||||||
const dryRun = process.env.DRY_RUN !== "false";
|
const dryRun = process.env.DRY_RUN !== "false";
|
||||||
const daysBack = parseInt(process.env.DAYS_BACK || "90", 10);
|
const maxIssueNumber = parseInt(process.env.MAX_ISSUE_NUMBER || "4050", 10);
|
||||||
|
const minIssueNumber = parseInt(process.env.MIN_ISSUE_NUMBER || "1", 10);
|
||||||
|
|
||||||
console.log(`[DEBUG] Repository: ${owner}/${repo}`);
|
console.log(`[DEBUG] Repository: ${owner}/${repo}`);
|
||||||
console.log(`[DEBUG] Dry run mode: ${dryRun}`);
|
console.log(`[DEBUG] Dry run mode: ${dryRun}`);
|
||||||
console.log(`[DEBUG] Looking back ${daysBack} days`);
|
console.log(`[DEBUG] Looking at issues between #${minIssueNumber} and #${maxIssueNumber}`);
|
||||||
|
|
||||||
const cutoffDate = new Date();
|
console.log(`[DEBUG] Fetching issues between #${minIssueNumber} and #${maxIssueNumber}...`);
|
||||||
cutoffDate.setDate(cutoffDate.getDate() - daysBack);
|
|
||||||
|
|
||||||
console.log(`[DEBUG] Fetching issues created since ${cutoffDate.toISOString()}...`);
|
|
||||||
const allIssues: GitHubIssue[] = [];
|
const allIssues: GitHubIssue[] = [];
|
||||||
let page = 1;
|
let page = 1;
|
||||||
const perPage = 100;
|
const perPage = 100;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
const pageIssues: GitHubIssue[] = await githubRequest(
|
const pageIssues: GitHubIssue[] = await githubRequest(
|
||||||
`/repos/${owner}/${repo}/issues?state=all&per_page=${perPage}&page=${page}&since=${cutoffDate.toISOString()}`,
|
`/repos/${owner}/${repo}/issues?state=all&per_page=${perPage}&page=${page}&sort=created&direction=desc`,
|
||||||
token
|
token
|
||||||
);
|
);
|
||||||
|
|
||||||
if (pageIssues.length === 0) break;
|
if (pageIssues.length === 0) break;
|
||||||
|
|
||||||
allIssues.push(...pageIssues);
|
// Filter to only include issues within the specified range
|
||||||
|
const filteredIssues = pageIssues.filter(issue =>
|
||||||
|
issue.number >= minIssueNumber && issue.number < maxIssueNumber
|
||||||
|
);
|
||||||
|
allIssues.push(...filteredIssues);
|
||||||
|
|
||||||
|
// If the oldest issue in this page is still above our minimum, we need to continue
|
||||||
|
// but if the oldest issue is below our minimum, we can stop
|
||||||
|
const oldestIssueInPage = pageIssues[pageIssues.length - 1];
|
||||||
|
if (oldestIssueInPage && oldestIssueInPage.number >= maxIssueNumber) {
|
||||||
|
console.log(`[DEBUG] Oldest issue in page #${page} is #${oldestIssueInPage.number}, continuing...`);
|
||||||
|
} else if (oldestIssueInPage && oldestIssueInPage.number < minIssueNumber) {
|
||||||
|
console.log(`[DEBUG] Oldest issue in page #${page} is #${oldestIssueInPage.number}, below minimum, stopping`);
|
||||||
|
break;
|
||||||
|
} else if (filteredIssues.length === 0 && pageIssues.length > 0) {
|
||||||
|
console.log(`[DEBUG] No issues in page #${page} are in range #${minIssueNumber}-#${maxIssueNumber}, continuing...`);
|
||||||
|
}
|
||||||
|
|
||||||
page++;
|
page++;
|
||||||
|
|
||||||
// Safety limit to avoid infinite loops
|
// Safety limit to avoid infinite loops
|
||||||
if (page > 100) {
|
if (page > 200) {
|
||||||
console.log("[DEBUG] Reached page limit, stopping pagination");
|
console.log("[DEBUG] Reached page limit, stopping pagination");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`[DEBUG] Found ${allIssues.length} issues from the last ${daysBack} days`);
|
console.log(`[DEBUG] Found ${allIssues.length} issues between #${minIssueNumber} and #${maxIssueNumber}`);
|
||||||
|
|
||||||
let processedCount = 0;
|
let processedCount = 0;
|
||||||
let candidateCount = 0;
|
let candidateCount = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user