arg-dashboard 0.1.19__tar.gz

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 (78) hide show
  1. arg_dashboard-0.1.19/.devcontainer/Dockerfile +103 -0
  2. arg_dashboard-0.1.19/.devcontainer/README.md +135 -0
  3. arg_dashboard-0.1.19/.devcontainer/devcontainer.json +110 -0
  4. arg_dashboard-0.1.19/.devcontainer/init-firewall.sh +157 -0
  5. arg_dashboard-0.1.19/.devcontainer/mcp-setup/generate-config.sh +210 -0
  6. arg_dashboard-0.1.19/.devcontainer/mcp-setup/install.sh +109 -0
  7. arg_dashboard-0.1.19/.devcontainer/mcp-setup/pixi.toml +89 -0
  8. arg_dashboard-0.1.19/.devcontainer/mcp-setup/servers.txt +19 -0
  9. arg_dashboard-0.1.19/.devcontainer/mcp-setup/test-servers.sh +47 -0
  10. arg_dashboard-0.1.19/.gitattributes +4 -0
  11. arg_dashboard-0.1.19/.github/workflows/conda-release.yml +107 -0
  12. arg_dashboard-0.1.19/.github/workflows/pypi-release.yml +144 -0
  13. arg_dashboard-0.1.19/.github/workflows/quarto-publish.yml +68 -0
  14. arg_dashboard-0.1.19/.gitignore +147 -0
  15. arg_dashboard-0.1.19/.vscode/vscode.css +4 -0
  16. arg_dashboard-0.1.19/CHANGELOG.md +0 -0
  17. arg_dashboard-0.1.19/CLAUDE.md +213 -0
  18. arg_dashboard-0.1.19/LICENSE +674 -0
  19. arg_dashboard-0.1.19/PKG-INFO +88 -0
  20. arg_dashboard-0.1.19/README.md +58 -0
  21. arg_dashboard-0.1.19/_quarto.yml +67 -0
  22. arg_dashboard-0.1.19/conda-build/README.md +22 -0
  23. arg_dashboard-0.1.19/conda-build/build_env.yaml +7 -0
  24. arg_dashboard-0.1.19/conda-build/meta.yaml +45 -0
  25. arg_dashboard-0.1.19/data/data_table.csv +25 -0
  26. arg_dashboard-0.1.19/docs/.gitignore +3 -0
  27. arg_dashboard-0.1.19/docs/README.md +21 -0
  28. arg_dashboard-0.1.19/docs/_extensions/machow/interlinks/.gitignore +3 -0
  29. arg_dashboard-0.1.19/docs/_extensions/machow/interlinks/_extension.yml +7 -0
  30. arg_dashboard-0.1.19/docs/_extensions/machow/interlinks/interlinks.lua +254 -0
  31. arg_dashboard-0.1.19/docs/_inv/griffe_objects.txt +6689 -0
  32. arg_dashboard-0.1.19/docs/_inv/numpy_objects.txt +8460 -0
  33. arg_dashboard-0.1.19/docs/_inv/python_objects.txt +18353 -0
  34. arg_dashboard-0.1.19/docs/_quarto.yml +103 -0
  35. arg_dashboard-0.1.19/docs/api/_sidebar.yml +9 -0
  36. arg_dashboard-0.1.19/docs/api/_styles-quartodoc.css +22 -0
  37. arg_dashboard-0.1.19/docs/api/app.qmd +4 -0
  38. arg_dashboard-0.1.19/docs/api/functionname.qmd +35 -0
  39. arg_dashboard-0.1.19/docs/api/index.qmd +10 -0
  40. arg_dashboard-0.1.19/docs/api/scriptname.qmd +6 -0
  41. arg_dashboard-0.1.19/docs/autodoc.mustache +44 -0
  42. arg_dashboard-0.1.19/docs/custom.scss +4 -0
  43. arg_dashboard-0.1.19/docs/objects.txt +5 -0
  44. arg_dashboard-0.1.19/docs/pages/example.ipynb +5104 -0
  45. arg_dashboard-0.1.19/docs/pages/overview.ipynb +131 -0
  46. arg_dashboard-0.1.19/docs/styles.css +115 -0
  47. arg_dashboard-0.1.19/notebooks/README.md +6 -0
  48. arg_dashboard-0.1.19/notebooks/tester.ipynb +61 -0
  49. arg_dashboard-0.1.19/pixi.lock +6379 -0
  50. arg_dashboard-0.1.19/pyproject.toml +141 -0
  51. arg_dashboard-0.1.19/scripts/bump_changelog.py +343 -0
  52. arg_dashboard-0.1.19/scripts/bump_version.py +119 -0
  53. arg_dashboard-0.1.19/scripts/docs-build-render.sh +8 -0
  54. arg_dashboard-0.1.19/scripts/docs-run-notebooks.sh +26 -0
  55. arg_dashboard-0.1.19/scripts/git-commit.sh +115 -0
  56. arg_dashboard-0.1.19/scripts/github-release.sh +52 -0
  57. arg_dashboard-0.1.19/scripts/rename.py +137 -0
  58. arg_dashboard-0.1.19/scripts/tmux-project.sh +172 -0
  59. arg_dashboard-0.1.19/setup.cfg +4 -0
  60. arg_dashboard-0.1.19/src/arg_dashboard/__init__.py +934 -0
  61. arg_dashboard-0.1.19/src/arg_dashboard/arg.py +1019 -0
  62. arg_dashboard-0.1.19/src/arg_dashboard/arg_layout_force.py +365 -0
  63. arg_dashboard-0.1.19/src/arg_dashboard/arg_layout_json.py +269 -0
  64. arg_dashboard-0.1.19/src/arg_dashboard/arg_layout_mindist.py +412 -0
  65. arg_dashboard-0.1.19/src/arg_dashboard/assets/dashboard.css +139 -0
  66. arg_dashboard-0.1.19/src/arg_dashboard/assets/images/arg.png +0 -0
  67. arg_dashboard-0.1.19/src/arg_dashboard/assets/images/placeholder286x180.png +0 -0
  68. arg_dashboard-0.1.19/src/arg_dashboard/assets/tabs.css +34 -0
  69. arg_dashboard-0.1.19/src/arg_dashboard/index.py +6 -0
  70. arg_dashboard-0.1.19/src/arg_dashboard.egg-info/PKG-INFO +88 -0
  71. arg_dashboard-0.1.19/src/arg_dashboard.egg-info/SOURCES.txt +76 -0
  72. arg_dashboard-0.1.19/src/arg_dashboard.egg-info/dependency_links.txt +1 -0
  73. arg_dashboard-0.1.19/src/arg_dashboard.egg-info/entry_points.txt +2 -0
  74. arg_dashboard-0.1.19/src/arg_dashboard.egg-info/requires.txt +14 -0
  75. arg_dashboard-0.1.19/src/arg_dashboard.egg-info/top_level.txt +1 -0
  76. arg_dashboard-0.1.19/test/__init__.py +0 -0
  77. arg_dashboard-0.1.19/test/test_dummy.py +104 -0
  78. arg_dashboard-0.1.19/test/test_modulename.py +13 -0
