curses 1.6.0 → 1.6.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c6c663a808bf8a6c76299105512ed71e57db768054d26ffd51527b254b6fed9f
4
- data.tar.gz: 6c088c90e25573f398d2051b84be37c394acace504948ed831d039e1e625efe2
3
+ metadata.gz: fb2bc3cbe268313c253f41ee1a5e5bbabe504fa69e7631fae89a0865f1298125
4
+ data.tar.gz: a534a9ec711119fd1739c5df302167efc550fc089b346ab89b97004096cce060
5
5
  SHA512:
6
- metadata.gz: e4404453e5b9c2d2db0697131c1253f3363d553e51f7427822e4ec7d5c70b3959a457cb4791c694be979d54bf0dec13dbf2b7904bab6115a0b7722979982829c
7
- data.tar.gz: 5a6e4d31948c5808601fec0e34633b185586657af4e6bb8d95e07b9144991e0ff3e5f15584985997e9847232510d55c99b9b9821a052ef7784607a1aa2f8214b
6
+ metadata.gz: 8be3f5ce383b3626e8cd3a2800408bb6fbc8abc98a24e13bd365d7e74e93c49aff2f2501d73a2db584bcd7250f2834215411cd1ab7511c7c4fd8a4457e55e56a
7
+ data.tar.gz: e67a948df315465f11539eda4bd9f751272c02a72bfa68b0546ade9b7af86d0f097ccebc9b9b318449958362ba99d748a23b63de76664b581e2ce675db509347
@@ -0,0 +1,132 @@
1
+ FROM node:20
2
+
3
+ ARG TZ
4
+ ENV TZ="$TZ"
5
+
6
+ ARG CLAUDE_CODE_VERSION=latest
7
+
8
+ # Install GitHub CLI from official repository
9
+ RUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \
10
+ | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg \
11
+ && chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg \
12
+ && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" \
13
+ > /etc/apt/sources.list.d/github-cli.list
14
+
15
+ # Install basic development tools and iptables/ipset
16
+ RUN apt-get update && apt-get install -y --no-install-recommends \
17
+ less \
18
+ git \
19
+ procps \
20
+ sudo \
21
+ fzf \
22
+ zsh \
23
+ man-db \
24
+ unzip \
25
+ gnupg2 \
26
+ gh \
27
+ iptables \
28
+ ipset \
29
+ iproute2 \
30
+ dnsutils \
31
+ aggregate \
32
+ jq \
33
+ nano \
34
+ vim \
35
+ locales \
36
+ # Ruby build dependencies
37
+ build-essential \
38
+ libssl-dev \
39
+ libreadline-dev \
40
+ zlib1g-dev \
41
+ libyaml-dev \
42
+ libffi-dev \
43
+ libncurses-dev \
44
+ aspell \
45
+ aspell-en \
46
+ aspell-fr \
47
+ && apt-get clean && rm -rf /var/lib/apt/lists/*
48
+
49
+ # Configure locale
50
+ RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && \
51
+ locale-gen en_US.UTF-8
52
+
53
+ ENV LANG=en_US.UTF-8
54
+ ENV LC_ALL=en_US.UTF-8
55
+
56
+ # Ensure default node user has access to /usr/local/share
57
+ RUN mkdir -p /usr/local/share/npm-global && \
58
+ chown -R node:node /usr/local/share
59
+
60
+ ARG USERNAME=node
61
+
62
+ # Persist bash history.
63
+ RUN SNIPPET="export PROMPT_COMMAND='history -a' && export HISTFILE=/commandhistory/.bash_history" \
64
+ && mkdir /commandhistory \
65
+ && touch /commandhistory/.bash_history \
66
+ && chown -R $USERNAME /commandhistory
67
+
68
+ # Set `DEVCONTAINER` environment variable to help with orientation
69
+ ENV DEVCONTAINER=true
70
+
71
+ # Create workspace and config directories and set permissions
72
+ RUN mkdir -p /workspace /home/node/.claude /home/node/.config/gh && \
73
+ chown -R node:node /workspace /home/node/.claude /home/node/.config/gh
74
+
75
+ WORKDIR /workspace
76
+
77
+ ARG GIT_DELTA_VERSION=0.18.2
78
+ RUN ARCH=$(dpkg --print-architecture) && \
79
+ wget "https://github.com/dandavison/delta/releases/download/${GIT_DELTA_VERSION}/git-delta_${GIT_DELTA_VERSION}_${ARCH}.deb" && \
80
+ sudo dpkg -i "git-delta_${GIT_DELTA_VERSION}_${ARCH}.deb" && \
81
+ rm "git-delta_${GIT_DELTA_VERSION}_${ARCH}.deb"
82
+
83
+ # Set up non-root user
84
+ USER node
85
+
86
+ # Install rbenv and ruby-build
87
+ ARG RUBY_VERSION=4.0.1
88
+ RUN git clone https://github.com/rbenv/rbenv.git ~/.rbenv && \
89
+ git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build && \
90
+ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.zshrc && \
91
+ echo 'eval "$(rbenv init - zsh)"' >> ~/.zshrc && \
92
+ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc && \
93
+ echo 'eval "$(rbenv init - bash)"' >> ~/.bashrc
94
+
95
+ # Install Ruby
96
+ ENV PATH="/home/node/.rbenv/bin:/home/node/.rbenv/shims:$PATH"
97
+ RUN rbenv install ${RUBY_VERSION} && \
98
+ rbenv global ${RUBY_VERSION} && \
99
+ gem install bundler
100
+
101
+ # Install global packages
102
+ ENV NPM_CONFIG_PREFIX=/usr/local/share/npm-global
103
+ ENV PATH=$PATH:/usr/local/share/npm-global/bin
104
+
105
+ # Set the default shell to zsh rather than sh
106
+ ENV SHELL=/bin/zsh
107
+
108
+ # Set the default editor and visual
109
+ ENV EDITOR=nano
110
+ ENV VISUAL=nano
111
+
112
+ # Default powerline10k theme
113
+ ARG ZSH_IN_DOCKER_VERSION=1.2.0
114
+ RUN sh -c "$(wget -O- https://github.com/deluan/zsh-in-docker/releases/download/v${ZSH_IN_DOCKER_VERSION}/zsh-in-docker.sh)" -- \
115
+ -p git \
116
+ -p fzf \
117
+ -a "source /usr/share/doc/fzf/examples/key-bindings.zsh" \
118
+ -a "source /usr/share/doc/fzf/examples/completion.zsh" \
119
+ -a "export PROMPT_COMMAND='history -a' && export HISTFILE=/commandhistory/.bash_history" \
120
+ -x
121
+
122
+ # Install Claude
123
+ RUN curl -fsSL https://claude.ai/install.sh | bash
124
+
125
+
126
+ # Copy and set up firewall script
127
+ COPY init-firewall.sh /usr/local/bin/
128
+ USER root
129
+ RUN chmod +x /usr/local/bin/init-firewall.sh && \
130
+ echo "node ALL=(root) NOPASSWD: /usr/local/bin/init-firewall.sh" > /etc/sudoers.d/node-firewall && \
131
+ chmod 0440 /etc/sudoers.d/node-firewall
132
+ USER node
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "Claude Code Sandbox",
3
+ "build": {
4
+ "dockerfile": "Dockerfile",
5
+ "args": {
6
+ "TZ": "${localEnv:TZ:America/Los_Angeles}",
7
+ "CLAUDE_CODE_VERSION": "latest",
8
+ "GIT_DELTA_VERSION": "0.18.2",
9
+ "ZSH_IN_DOCKER_VERSION": "1.2.0"
10
+ }
11
+ },
12
+ "runArgs": [
13
+ "--cap-add=NET_ADMIN",
14
+ "--cap-add=NET_RAW"
15
+ ],
16
+ "customizations": {
17
+ "vscode": {
18
+ "extensions": [
19
+ "anthropic.claude-code",
20
+ "dbaeumer.vscode-eslint",
21
+ "esbenp.prettier-vscode",
22
+ "eamodio.gitlens"
23
+ ],
24
+ "settings": {
25
+ "editor.formatOnSave": true,
26
+ "editor.defaultFormatter": "esbenp.prettier-vscode",
27
+ "editor.codeActionsOnSave": {
28
+ "source.fixAll.eslint": "explicit"
29
+ },
30
+ "terminal.integrated.defaultProfile.linux": "zsh",
31
+ "terminal.integrated.profiles.linux": {
32
+ "bash": {
33
+ "path": "bash",
34
+ "icon": "terminal-bash"
35
+ },
36
+ "zsh": {
37
+ "path": "zsh"
38
+ }
39
+ }
40
+ }
41
+ }
42
+ },
43
+ "remoteUser": "node",
44
+ "mounts": [
45
+ "source=claude-code-bashhistory-${devcontainerId},target=/commandhistory,type=volume",
46
+ "source=claude-code-config,target=/home/node/.claude,type=volume",
47
+ "source=claude-code-gh-config,target=/home/node/.config/gh,type=volume"
48
+ ],
49
+ "containerEnv": {
50
+ "NODE_OPTIONS": "--max-old-space-size=4096",
51
+ "CLAUDE_CONFIG_DIR": "/home/node/.claude",
52
+ "POWERLEVEL9K_DISABLE_GITSTATUS": "true"
53
+ },
54
+ "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind,consistency=delegated",
55
+ "workspaceFolder": "/workspace",
56
+ "postStartCommand": "sudo /usr/local/bin/init-firewall.sh",
57
+ "waitFor": "postStartCommand"
58
+ }
@@ -0,0 +1,139 @@
1
+ #!/bin/bash
2
+ set -euo pipefail # Exit on error, undefined vars, and pipeline failures
3
+ IFS=$'\n\t' # Stricter word splitting
4
+
5
+ # 1. Extract Docker DNS info BEFORE any flushing
6
+ DOCKER_DNS_RULES=$(iptables-save -t nat | grep "127\.0\.0\.11" || true)
7
+
8
+ # Flush existing rules and delete existing ipsets
9
+ iptables -F
10
+ iptables -X
11
+ iptables -t nat -F
12
+ iptables -t nat -X
13
+ iptables -t mangle -F
14
+ iptables -t mangle -X
15
+ ipset destroy allowed-domains 2>/dev/null || true
16
+
17
+ # 2. Selectively restore ONLY internal Docker DNS resolution
18
+ if [ -n "$DOCKER_DNS_RULES" ]; then
19
+ echo "Restoring Docker DNS rules..."
20
+ iptables -t nat -N DOCKER_OUTPUT 2>/dev/null || true
21
+ iptables -t nat -N DOCKER_POSTROUTING 2>/dev/null || true
22
+ echo "$DOCKER_DNS_RULES" | xargs -L 1 iptables -t nat
23
+ else
24
+ echo "No Docker DNS rules to restore"
25
+ fi
26
+
27
+ # First allow DNS and localhost before any restrictions
28
+ # Allow outbound DNS
29
+ iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
30
+ # Allow inbound DNS responses
31
+ iptables -A INPUT -p udp --sport 53 -j ACCEPT
32
+ # Allow outbound SSH
33
+ iptables -A OUTPUT -p tcp --dport 22 -j ACCEPT
34
+ # Allow inbound SSH responses
35
+ iptables -A INPUT -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
36
+ # Allow localhost
37
+ iptables -A INPUT -i lo -j ACCEPT
38
+ iptables -A OUTPUT -o lo -j ACCEPT
39
+
40
+ # Create ipset with CIDR support
41
+ ipset create allowed-domains hash:net
42
+
43
+ # Fetch GitHub meta information and aggregate + add their IP ranges
44
+ echo "Fetching GitHub IP ranges..."
45
+ gh_ranges=$(curl -s https://api.github.com/meta)
46
+ if [ -z "$gh_ranges" ]; then
47
+ echo "ERROR: Failed to fetch GitHub IP ranges"
48
+ exit 1
49
+ fi
50
+
51
+ if ! echo "$gh_ranges" | jq -e '.web and .api and .git' >/dev/null; then
52
+ echo "ERROR: GitHub API response missing required fields"
53
+ exit 1
54
+ fi
55
+
56
+ echo "Processing GitHub IPs..."
57
+ while read -r cidr; do
58
+ if [[ ! "$cidr" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/[0-9]{1,2}$ ]]; then
59
+ echo "ERROR: Invalid CIDR range from GitHub meta: $cidr"
60
+ exit 1
61
+ fi
62
+ echo "Adding GitHub range $cidr"
63
+ ipset add allowed-domains "$cidr"
64
+ done < <(echo "$gh_ranges" | jq -r '(.web + .api + .git)[]' | aggregate -q)
65
+
66
+ # Resolve and add other allowed domains
67
+ for domain in \
68
+ "storage.googleapis.com" \
69
+ "registry.npmjs.org" \
70
+ "api.anthropic.com" \
71
+ "sentry.io" \
72
+ "statsig.anthropic.com" \
73
+ "statsig.com" \
74
+ "marketplace.visualstudio.com" \
75
+ "vscode.blob.core.windows.net" \
76
+ "update.code.visualstudio.com" \
77
+ "rubygems.org"; do
78
+ echo "Resolving $domain..."
79
+ ips=$(dig +noall +answer A "$domain" | awk '$4 == "A" {print $5}')
80
+ if [ -z "$ips" ]; then
81
+ echo "ERROR: Failed to resolve $domain"
82
+ exit 1
83
+ fi
84
+
85
+ while read -r ip; do
86
+ if [[ ! "$ip" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
87
+ echo "ERROR: Invalid IP from DNS for $domain: $ip"
88
+ exit 1
89
+ fi
90
+ echo "Adding $ip for $domain"
91
+ ipset add allowed-domains "$ip"
92
+ done < <(echo "$ips")
93
+ done
94
+
95
+ # Get host IP from default route
96
+ HOST_IP=$(ip route | grep default | cut -d" " -f3)
97
+ if [ -z "$HOST_IP" ]; then
98
+ echo "ERROR: Failed to detect host IP"
99
+ exit 1
100
+ fi
101
+
102
+ HOST_NETWORK=$(echo "$HOST_IP" | sed "s/\.[0-9]*$/.0\/24/")
103
+ echo "Host network detected as: $HOST_NETWORK"
104
+
105
+ # Set up remaining iptables rules
106
+ iptables -A INPUT -s "$HOST_NETWORK" -j ACCEPT
107
+ iptables -A OUTPUT -d "$HOST_NETWORK" -j ACCEPT
108
+
109
+ # Set default policies to DROP first
110
+ iptables -P INPUT DROP
111
+ iptables -P FORWARD DROP
112
+ iptables -P OUTPUT DROP
113
+
114
+ # First allow established connections for already approved traffic
115
+ iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
116
+ iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
117
+
118
+ # Then allow only specific outbound traffic to allowed domains
119
+ iptables -A OUTPUT -m set --match-set allowed-domains dst -j ACCEPT
120
+
121
+ # Explicitly REJECT all other outbound traffic for immediate feedback
122
+ iptables -A OUTPUT -j REJECT --reject-with icmp-admin-prohibited
123
+
124
+ echo "Firewall configuration complete"
125
+ echo "Verifying firewall rules..."
126
+ if curl --connect-timeout 5 https://example.com >/dev/null 2>&1; then
127
+ echo "ERROR: Firewall verification failed - was able to reach https://example.com"
128
+ exit 1
129
+ else
130
+ echo "Firewall verification passed - unable to reach https://example.com as expected"
131
+ fi
132
+
133
+ # Verify GitHub API access
134
+ if ! curl --connect-timeout 5 https://api.github.com/zen >/dev/null 2>&1; then
135
+ echo "ERROR: Firewall verification failed - unable to reach https://api.github.com"
136
+ exit 1
137
+ else
138
+ echo "Firewall verification passed - able to reach https://api.github.com as expected"
139
+ fi
@@ -19,7 +19,7 @@ jobs:
19
19
  runs-on: ubuntu-latest
20
20
  steps:
21
21
  - name: Checkout
22
- uses: actions/checkout@v6
22
+ uses: actions/checkout@v7
23
23
  - name: Setup Ruby
24
24
  uses: ruby/setup-ruby@a4effe49ee8ee5b8b5091268c473a4628afb5651 # v1.245.0
25
25
  with:
@@ -27,14 +27,14 @@ jobs:
27
27
  bundler-cache: true
28
28
  - name: Setup Pages
29
29
  id: pages
30
- uses: actions/configure-pages@v5
30
+ uses: actions/configure-pages@v6
31
31
  - name: Install dependencies
32
32
  run: gem install rdoc
33
33
  - name: Build with RDoc
34
34
  # Outputs to the './_site' directory by default
35
35
  run: rake rdoc
36
36
  - name: Upload artifact
37
- uses: actions/upload-pages-artifact@v4
37
+ uses: actions/upload-pages-artifact@v5
38
38
 
39
39
  deploy:
40
40
  environment:
@@ -45,4 +45,4 @@ jobs:
45
45
  steps:
46
46
  - name: Deploy to GitHub Pages
47
47
  id: deployment
48
- uses: actions/deploy-pages@v4
48
+ uses: actions/deploy-pages@v5
@@ -1,12 +1,15 @@
1
1
  name: macos
2
2
 
3
- on: [push]
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
4
7
 
5
8
  jobs:
6
9
  build:
7
10
  runs-on: macos-latest
8
11
  steps:
9
- - uses: actions/checkout@v6
12
+ - uses: actions/checkout@v7
10
13
  - uses: ruby/setup-ruby@v1
11
14
  with:
12
15
  ruby-version: 3.4
@@ -24,11 +24,11 @@ jobs:
24
24
  steps:
25
25
  # Set up
26
26
  - name: Harden Runner
27
- uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
27
+ uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0
28
28
  with:
29
29
  egress-policy: audit
30
30
 
31
- - uses: actions/checkout@v6
31
+ - uses: actions/checkout@v7
32
32
  with:
33
33
  submodules: true
34
34
 
@@ -38,6 +38,11 @@ jobs:
38
38
  bundler-cache: true
39
39
  ruby-version: ruby
40
40
 
41
+ # Prevent `git fetch --tags` in release-gem from fetching submodule
42
+ # commits unreachable in the current submodule remote
43
+ - name: Disable submodule fetch recursion
44
+ run: git config fetch.recurseSubmodules false
45
+
41
46
  # Release
42
47
  - name: Publish to RubyGems
43
48
  uses: rubygems/release-gem@v1
@@ -1,6 +1,9 @@
1
1
  name: ubuntu
2
2
 
3
- on: [push]
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
4
7
 
5
8
  jobs:
6
9
  test:
@@ -9,7 +12,7 @@ jobs:
9
12
  ruby: [ head, 3.4, 3.3, 3.2 ]
10
13
  runs-on: ubuntu-latest
11
14
  steps:
12
- - uses: actions/checkout@v6
15
+ - uses: actions/checkout@v7
13
16
  - uses: ruby/setup-ruby@v1
14
17
  with:
15
18
  ruby-version: ${{ matrix.ruby }}
@@ -1,6 +1,9 @@
1
1
  name: windows
2
2
 
3
- on: [push]
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
4
7
 
5
8
  jobs:
6
9
  build:
@@ -9,7 +12,7 @@ jobs:
9
12
  matrix:
10
13
  ruby: [ 'mingw', 'mswin', '3.4' ]
11
14
  steps:
12
- - uses: actions/checkout@v6
15
+ - uses: actions/checkout@v7
13
16
  with:
14
17
  submodules: true
15
18
  - name: Set up Ruby
data/curses.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new { |s|
2
2
  s.name = "curses"
3
- s.version = "1.6.0"
3
+ s.version = "1.6.1"
4
4
  s.author = ["Shugo Maeda", 'Eric Hodel']
5
5
  s.email = ["shugo@ruby-lang.org", 'drbrain@segment7.net']
6
6
  s.homepage = "https://github.com/ruby/curses"
@@ -68,7 +68,7 @@ if $use_bundled_pdcurses
68
68
  $pdcurses_dll_default = true
69
69
  else
70
70
  w64 = $x64 ? "_w64=1" : ""
71
- exec_command "make -f Makefile.mng clean all #{w64} WIDE=Y DLL=N CC=\"gcc -std=gnu17\""
71
+ exec_command "make -f Makefile.mng clean libs #{w64} WIDE=Y DLL=N CC=\"gcc -std=gnu17\""
72
72
  FileUtils.cp("pdcurses.a", File.expand_path("libpdcurses.a", pdcurses_dir))
73
73
  end
74
74
  ensure
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: curses
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.0
4
+ version: 1.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shugo Maeda
@@ -46,6 +46,9 @@ extensions:
46
46
  - ext/curses/extconf.rb
47
47
  extra_rdoc_files: []
48
48
  files:
49
+ - ".devcontainer/Dockerfile"
50
+ - ".devcontainer/devcontainer.json"
51
+ - ".devcontainer/init-firewall.sh"
49
52
  - ".github/dependabot.yml"
50
53
  - ".github/release.yml"
51
54
  - ".github/workflows/gh-pages.yml"
@@ -345,7 +348,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
345
348
  - !ruby/object:Gem::Version
346
349
  version: '0'
347
350
  requirements: []
348
- rubygems_version: 4.0.3
351
+ rubygems_version: 4.0.16
349
352
  specification_version: 4
350
353
  summary: A Ruby binding for curses, ncurses, and PDCurses. curses is an extension
351
354
  library for text UI applications. Formerly part of the Ruby standard library, [curses