@@ -0,0 +1,103 @@
1
+ FROM node:20
2
+
3
+ ARG TZ
4
+ ENV TZ="$TZ"
5
+
6
+ ARG CLAUDE_CODE_VERSION=latest
7
+
8
+ # Install basic development tools and iptables/ipset
9
+ RUN apt-get update && apt-get install -y --no-install-recommends \
10
+ less \
11
+ git \
12
+ procps \
13
+ sudo \
14
+ fzf \
15
+ zsh \
16
+ man-db \
17
+ unzip \
18
+ gnupg2 \
19
+ gh \
20
+ iptables \
21
+ ipset \
22
+ iproute2 \
23
+ dnsutils \
24
+ aggregate \
25
+ jq \
26
+ nano \
27
+ vim \
28
+ && apt-get clean && rm -rf /var/lib/apt/lists/*
29
+
30
+ # Ensure default node user has access to /usr/local/share
31
+ RUN mkdir -p /usr/local/share/npm-global && \
32
+ chown -R node:node /usr/local/share
33
+
34
+ ARG USERNAME=node
35
+
36
+ # Persist bash history.
37
+ RUN SNIPPET="export PROMPT_COMMAND='history -a' && export HISTFILE=/commandhistory/.bash_history" \
38
+ && mkdir /commandhistory \
39
+ && touch /commandhistory/.bash_history \
40
+ && chown -R $USERNAME /commandhistory
41
+
42
+ # Set `DEVCONTAINER` environment variable to help with orientation
43
+ ENV DEVCONTAINER=true
44
+
45
+ # Create workspace and config directories and set permissions
46
+ RUN mkdir -p /workspace /home/node/.claude /home/node/.local/mcp-servers /home/node/.config/claude /home/node/.pixi && \
47
+ chown -R node:node /workspace /home/node/.claude /home/node/.local /home/node/.config /home/node/.pixi
48
+
49
+ WORKDIR /workspace
50
+
51
+ ARG GIT_DELTA_VERSION=0.18.2
52
+ RUN ARCH=$(dpkg --print-architecture) && \
53
+ wget "https://github.com/dandavison/delta/releases/download/${GIT_DELTA_VERSION}/git-delta_${GIT_DELTA_VERSION}_${ARCH}.deb" && \
54
+ sudo dpkg -i "git-delta_${GIT_DELTA_VERSION}_${ARCH}.deb" && \
55
+ rm "git-delta_${GIT_DELTA_VERSION}_${ARCH}.deb"
56
+
57
+ # Set up non-root user
58
+ USER node
59
+
60
+ # Install global packages
61
+ ENV NPM_CONFIG_PREFIX=/usr/local/share/npm-global
62
+ ENV PATH=$PATH:/usr/local/share/npm-global/bin
63
+
64
+ # Set the default shell to zsh rather than sh
65
+ ENV SHELL=/bin/zsh
66
+
67
+ # Set the default editor and visual
68
+ ENV EDITOR=nano
69
+ ENV VISUAL=nano
70
+
71
+ # # Default powerline10k theme
72
+ # ARG ZSH_IN_DOCKER_VERSION=1.2.0
73
+ # RUN sh -c "$(wget -O- https://github.com/deluan/zsh-in-docker/releases/download/v${ZSH_IN_DOCKER_VERSION}/zsh-in-docker.sh)" -- \
74
+ # -p git \
75
+ # -p fzf \
76
+ # -a "source /usr/share/doc/fzf/examples/key-bindings.zsh" \
77
+ # -a "source /usr/share/doc/fzf/examples/completion.zsh" \
78
+ # -a "export PROMPT_COMMAND='history -a' && export HISTFILE=/commandhistory/.bash_history" \
79
+ # -x
80
+
81
+ # Install Claude
82
+ RUN npm install -g @anthropic-ai/claude-code@${CLAUDE_CODE_VERSION}
83
+
84
+
85
+ # Copy and set up firewall script
86
+ COPY init-firewall.sh /usr/local/bin/
87
+ USER root
88
+ RUN chmod +x /usr/local/bin/init-firewall.sh && \
89
+ echo "node ALL=(root) NOPASSWD: /usr/local/bin/init-firewall.sh" > /etc/sudoers.d/node-firewall && \
90
+ chmod 0440 /etc/sudoers.d/node-firewall
91
+ USER node
92
+
93
+ # Install pixi (conda-based package manager for MCP servers)
94
+ RUN curl -fsSL https://pixi.sh/install.sh | bash
95
+
96
+ # Install uv (Python package manager for pyproject.toml-based MCP servers)
97
+ RUN curl -LsSf https://astral.sh/uv/install.sh | bash
98
+
99
+ # Update PATH to include pixi, uv, and local binaries
100
+ ENV PATH="/home/node/.pixi/bin:/home/node/.cargo/bin:/home/node/.local/bin:${PATH}"
101
+
102
+ RUN echo 'eval "$(pixi/bin/pixi completion -s bash)"' >> /home/node/.bashrc
103
+ RUN echo 'eval "$(pixi/bin/pixi completion -s zsh)"' >> /home/node/.zshrc
@@ -0,0 +1,135 @@
1
+ # MCP Devcontainer Setup with Pixi
2
+
3
+ This devcontainer configuration sets up MCP (Model Context Protocol) servers using pixi for dependency management.
4
+
5
+ **Platform:** Linux-64 only (works on all Docker hosts, including Apple Silicon via Rosetta)
6
+
7
+ ## Quick Start
8
+
9
+ 1. Copy the `.devcontainer` folder to your project
10
+ 2. Open in VS Code and select "Reopen in Container"
11
+ 3. MCP servers will be installed automatically via `postCreateCommand`
12
+
13
+ ## Configuration
14
+
15
+ ### Choosing an Environment
16
+
17
+ Set `MCP_ENV` before building the container to choose which servers to install:
18
+
19
+ ```bash
20
+ # In devcontainer.json, modify containerEnv:
21
+ "containerEnv": {
22
+ "MCP_ENV": "research" # Options: minimal, default, research, full
23
+ }
24
+ ```
25
+
26
+ **Available environments:**
27
+ - `minimal` - Just filesystem server
28
+ - `default` - filesystem, memory, fetch
29
+ - `research` - filesystem, arxiv, fetch
30
+ - `full` - All servers
31
+
32
+ ### Adding New Servers
33
+
34
+ #### Option 1: Add to pixi.toml (recommended for PyPI/conda packages)
35
+
36
+ Edit `.devcontainer/mcp-setup/pixi.toml`:
37
+
38
+ ```toml
39
+ [feature.my-new-server]
40
+ [feature.my-new-server.pypi-dependencies]
41
+ my-new-mcp-server = "*"
42
+
43
+ # Or from git:
44
+ [feature.another-server]
45
+ [feature.another-server.pypi-dependencies]
46
+ another-server = { git = "https://github.com/user/repo.git" }
47
+ ```
48
+
49
+ Then add the feature to an environment:
50
+
51
+ ```toml
52
+ [environments]
53
+ default = { features = ["filesystem", "memory", "fetch", "my-new-server"], solve-group = "default" }
54
+ ```
55
+
56
+ And update `generate-config.sh` to include the new server mapping.
57
+
58
+ #### Option 2: Clone from git (supports both pixi.toml and pyproject.toml)
59
+
60
+ Add to `.devcontainer/mcp-setup/servers.txt`:
61
+
62
+ ```
63
+ my-server|git-clone|https://github.com/user/my-mcp-server.git|
64
+ ```
65
+
66
+ The setup automatically detects and handles:
67
+ - **pixi.toml**: Creates isolated conda environment via `pixi install`
68
+ - **pyproject.toml**: Installs in shared pixi environment via `pixi run pip install -e`
69
+ - Uses pixi's Python (includes development headers)
70
+ - Avoids missing `Python.h` compilation errors
71
+ - Better binary compatibility via conda-forge packages
72
+
73
+ ### Using the MCP Servers
74
+
75
+ After installation, the MCP config is at:
76
+ ```
77
+ ~/.config/claude/mcp_servers.json
78
+ ```
79
+
80
+ Wrapper scripts are at:
81
+ ```
82
+ ~/.local/mcp-servers/wrappers/
83
+ ```
84
+
85
+ ### Testing
86
+
87
+ Run the test script to verify all servers are working:
88
+
89
+ ```bash
90
+ bash .devcontainer/mcp-setup/test-servers.sh
91
+ ```
92
+
93
+ ### Regenerating Config
94
+
95
+ If you modify the setup, regenerate the config:
96
+
97
+ ```bash
98
+ cd ~/.local/mcp-servers
99
+ bash /workspace/.devcontainer/mcp-setup/generate-config.sh default
100
+ ```
101
+
102
+ ## File Structure
103
+
104
+ ```
105
+ .devcontainer/
106
+ ├── devcontainer.json # VS Code devcontainer config
107
+ ├── Dockerfile # Container image with pixi
108
+ └── mcp-setup/
109
+ ├── pixi.toml # MCP server dependencies
110
+ ├── install.sh # Main installation script
111
+ ├── generate-config.sh # Generates Claude MCP config
112
+ ├── test-servers.sh # Tests installed servers
113
+ └── servers.txt # Git repos to clone
114
+ ```
115
+
116
+ ## Troubleshooting
117
+
118
+ ### Servers not found
119
+
120
+ 1. Check that pixi installed correctly: `pixi --version`
121
+ 2. Verify the environment: `cd ~/.local/mcp-servers && pixi info`
122
+ 3. Check wrapper scripts exist: `ls ~/.local/mcp-servers/wrappers/`
123
+
124
+ ### Permission issues
125
+
126
+ The setup runs as the `vscode` user. All installations go to user-writable directories:
127
+ - `~/.local/mcp-servers/`
128
+ - `~/.config/claude/`
129
+ - `~/.pixi/`
130
+
131
+ ### Dependency conflicts
132
+
133
+ If servers have conflicting dependencies, consider:
134
+ 1. Using separate pixi environments per server
135
+ 2. Installing conflicting servers via `servers.txt` with their own pixi.toml
@@ -0,0 +1,110 @@
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
+ // "context": "..",
12
+ "options": ["--platform=linux/amd64"]
13
+ },
14
+ "runArgs": [
15
+ "--cap-add=NET_ADMIN",
16
+ "--cap-add=NET_RAW",
17
+ "--platform=linux/amd64"
18
+ ],
19
+ // "runArgs": ["--cap-add=NET_ADMIN", "--cap-add=NET_RAW"],
20
+ "features": {
21
+ "ghcr.io/devcontainers/features/common-utils:2": {
22
+ "installZsh": true,
23
+ "configureZshAsDefaultShell": true,
24
+ "installOhMyZsh": true
25
+ }
26
+ },
27
+ "customizations": {
28
+ "vscode": {
29
+ "extensions": [
30
+ "anthropic.claude-code",
31
+ "dbaeumer.vscode-eslint",
32
+ "esbenp.prettier-vscode",
33
+ "eamodio.gitlens",
34
+ "be5invis.toml",
35
+ "ms-vscode.cpptools-",
36
+ "ms-toolsai.jupyter-",
37
+ "reditorsupport.r-syntax",
38
+ "dnut.rewrap-revived",
39
+ "ms-vscode.vscode-speech",
40
+ "njpwerner.autodocst",
41
+ "samuelcolvin.jinjah",
42
+ "ms-vscode.cpptools",
43
+ "ms-vscode.cmake-tools",
44
+ "vadimcn.vscode-lldb",
45
+ "streetsidesoftware.code-spell-checker",
46
+ "howardzuo.vscode-favorites",
47
+ "mhutchie.git-graph",
48
+ "github.vscode-github-actions",
49
+ "github.vscode-pull-request-github",
50
+ // "ms-python.isort",
51
+ "ms-toolsai.jupyter",
52
+ "ms-toolsai.vscode-jupyter-cell-tags",
53
+ "ms-toolsai.jupyter-renderers",
54
+ "james-yu.latex-workshop",
55
+ "sumneko.lua",
56
+ "yzhang.markdown-all-in-one",
57
+ "takumii.markdownt",
58
+ "webfreak.debug",
59
+ "ms-python.vscode-pylance",
60
+ "ms-python.python",
61
+ "ms-python.debugpy",
62
+ "ms-python.vscode-python-envs",
63
+ "quarto.quarto",
64
+ "reditorsupport.r",
65
+ "mechatroner.rainbow-csv",
66
+ "redhat.vscode-yaml",
67
+ "charliermarsh.ruff",
68
+ "tamasfe.even-better-toml"
69
+ ],
70
+ "settings": {
71
+ "editor.formatOnSave": true,
72
+ "editor.defaultFormatter": "esbenp.prettier-vscode",
73
+ "editor.codeActionsOnSave": {
74
+ "source.fixAll.eslint": "explicit"
75
+ },
76
+ "terminal.integrated.defaultProfile.linux": "zsh",
77
+ "terminal.integrated.profiles.linux": {
78
+ "bash": {
79
+ "path": "bash",
80
+ "icon": "terminal-bash"
81
+ },
82
+ "zsh": {
83
+ "path": "zsh"
84
+ }
85
+ }
86
+ }
87
+ }
88
+ },
89
+ // "postCreateCommand": "pixi config set --local run-post-link-scripts insecure && /workspace/.devcontainer/mcp-setup/install.sh",
90
+ "postCreateCommand": "/workspace/.devcontainer/mcp-setup/install.sh",
91
+ "remoteUser": "node",
92
+ "mounts": [
93
+ "source=claude-code-bashhistory-${devcontainerId},target=/commandhistory,type=volume",
94
+ "source=claude-code-config-${devcontainerId},target=/home/node/.claude,type=volume"
95
+ ],
96
+ "containerEnv": {
97
+ "NODE_OPTIONS": "--max-old-space-size=4096",
98
+ "CLAUDE_CONFIG_DIR": "/home/node/.claude",
99
+ "POWERLEVEL9K_DISABLE_GITSTATUS": "true",
100
+ "PIXI_HOME": "/home/node/.pixi",
101
+ "MCP_SERVERS_DIR": "/home/node/.local/mcp-servers"
102
+ },
103
+ "remoteEnv": {
104
+ "PATH": "${containerEnv:PATH}:/home/node/.pixi/bin:/home/node/.cargo/bin:/home/node/.local/bin"
105
+ },
106
+ "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind,consistency=delegated",
107
+ "workspaceFolder": "/workspace",
108
+ "postStartCommand": "sudo /usr/local/bin/init-firewall.sh",
109
+ "waitFor": "postStartCommand"
110
+ }
@@ -0,0 +1,157 @@
1
+ #!/bin/bash
2
+ # set -euo pipefail # Exit on error, undefined vars, and pipeline failures
3
+ # IFS=$'\n\t' # Stricter word splitting
4
+
5
+ # =============================================================================
6
+ # FIREWALL DISABLED
7
+ # =============================================================================
8
+ # The IP-based whitelist approach is incompatible with Claude Code's WebSearch
9
+ # and WebFetch tools, which need general internet access.
10
+ #
11
+ # Docker/devcontainer already provides sufficient compartmentalization:
12
+ # - Claude can only access mounted paths (/workspace, /commandhistory, ~/.claude)
13
+ # - No access to host filesystem, other containers, or host processes
14
+ #
15
+ # To re-enable the firewall, uncomment the code below.
16
+ # =============================================================================
17
+
18
+ echo "Firewall disabled - relying on Docker container isolation"
19
+ exit 0
20
+
21
+ # # 1. Extract Docker DNS info BEFORE any flushing
22
+ # DOCKER_DNS_RULES=$(iptables-save -t nat | grep "127\.0\.0\.11" || true)
23
+ #
24
+ # # Flush existing rules and delete existing ipsets
25
+ # iptables -F
26
+ # iptables -X
27
+ # iptables -t nat -F
28
+ # iptables -t nat -X
29
+ # iptables -t mangle -F
30
+ # iptables -t mangle -X
31
+ # ipset destroy allowed-domains 2>/dev/null || true
32
+ #
33
+ # # 2. Selectively restore ONLY internal Docker DNS resolution
34
+ # if [ -n "$DOCKER_DNS_RULES" ]; then
35
+ # echo "Restoring Docker DNS rules..."
36
+ # iptables -t nat -N DOCKER_OUTPUT 2>/dev/null || true
37
+ # iptables -t nat -N DOCKER_POSTROUTING 2>/dev/null || true
38
+ # echo "$DOCKER_DNS_RULES" | xargs -L 1 iptables -t nat
39
+ # else
40
+ # echo "No Docker DNS rules to restore"
41
+ # fi
42
+ #
43
+ # # First allow DNS and localhost before any restrictions
44
+ # # Allow outbound DNS
45
+ # iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
46
+ # # Allow inbound DNS responses
47
+ # iptables -A INPUT -p udp --sport 53 -j ACCEPT
48
+ # # Allow outbound SSH
49
+ # iptables -A OUTPUT -p tcp --dport 22 -j ACCEPT
50
+ # # Allow inbound SSH responses
51
+ # iptables -A INPUT -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
52
+ # # Allow localhost
53
+ # iptables -A INPUT -i lo -j ACCEPT
54
+ # iptables -A OUTPUT -o lo -j ACCEPT
55
+ #
56
+ # # Create ipset with CIDR support
57
+ # ipset create allowed-domains hash:net
58
+ #
59
+ # # Fetch GitHub meta information and aggregate + add their IP ranges
60
+ # echo "Fetching GitHub IP ranges..."
61
+ # gh_ranges=$(curl -s https://api.github.com/meta)
62
+ # if [ -z "$gh_ranges" ]; then
63
+ # echo "ERROR: Failed to fetch GitHub IP ranges"
64
+ # exit 1
65
+ # fi
66
+ #
67
+ # if ! echo "$gh_ranges" | jq -e '.web and .api and .git' >/dev/null; then
68
+ # echo "ERROR: GitHub API response missing required fields"
69
+ # exit 1
70
+ # fi
71
+ #
72
+ # echo "Processing GitHub IPs..."
73
+ # while read -r cidr; do
74
+ # if [[ ! "$cidr" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/[0-9]{1,2}$ ]]; then
75
+ # echo "ERROR: Invalid CIDR range from GitHub meta: $cidr"
76
+ # exit 1
77
+ # fi
78
+ # echo "Adding GitHub range $cidr"
79
+ # ipset add allowed-domains "$cidr"
80
+ # done < <(echo "$gh_ranges" | jq -r '(.web + .api + .git)[]' | aggregate -q)
81
+ #
82
+ # # Resolve and add other allowed domains
83
+ # for domain in \
84
+ # "registry.npmjs.org" \
85
+ # "api.anthropic.com" \
86
+ # "sentry.io" \
87
+ # "statsig.anthropic.com" \
88
+ # "statsig.com" \
89
+ # "marketplace.visualstudio.com" \
90
+ # "vscode.blob.core.windows.net" \
91
+ # "update.code.visualstudio.com" \
92
+ # "conda.anaconda.org" \
93
+ # "repo.anaconda.com" \
94
+ # "pypi.org" \
95
+ # "files.pythonhosted.org"; do
96
+ # echo "Resolving $domain..."
97
+ # ips=$(dig +noall +answer A "$domain" | awk '$4 == "A" {print $5}')
98
+ # if [ -z "$ips" ]; then
99
+ # echo "ERROR: Failed to resolve $domain"
100
+ # exit 1
101
+ # fi
102
+ #
103
+ # while read -r ip; do
104
+ # if [[ ! "$ip" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
105
+ # echo "ERROR: Invalid IP from DNS for $domain: $ip"
106
+ # exit 1
107
+ # fi
108
+ # echo "Adding $ip for $domain"
109
+ # ipset add allowed-domains "$ip"
110
+ # done < <(echo "$ips")
111
+ # done
112
+ #
113
+ # # Get host IP from default route
114
+ # HOST_IP=$(ip route | grep default | cut -d" " -f3)
115
+ # if [ -z "$HOST_IP" ]; then
116
+ # echo "ERROR: Failed to detect host IP"
117
+ # exit 1
118
+ # fi
119
+ #
120
+ # HOST_NETWORK=$(echo "$HOST_IP" | sed "s/\.[0-9]*$/.0\/24/")
121
+ # echo "Host network detected as: $HOST_NETWORK"
122
+ #
123
+ # # Set up remaining iptables rules
124
+ # iptables -A INPUT -s "$HOST_NETWORK" -j ACCEPT
125
+ # iptables -A OUTPUT -d "$HOST_NETWORK" -j ACCEPT
126
+ #
127
+ # # Set default policies to DROP first
128
+ # iptables -P INPUT DROP
129
+ # iptables -P FORWARD DROP
130
+ # iptables -P OUTPUT DROP
131
+ #
132
+ # # First allow established connections for already approved traffic
133
+ # iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
134
+ # iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
135
+ #
136
+ # # Then allow only specific outbound traffic to allowed domains
137
+ # iptables -A OUTPUT -m set --match-set allowed-domains dst -j ACCEPT
138
+ #
139
+ # # Explicitly REJECT all other outbound traffic for immediate feedback
140
+ # iptables -A OUTPUT -j REJECT --reject-with icmp-admin-prohibited
141
+ #
142
+ # echo "Firewall configuration complete"
143
+ # echo "Verifying firewall rules..."
144
+ # if curl --connect-timeout 5 https://example.com >/dev/null 2>&1; then
145
+ # echo "ERROR: Firewall verification failed - was able to reach https://example.com"
146
+ # exit 1
147
+ # else
148
+ # echo "Firewall verification passed - unable to reach https://example.com as expected"
149
+ # fi
150
+ #
151
+ # # Verify GitHub API access
152
+ # if ! curl --connect-timeout 5 https://api.github.com/zen >/dev/null 2>&1; then
153
+ # echo "ERROR: Firewall verification failed - unable to reach https://api.github.com"
154
+ # exit 1
155
+ # else
156
+ # echo "Firewall verification passed - able to reach https://api.github.com as expected"
157
+ # fi