codeforge-dev 1.5.8 → 1.8.0
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.
- package/.devcontainer/.env +4 -5
- package/.devcontainer/.env.example +29 -0
- package/.devcontainer/.gitignore +8 -0
- package/.devcontainer/.secrets.example +12 -0
- package/.devcontainer/CHANGELOG.md +186 -0
- package/.devcontainer/CLAUDE.md +108 -21
- package/.devcontainer/README.md +173 -57
- package/.devcontainer/config/defaults/keybindings.json +5 -0
- package/.devcontainer/config/{main-system-prompt.md → defaults/main-system-prompt.md} +135 -2
- package/.devcontainer/config/{settings.json → defaults/settings.json} +25 -6
- package/.devcontainer/config/file-manifest.json +20 -0
- package/.devcontainer/devcontainer.json +38 -2
- package/.devcontainer/docs/configuration-reference.md +90 -0
- package/.devcontainer/docs/keybindings.md +100 -0
- package/.devcontainer/docs/optional-features.md +129 -0
- package/.devcontainer/docs/plugins.md +154 -0
- package/.devcontainer/docs/troubleshooting.md +128 -0
- package/.devcontainer/features/README.md +21 -7
- package/.devcontainer/features/agent-browser/install.sh +6 -0
- package/.devcontainer/features/ast-grep/install.sh +6 -0
- package/.devcontainer/features/biome/README.md +27 -0
- package/.devcontainer/features/biome/install.sh +6 -0
- package/.devcontainer/features/ccburn/README.md +60 -0
- package/.devcontainer/features/ccburn/devcontainer-feature.json +38 -0
- package/.devcontainer/features/ccburn/install.sh +180 -0
- package/.devcontainer/features/ccstatusline/README.md +22 -21
- package/.devcontainer/features/ccstatusline/devcontainer-feature.json +6 -1
- package/.devcontainer/features/ccstatusline/install.sh +55 -16
- package/.devcontainer/features/ccusage/install.sh +6 -0
- package/.devcontainer/features/claude-monitor/install.sh +6 -0
- package/.devcontainer/features/dprint/README.md +30 -0
- package/.devcontainer/features/dprint/devcontainer-feature.json +18 -0
- package/.devcontainer/features/dprint/install.sh +131 -0
- package/.devcontainer/features/hadolint/README.md +35 -0
- package/.devcontainer/features/hadolint/devcontainer-feature.json +13 -0
- package/.devcontainer/features/hadolint/install.sh +86 -0
- package/.devcontainer/features/lsp-servers/devcontainer-feature.json +5 -0
- package/.devcontainer/features/lsp-servers/install.sh +7 -0
- package/.devcontainer/features/mcp-qdrant/devcontainer-feature.json +6 -1
- package/.devcontainer/features/mcp-qdrant/install.sh +13 -6
- package/.devcontainer/features/mcp-reasoner/devcontainer-feature.json +6 -1
- package/.devcontainer/features/mcp-reasoner/install.sh +8 -1
- package/.devcontainer/features/notify-hook/devcontainer-feature.json +5 -0
- package/.devcontainer/features/notify-hook/install.sh +7 -0
- package/.devcontainer/features/ruff/README.md +26 -0
- package/.devcontainer/features/ruff/devcontainer-feature.json +21 -0
- package/.devcontainer/features/ruff/install.sh +74 -0
- package/.devcontainer/features/shellcheck/README.md +38 -0
- package/.devcontainer/features/shellcheck/devcontainer-feature.json +13 -0
- package/.devcontainer/features/shellcheck/install.sh +24 -0
- package/.devcontainer/features/shfmt/README.md +37 -0
- package/.devcontainer/features/shfmt/devcontainer-feature.json +13 -0
- package/.devcontainer/features/shfmt/install.sh +85 -0
- package/.devcontainer/features/splitrail/devcontainer-feature.json +5 -0
- package/.devcontainer/features/splitrail/install.sh +7 -0
- package/.devcontainer/features/tmux/install.sh +8 -0
- package/.devcontainer/features/tree-sitter/install.sh +6 -0
- package/.devcontainer/plugins/devs-marketplace/.claude-plugin/marketplace.json +3 -10
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-formatter/.claude-plugin/plugin.json +1 -1
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-formatter/scripts/__pycache__/format-on-stop.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-formatter/scripts/format-on-stop.py +133 -13
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-linter/.claude-plugin/plugin.json +1 -1
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-linter/hooks/hooks.json +4 -5
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-linter/scripts/__pycache__/lint-file.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-linter/scripts/lint-file.py +477 -78
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/.claude-plugin/plugin.json +1 -1
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/AGENT-REDIRECTION.md +226 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/REVIEW-RUBRIC.md +440 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/architect.md +207 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/bash-exec.md +173 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/claude-guide.md +146 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/debug-logs.md +2 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/dependency-analyst.md +250 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/doc-writer.md +246 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/explorer.md +237 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/generalist.md +134 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/git-archaeologist.md +242 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/migrator.md +201 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/perf-profiler.md +265 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/refactorer.md +213 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/researcher.md +195 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/security-auditor.md +289 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/spec-writer.md +297 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/statusline-config.md +188 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/test-writer.md +248 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/hooks/hooks.json +51 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/advisory-test-runner.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/collect-edited-files.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/commit-reminder.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/git-state-injector.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/guard-readonly-bash.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/redirect-builtin-agents.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/skill-suggester.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/syntax-validator.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/ticket-linker.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/todo-harvester.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/verify-no-regression.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/verify-tests-pass.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/advisory-test-runner.py +174 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/collect-edited-files.py +8 -6
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/commit-reminder.py +90 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/git-state-injector.py +114 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/guard-readonly-bash.py +611 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/redirect-builtin-agents.py +83 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/skill-suggester.py +146 -2
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/syntax-validator.py +9 -4
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/ticket-linker.py +137 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/todo-harvester.py +130 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/verify-no-regression.py +221 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/verify-tests-pass.py +176 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/api-design/SKILL.md +224 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/api-design/references/error-handling.md +166 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/api-design/references/rest-conventions.md +215 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/ast-grep-patterns/SKILL.md +211 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/ast-grep-patterns/references/language-patterns.md +327 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/claude-agent-sdk/SKILL.md +599 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/claude-agent-sdk/references/sdk-typescript-reference.md +954 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/dependency-management/SKILL.md +134 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/dependency-management/references/ecosystem-commands.md +264 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/dependency-management/references/license-compliance.md +80 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/documentation-patterns/SKILL.md +153 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/documentation-patterns/references/api-doc-templates.md +221 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/documentation-patterns/references/docstring-formats.md +296 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/git-forensics/SKILL.md +276 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/git-forensics/references/advanced-commands.md +332 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/git-forensics/references/investigation-playbooks.md +319 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/migration-patterns/SKILL.md +150 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/migration-patterns/references/javascript-migrations.md +179 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/migration-patterns/references/python-migrations.md +141 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/performance-profiling/SKILL.md +341 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/performance-profiling/references/interpreting-results.md +235 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/performance-profiling/references/tool-commands.md +395 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/refactoring-patterns/SKILL.md +344 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/refactoring-patterns/references/safe-transformations.md +247 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/refactoring-patterns/references/smell-catalog.md +332 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/security-checklist/SKILL.md +277 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/security-checklist/references/owasp-patterns.md +269 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/security-checklist/references/secrets-patterns.md +253 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/specification-writing/SKILL.md +320 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/specification-writing/references/criteria-patterns.md +245 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/specification-writing/references/ears-templates.md +239 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/dangerous-command-blocker/scripts/__pycache__/block-dangerous.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/notify-hook/hooks/hooks.json +1 -1
- package/.devcontainer/plugins/devs-marketplace/plugins/protected-files-guard/scripts/__pycache__/guard-protected.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/protected-files-guard/scripts/guard-protected.py +40 -39
- package/.devcontainer/scripts/check-setup.sh +72 -0
- package/.devcontainer/scripts/setup-aliases.sh +51 -6
- package/.devcontainer/scripts/setup-auth.sh +74 -0
- package/.devcontainer/scripts/setup-config.sh +112 -20
- package/.devcontainer/scripts/setup-plugins.sh +38 -46
- package/.devcontainer/scripts/setup-projects.sh +175 -0
- package/.devcontainer/scripts/setup-symlink-claude.sh +36 -0
- package/.devcontainer/scripts/setup-update-claude.sh +19 -8
- package/.devcontainer/scripts/setup.sh +49 -14
- package/README.md +23 -190
- package/package.json +1 -1
- package/setup.js +245 -71
- package/.devcontainer/features/claude-code/README.md +0 -498
- package/.devcontainer/features/claude-code/config/settings.json +0 -36
- package/.devcontainer/features/claude-code/config/system-prompt.md +0 -118
- package/.devcontainer/features/claude-code/config/world-building-sp.md +0 -1432
- package/.devcontainer/features/claude-code/devcontainer-feature.json +0 -42
- package/.devcontainer/features/claude-code/install.sh +0 -466
- package/.devcontainer/plugins/devs-marketplace/plugins/planning-reminder/.claude-plugin/plugin.json +0 -7
- package/.devcontainer/plugins/devs-marketplace/plugins/planning-reminder/hooks/hooks.json +0 -17
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/.claude-plugin/plugin.json +0 -6
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/config/planning-instructions.md +0 -14
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/functional-conjuring-map.md +0 -989
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/hooks/hooks.json +0 -33
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/__pycache__/post-enhance-task.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/enhance-planning.py +0 -71
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/enhancers/enhance-plan.sh +0 -68
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/enhancers/enhance-task.sh +0 -120
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/post-enhance-plan.py +0 -133
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/post-enhance-task.py +0 -253
- package/.devcontainer/scripts/setup-irie-claude.sh +0 -32
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
# ==============================
|
|
5
|
+
# dprint DevContainer Feature
|
|
6
|
+
# Official installer + global config
|
|
7
|
+
# ==============================
|
|
8
|
+
|
|
9
|
+
DPRINT_VERSION="${VERSION:-latest}"
|
|
10
|
+
USERNAME="${USERNAME:-automatic}"
|
|
11
|
+
|
|
12
|
+
# Skip installation if version is "none"
|
|
13
|
+
if [ "${DPRINT_VERSION}" = "none" ]; then
|
|
14
|
+
echo "[dprint] Skipping installation (version=none)"
|
|
15
|
+
exit 0
|
|
16
|
+
fi
|
|
17
|
+
|
|
18
|
+
echo "[dprint] Starting installation..."
|
|
19
|
+
|
|
20
|
+
# ---------- USER ----------
|
|
21
|
+
if [[ "${USERNAME}" == "auto" || "${USERNAME}" == "automatic" ]]; then
|
|
22
|
+
for u in vscode node codespace; do
|
|
23
|
+
if id -u "$u" >/dev/null 2>&1; then
|
|
24
|
+
USERNAME="$u"
|
|
25
|
+
break
|
|
26
|
+
fi
|
|
27
|
+
done
|
|
28
|
+
USERNAME="${USERNAME:-root}"
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
USER_HOME="$(eval echo "~${USERNAME}")"
|
|
32
|
+
|
|
33
|
+
echo "[dprint] Target user: ${USERNAME}"
|
|
34
|
+
echo "[dprint] Version: ${DPRINT_VERSION}"
|
|
35
|
+
|
|
36
|
+
# ---------- HELPERS ----------
|
|
37
|
+
download_with_retry() {
|
|
38
|
+
local url="$1" dest="$2" retries="${3:-3}" delay="${4:-2}"
|
|
39
|
+
local attempt=1
|
|
40
|
+
while [ $attempt -le $retries ]; do
|
|
41
|
+
if curl -fsSL ${GITHUB_AUTH_HEADER:-} "$url" -o "$dest" 2>/dev/null; then
|
|
42
|
+
return 0
|
|
43
|
+
fi
|
|
44
|
+
echo "[dprint] Download attempt $attempt/$retries failed, retrying in ${delay}s..."
|
|
45
|
+
sleep "$delay"
|
|
46
|
+
attempt=$((attempt + 1))
|
|
47
|
+
delay=$((delay * 2))
|
|
48
|
+
done
|
|
49
|
+
echo "[dprint] ERROR: Download failed after $retries attempts: $url"
|
|
50
|
+
return 1
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
# GitHub API auth header (avoids rate limiting)
|
|
54
|
+
GITHUB_AUTH_HEADER=""
|
|
55
|
+
if [ -n "${GH_TOKEN:-}" ] || [ -n "${GITHUB_TOKEN:-}" ]; then
|
|
56
|
+
GITHUB_AUTH_HEADER="-H Authorization: token ${GH_TOKEN:-$GITHUB_TOKEN}"
|
|
57
|
+
fi
|
|
58
|
+
|
|
59
|
+
# ---------- INSTALL ----------
|
|
60
|
+
# Install to a system-wide location so all users can access it
|
|
61
|
+
export DPRINT_INSTALL="/usr/local/share/dprint"
|
|
62
|
+
mkdir -p "${DPRINT_INSTALL}/bin"
|
|
63
|
+
|
|
64
|
+
ARCH="$(dpkg --print-architecture)"
|
|
65
|
+
case "${ARCH}" in
|
|
66
|
+
amd64) TARGET="x86_64-unknown-linux-gnu" ;;
|
|
67
|
+
arm64) TARGET="aarch64-unknown-linux-gnu" ;;
|
|
68
|
+
*)
|
|
69
|
+
echo "[dprint] ERROR: Unsupported architecture: ${ARCH}" >&2
|
|
70
|
+
exit 1
|
|
71
|
+
;;
|
|
72
|
+
esac
|
|
73
|
+
|
|
74
|
+
# Version pinned for reproducible builds. Set "latest" to always get newest.
|
|
75
|
+
if [[ "${DPRINT_VERSION}" == "latest" ]]; then
|
|
76
|
+
DPRINT_VERSION="$(curl -fsSL ${GITHUB_AUTH_HEADER:-} https://api.github.com/repos/dprint/dprint/releases/latest | grep -o '"tag_name": *"[^"]*"' | head -1 | cut -d'"' -f4)"
|
|
77
|
+
echo "[dprint] Resolved latest version: ${DPRINT_VERSION}"
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
ZIP_URL="https://github.com/dprint/dprint/releases/download/${DPRINT_VERSION}/dprint-${TARGET}.zip"
|
|
81
|
+
echo "[dprint] Downloading from: ${ZIP_URL}"
|
|
82
|
+
|
|
83
|
+
TMP_DIR="$(mktemp -d)"
|
|
84
|
+
download_with_retry "${ZIP_URL}" "${TMP_DIR}/dprint.zip"
|
|
85
|
+
|
|
86
|
+
# ---------- CHECKSUM VERIFICATION ----------
|
|
87
|
+
CHECKSUM_URL="https://github.com/dprint/dprint/releases/download/${DPRINT_VERSION}/SHASUMS256.txt"
|
|
88
|
+
if curl -fsSL "${CHECKSUM_URL}" -o "${TMP_DIR}/checksums.txt" 2>/dev/null; then
|
|
89
|
+
EXPECTED=$(grep "dprint-${TARGET}.zip" "${TMP_DIR}/checksums.txt" | awk '{print $1}')
|
|
90
|
+
ACTUAL=$(sha256sum "${TMP_DIR}/dprint.zip" | cut -d' ' -f1)
|
|
91
|
+
if [ -n "$EXPECTED" ] && [ "$ACTUAL" != "$EXPECTED" ]; then
|
|
92
|
+
echo "[dprint] ERROR: Checksum verification failed"
|
|
93
|
+
echo " Expected: $EXPECTED"
|
|
94
|
+
echo " Actual: $ACTUAL"
|
|
95
|
+
rm -rf "${TMP_DIR}"
|
|
96
|
+
exit 1
|
|
97
|
+
fi
|
|
98
|
+
echo "[dprint] Checksum verified"
|
|
99
|
+
else
|
|
100
|
+
echo "[dprint] WARNING: Could not fetch checksums, skipping verification"
|
|
101
|
+
fi
|
|
102
|
+
|
|
103
|
+
unzip -o "${TMP_DIR}/dprint.zip" -d "${DPRINT_INSTALL}/bin"
|
|
104
|
+
chmod +x "${DPRINT_INSTALL}/bin/dprint"
|
|
105
|
+
rm -rf "${TMP_DIR}"
|
|
106
|
+
|
|
107
|
+
# Symlink into PATH
|
|
108
|
+
ln -sf "${DPRINT_INSTALL}/bin/dprint" /usr/local/bin/dprint
|
|
109
|
+
|
|
110
|
+
# ---------- GLOBAL CONFIG ----------
|
|
111
|
+
cat > "${DPRINT_INSTALL}/dprint.json" << 'DPRINT_CONFIG'
|
|
112
|
+
{
|
|
113
|
+
"lineWidth": 120,
|
|
114
|
+
"indentWidth": 2,
|
|
115
|
+
"markdown": {},
|
|
116
|
+
"yaml": {},
|
|
117
|
+
"toml": {},
|
|
118
|
+
"dockerfile": {},
|
|
119
|
+
"plugins": [
|
|
120
|
+
"https://plugins.dprint.dev/markdown-0.17.8.wasm",
|
|
121
|
+
"https://plugins.dprint.dev/g-plane/pretty_yaml-0.5.0.wasm",
|
|
122
|
+
"https://plugins.dprint.dev/toml-0.6.4.wasm",
|
|
123
|
+
"https://plugins.dprint.dev/dockerfile-0.3.2.wasm"
|
|
124
|
+
]
|
|
125
|
+
}
|
|
126
|
+
DPRINT_CONFIG
|
|
127
|
+
|
|
128
|
+
echo "[dprint] Global config written to ${DPRINT_INSTALL}/dprint.json"
|
|
129
|
+
|
|
130
|
+
# ---------- VERIFY ----------
|
|
131
|
+
echo "[dprint] Installed: $(dprint --version 2>/dev/null || echo 'unknown')"
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# hadolint
|
|
2
|
+
|
|
3
|
+
Dockerfile linter that validates best practices.
|
|
4
|
+
|
|
5
|
+
## What It Does
|
|
6
|
+
|
|
7
|
+
Installs [hadolint](https://github.com/hadolint/hadolint) as a static binary. Hadolint parses Dockerfiles and checks them against best-practice rules based on the official Docker documentation.
|
|
8
|
+
|
|
9
|
+
## Options
|
|
10
|
+
|
|
11
|
+
| Option | Default | Description |
|
|
12
|
+
|--------|---------|-------------|
|
|
13
|
+
| `version` | `v2.14.0` | hadolint version to install. Set `"latest"` for newest, `"none"` to skip. |
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
hadolint Dockerfile
|
|
19
|
+
hadolint --ignore DL3008 Dockerfile # ignore specific rule
|
|
20
|
+
hadolint -f json Dockerfile # JSON output
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Configuration
|
|
24
|
+
|
|
25
|
+
Used by the `auto-linter` plugin to lint Dockerfiles on save. For project-specific ignores, create a `.hadolint.yaml` in your project root:
|
|
26
|
+
|
|
27
|
+
```yaml
|
|
28
|
+
ignored:
|
|
29
|
+
- DL3008 # Pin versions in apt-get install
|
|
30
|
+
- DL3009 # Delete apt lists
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Checksum Verification
|
|
34
|
+
|
|
35
|
+
Downloads are verified against per-binary `.sha256` files published with each GitHub release.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "hadolint",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"name": "hadolint",
|
|
5
|
+
"description": "Dockerfile linter that validates best practices",
|
|
6
|
+
"options": {
|
|
7
|
+
"version": {
|
|
8
|
+
"type": "string",
|
|
9
|
+
"default": "v2.14.0",
|
|
10
|
+
"description": "hadolint version to install. Set 'latest' to always get newest."
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
# ==============================
|
|
5
|
+
# hadolint DevContainer Feature
|
|
6
|
+
# Direct binary from GitHub releases
|
|
7
|
+
# ==============================
|
|
8
|
+
|
|
9
|
+
HADOLINT_VERSION="${VERSION:-latest}"
|
|
10
|
+
|
|
11
|
+
# Skip installation if version is "none"
|
|
12
|
+
if [ "${HADOLINT_VERSION}" = "none" ]; then
|
|
13
|
+
echo "[hadolint] Skipping installation (version=none)"
|
|
14
|
+
exit 0
|
|
15
|
+
fi
|
|
16
|
+
|
|
17
|
+
echo "[hadolint] Starting installation..."
|
|
18
|
+
|
|
19
|
+
# ---------- HELPERS ----------
|
|
20
|
+
download_with_retry() {
|
|
21
|
+
local url="$1" dest="$2" retries="${3:-3}" delay="${4:-2}"
|
|
22
|
+
local attempt=1
|
|
23
|
+
while [ $attempt -le $retries ]; do
|
|
24
|
+
if curl -fsSL ${GITHUB_AUTH_HEADER:-} "$url" -o "$dest" 2>/dev/null; then
|
|
25
|
+
return 0
|
|
26
|
+
fi
|
|
27
|
+
echo "[hadolint] Download attempt $attempt/$retries failed, retrying in ${delay}s..."
|
|
28
|
+
sleep "$delay"
|
|
29
|
+
attempt=$((attempt + 1))
|
|
30
|
+
delay=$((delay * 2))
|
|
31
|
+
done
|
|
32
|
+
echo "[hadolint] ERROR: Download failed after $retries attempts: $url"
|
|
33
|
+
return 1
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
# GitHub API auth header (avoids rate limiting)
|
|
37
|
+
GITHUB_AUTH_HEADER=""
|
|
38
|
+
if [ -n "${GH_TOKEN:-}" ] || [ -n "${GITHUB_TOKEN:-}" ]; then
|
|
39
|
+
GITHUB_AUTH_HEADER="-H Authorization: token ${GH_TOKEN:-$GITHUB_TOKEN}"
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
ARCH="$(dpkg --print-architecture)"
|
|
43
|
+
case "${ARCH}" in
|
|
44
|
+
amd64) BINARY_ARCH="x86_64" ;;
|
|
45
|
+
arm64) BINARY_ARCH="arm64" ;;
|
|
46
|
+
*)
|
|
47
|
+
echo "[hadolint] ERROR: Unsupported architecture: ${ARCH}" >&2
|
|
48
|
+
exit 1
|
|
49
|
+
;;
|
|
50
|
+
esac
|
|
51
|
+
|
|
52
|
+
# Version pinned for reproducible builds. Set "latest" to always get newest.
|
|
53
|
+
if [[ "${HADOLINT_VERSION}" == "latest" ]]; then
|
|
54
|
+
HADOLINT_VERSION="$(curl -fsSL ${GITHUB_AUTH_HEADER:-} https://api.github.com/repos/hadolint/hadolint/releases/latest | grep -o '"tag_name": *"[^"]*"' | head -1 | cut -d'"' -f4)"
|
|
55
|
+
echo "[hadolint] Resolved latest version: ${HADOLINT_VERSION}"
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
URL="https://github.com/hadolint/hadolint/releases/download/${HADOLINT_VERSION}/hadolint-Linux-${BINARY_ARCH}"
|
|
59
|
+
echo "[hadolint] Downloading from: ${URL}"
|
|
60
|
+
|
|
61
|
+
TMP_DIR="$(mktemp -d)"
|
|
62
|
+
download_with_retry "${URL}" "${TMP_DIR}/hadolint"
|
|
63
|
+
|
|
64
|
+
# ---------- CHECKSUM VERIFICATION ----------
|
|
65
|
+
# hadolint publishes per-binary .sha256 files
|
|
66
|
+
CHECKSUM_URL="${URL}.sha256"
|
|
67
|
+
if curl -fsSL "${CHECKSUM_URL}" -o "${TMP_DIR}/checksum.sha256" 2>/dev/null; then
|
|
68
|
+
EXPECTED=$(awk '{print $1}' "${TMP_DIR}/checksum.sha256")
|
|
69
|
+
ACTUAL=$(sha256sum "${TMP_DIR}/hadolint" | cut -d' ' -f1)
|
|
70
|
+
if [ -n "$EXPECTED" ] && [ "$ACTUAL" != "$EXPECTED" ]; then
|
|
71
|
+
echo "[hadolint] ERROR: Checksum verification failed"
|
|
72
|
+
echo " Expected: $EXPECTED"
|
|
73
|
+
echo " Actual: $ACTUAL"
|
|
74
|
+
rm -rf "${TMP_DIR}"
|
|
75
|
+
exit 1
|
|
76
|
+
fi
|
|
77
|
+
echo "[hadolint] Checksum verified"
|
|
78
|
+
else
|
|
79
|
+
echo "[hadolint] WARNING: Could not fetch checksum, skipping verification"
|
|
80
|
+
fi
|
|
81
|
+
|
|
82
|
+
cp "${TMP_DIR}/hadolint" /usr/local/bin/hadolint
|
|
83
|
+
chmod +x /usr/local/bin/hadolint
|
|
84
|
+
rm -rf "${TMP_DIR}"
|
|
85
|
+
|
|
86
|
+
echo "[hadolint] Installed: $(hadolint --version 2>/dev/null || echo 'unknown')"
|
|
@@ -6,6 +6,11 @@
|
|
|
6
6
|
"maintainer": "AnExiledDev",
|
|
7
7
|
"documentationURL": "https://code.claude.com/docs/en/discover-plugins#code-intelligence",
|
|
8
8
|
"options": {
|
|
9
|
+
"version": {
|
|
10
|
+
"type": "string",
|
|
11
|
+
"description": "Set to 'none' to skip installation of all LSP servers",
|
|
12
|
+
"default": "latest"
|
|
13
|
+
},
|
|
9
14
|
"pyrightVersion": {
|
|
10
15
|
"type": "string",
|
|
11
16
|
"description": "Pyright npm package version (e.g., 'latest', '1.1.350')",
|
|
@@ -4,12 +4,19 @@
|
|
|
4
4
|
|
|
5
5
|
set -euo pipefail
|
|
6
6
|
|
|
7
|
+
VERSION="${VERSION:-latest}"
|
|
7
8
|
PYRIGHT_VERSION="${PYRIGHTVERSION:-latest}"
|
|
8
9
|
TSLSP_VERSION="${TYPESCRIPTLSPVERSION:-latest}"
|
|
9
10
|
TS_VERSION="${TYPESCRIPTVERSION:-latest}"
|
|
10
11
|
GOPLS_VERSION="${GOPLSVERSION:-latest}"
|
|
11
12
|
USERNAME="${USERNAME:-automatic}"
|
|
12
13
|
|
|
14
|
+
# Skip installation if version is "none"
|
|
15
|
+
if [ "${VERSION}" = "none" ]; then
|
|
16
|
+
echo "[lsp-servers] Skipping installation (version=none)"
|
|
17
|
+
exit 0
|
|
18
|
+
fi
|
|
19
|
+
|
|
13
20
|
echo "[lsp-servers] Starting installation..."
|
|
14
21
|
echo "[lsp-servers] Pyright version: ${PYRIGHT_VERSION}"
|
|
15
22
|
echo "[lsp-servers] TypeScript LSP version: ${TSLSP_VERSION}"
|
|
@@ -6,6 +6,11 @@
|
|
|
6
6
|
"maintainer": "AnExiledDev",
|
|
7
7
|
"documentationURL": "https://github.com/qdrant/mcp-server-qdrant",
|
|
8
8
|
"options": {
|
|
9
|
+
"version": {
|
|
10
|
+
"type": "string",
|
|
11
|
+
"description": "Version to install (or 'none' to skip installation)",
|
|
12
|
+
"default": "latest"
|
|
13
|
+
},
|
|
9
14
|
"qdrantUrl": {
|
|
10
15
|
"type": "string",
|
|
11
16
|
"description": "Qdrant instance URL (e.g., https://xyz.cloud.qdrant.io:6333). Leave empty for local instance.",
|
|
@@ -52,6 +57,6 @@
|
|
|
52
57
|
"installsAfter": [
|
|
53
58
|
"ghcr.io/devcontainers/features/python:1",
|
|
54
59
|
"ghcr.io/devcontainers/features/common-utils:2",
|
|
55
|
-
"
|
|
60
|
+
"ghcr.io/anthropics/devcontainer-features/claude-code:1"
|
|
56
61
|
]
|
|
57
62
|
}
|
|
@@ -4,6 +4,14 @@ set -euo pipefail
|
|
|
4
4
|
# Import options from devcontainer-feature.json
|
|
5
5
|
# NOTE: DevContainer converts camelCase options to UPPERCASE without underscores
|
|
6
6
|
# Example: "qdrantUrl" becomes $QDRANTURL (not $QDRANT_URL)
|
|
7
|
+
VERSION="${VERSION:-latest}"
|
|
8
|
+
|
|
9
|
+
# Skip installation if version is "none"
|
|
10
|
+
if [ "${VERSION}" = "none" ]; then
|
|
11
|
+
echo "[mcp-qdrant] Skipping installation (version=none)"
|
|
12
|
+
exit 0
|
|
13
|
+
fi
|
|
14
|
+
|
|
7
15
|
QDRANT_URL="${QDRANTURL:-}"
|
|
8
16
|
QDRANT_API_KEY="${QDRANTAPIKEY:-}"
|
|
9
17
|
QDRANT_LOCAL_PATH="${QDRANTLOCALPATH:-/workspaces/.qdrant/storage}"
|
|
@@ -76,7 +84,7 @@ pip uninstall hf-xet -y 2>/dev/null || true
|
|
|
76
84
|
# Pre-download the embedding model from GCS (more reliable than HuggingFace Hub in containers)
|
|
77
85
|
# This is critical to avoid network timeouts from huggingface_hub
|
|
78
86
|
echo "[mcp-qdrant] Pre-downloading embedding model from GCS..."
|
|
79
|
-
FASTEMBED_CACHE="/
|
|
87
|
+
FASTEMBED_CACHE="/workspaces/.qdrant/fastembed_cache"
|
|
80
88
|
mkdir -p "${FASTEMBED_CACHE}"
|
|
81
89
|
|
|
82
90
|
# Map embedding model names to GCS URLs and legacy cache directory names
|
|
@@ -117,8 +125,7 @@ if [ -n "${MODEL_URL}" ]; then
|
|
|
117
125
|
# Remove macOS extended attribute files
|
|
118
126
|
find "${FASTEMBED_CACHE}" -name "._*" -delete 2>/dev/null || true
|
|
119
127
|
rm -f "${TEMP_TAR}"
|
|
120
|
-
|
|
121
|
-
chmod -R 777 "${FASTEMBED_CACHE}" 2>/dev/null || true
|
|
128
|
+
chmod -R 755 "${FASTEMBED_CACHE}" 2>/dev/null || true
|
|
122
129
|
echo "[mcp-qdrant] ✓ Embedding model pre-downloaded to ${FASTEMBED_CACHE}/${MODEL_DIR}"
|
|
123
130
|
else
|
|
124
131
|
echo "[mcp-qdrant] WARNING: Failed to download model from GCS"
|
|
@@ -208,7 +215,7 @@ if [ -n "$QDRANT_URL" ]; then
|
|
|
208
215
|
args: ["mcp-server-qdrant"],
|
|
209
216
|
env: {
|
|
210
217
|
HF_HUB_OFFLINE: "1",
|
|
211
|
-
FASTEMBED_CACHE_PATH: "/
|
|
218
|
+
FASTEMBED_CACHE_PATH: "/workspaces/.qdrant/fastembed_cache",
|
|
212
219
|
QDRANT_URL: $url,
|
|
213
220
|
QDRANT_API_KEY: $key,
|
|
214
221
|
COLLECTION_NAME: $collection
|
|
@@ -224,7 +231,7 @@ else
|
|
|
224
231
|
args: ["mcp-server-qdrant"],
|
|
225
232
|
env: {
|
|
226
233
|
HF_HUB_OFFLINE: "1",
|
|
227
|
-
FASTEMBED_CACHE_PATH: "/
|
|
234
|
+
FASTEMBED_CACHE_PATH: "/workspaces/.qdrant/fastembed_cache",
|
|
228
235
|
QDRANT_LOCAL_PATH: $path,
|
|
229
236
|
COLLECTION_NAME: $collection
|
|
230
237
|
}
|
|
@@ -250,7 +257,7 @@ fi
|
|
|
250
257
|
|
|
251
258
|
# Set proper permissions
|
|
252
259
|
chmod 644 "$SETTINGS_FILE"
|
|
253
|
-
chown
|
|
260
|
+
chown "$(id -un):$(id -gn)" "$SETTINGS_FILE" 2>/dev/null || true
|
|
254
261
|
|
|
255
262
|
echo "[mcp-qdrant] ✓ Configuration complete"
|
|
256
263
|
HOOK_EOF
|
|
@@ -6,6 +6,11 @@
|
|
|
6
6
|
"maintainer": "AnExiledDev",
|
|
7
7
|
"documentationURL": "https://github.com/Jacck/mcp-reasoner",
|
|
8
8
|
"options": {
|
|
9
|
+
"version": {
|
|
10
|
+
"type": "string",
|
|
11
|
+
"description": "Version to install (or 'none' to skip installation)",
|
|
12
|
+
"default": "latest"
|
|
13
|
+
},
|
|
9
14
|
"username": {
|
|
10
15
|
"type": "string",
|
|
11
16
|
"description": "Container user to install for",
|
|
@@ -15,6 +20,6 @@
|
|
|
15
20
|
"installsAfter": [
|
|
16
21
|
"ghcr.io/devcontainers/features/node:1",
|
|
17
22
|
"ghcr.io/devcontainers/features/common-utils:2",
|
|
18
|
-
"
|
|
23
|
+
"ghcr.io/anthropics/devcontainer-features/claude-code:1"
|
|
19
24
|
]
|
|
20
25
|
}
|
|
@@ -4,8 +4,15 @@ set -euo pipefail
|
|
|
4
4
|
# No cleanup needed - using CLI instead of temp files
|
|
5
5
|
|
|
6
6
|
# Import options
|
|
7
|
+
VERSION="${VERSION:-latest}"
|
|
7
8
|
USERNAME="${USERNAME:-automatic}"
|
|
8
9
|
|
|
10
|
+
# Skip installation if version is "none"
|
|
11
|
+
if [ "${VERSION}" = "none" ]; then
|
|
12
|
+
echo "[mcp-reasoner] Skipping installation (version=none)"
|
|
13
|
+
exit 0
|
|
14
|
+
fi
|
|
15
|
+
|
|
9
16
|
echo "[mcp-reasoner] Starting MCP Reasoner installation..."
|
|
10
17
|
|
|
11
18
|
# Source NVM (Node is installed via NVM by the node feature)
|
|
@@ -145,7 +152,7 @@ fi
|
|
|
145
152
|
|
|
146
153
|
# Set proper permissions
|
|
147
154
|
chmod 644 "$SETTINGS_FILE"
|
|
148
|
-
chown
|
|
155
|
+
chown "$(id -un):$(id -gn)" "$SETTINGS_FILE" 2>/dev/null || true
|
|
149
156
|
|
|
150
157
|
echo "[mcp-reasoner] ✓ Configuration complete"
|
|
151
158
|
HOOK_EOF
|
|
@@ -5,6 +5,11 @@
|
|
|
5
5
|
"description": "Desktop notifications and audio chime when Claude finishes responding",
|
|
6
6
|
"documentationURL": "https://github.com/AnExiledDev/CodeForge",
|
|
7
7
|
"options": {
|
|
8
|
+
"version": {
|
|
9
|
+
"type": "string",
|
|
10
|
+
"description": "Version to install (or 'none' to skip installation)",
|
|
11
|
+
"default": "latest"
|
|
12
|
+
},
|
|
8
13
|
"enableBell": {
|
|
9
14
|
"type": "boolean",
|
|
10
15
|
"description": "Enable terminal bell (audio chime) on completion",
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
set -euo pipefail
|
|
3
3
|
|
|
4
|
+
VERSION="${VERSION:-latest}"
|
|
4
5
|
ENABLEBELL="${ENABLEBELL:-true}"
|
|
5
6
|
ENABLEOSC="${ENABLEOSC:-true}"
|
|
6
7
|
|
|
8
|
+
# Skip installation if version is "none"
|
|
9
|
+
if [ "${VERSION}" = "none" ]; then
|
|
10
|
+
echo "[notify-hook] Skipping installation (version=none)"
|
|
11
|
+
exit 0
|
|
12
|
+
fi
|
|
13
|
+
|
|
7
14
|
echo "[notify-hook] Starting installation..."
|
|
8
15
|
echo "[notify-hook] Bell enabled: ${ENABLEBELL}"
|
|
9
16
|
echo "[notify-hook] OSC notifications enabled: ${ENABLEOSC}"
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Ruff
|
|
2
|
+
|
|
3
|
+
Fast Python linter and formatter, replacing Black + Flake8.
|
|
4
|
+
|
|
5
|
+
## What It Does
|
|
6
|
+
|
|
7
|
+
Installs [Ruff](https://docs.astral.sh/ruff/) via `uv tool install`. Ruff is an extremely fast Python linter and formatter written in Rust, compatible with Flake8, isort, and Black rules.
|
|
8
|
+
|
|
9
|
+
## Options
|
|
10
|
+
|
|
11
|
+
| Option | Default | Description |
|
|
12
|
+
|--------|---------|-------------|
|
|
13
|
+
| `version` | `latest` | Ruff version to install. Set `"none"` to skip. |
|
|
14
|
+
| `username` | `automatic` | Container user to install for. |
|
|
15
|
+
|
|
16
|
+
## Usage
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
ruff check . # lint
|
|
20
|
+
ruff check --fix . # lint and auto-fix
|
|
21
|
+
ruff format . # format (Black-compatible)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Configuration
|
|
25
|
+
|
|
26
|
+
Used by both `auto-formatter` (formatting) and `auto-linter` (linting) plugins for Python files. For project-specific config, add a `[tool.ruff]` section to `pyproject.toml` or create a `ruff.toml`. See [Ruff docs](https://docs.astral.sh/ruff/configuration/).
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "ruff",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"name": "Ruff",
|
|
5
|
+
"description": "Fast Python linter and formatter (replaces Black + Flake8)",
|
|
6
|
+
"options": {
|
|
7
|
+
"version": {
|
|
8
|
+
"type": "string",
|
|
9
|
+
"default": "latest",
|
|
10
|
+
"description": "Ruff version to install"
|
|
11
|
+
},
|
|
12
|
+
"username": {
|
|
13
|
+
"type": "string",
|
|
14
|
+
"default": "automatic",
|
|
15
|
+
"description": "Container user to install for"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"installsAfter": [
|
|
19
|
+
"ghcr.io/devcontainers-extra/features/uv"
|
|
20
|
+
]
|
|
21
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
# ==============================
|
|
5
|
+
# Ruff DevContainer Feature
|
|
6
|
+
# Installs via uv tool install
|
|
7
|
+
# ==============================
|
|
8
|
+
|
|
9
|
+
RUFF_VERSION="${VERSION:-latest}"
|
|
10
|
+
USERNAME="${USERNAME:-automatic}"
|
|
11
|
+
|
|
12
|
+
# Skip installation if version is "none"
|
|
13
|
+
if [ "${RUFF_VERSION}" = "none" ]; then
|
|
14
|
+
echo "[ruff] Skipping installation (version=none)"
|
|
15
|
+
exit 0
|
|
16
|
+
fi
|
|
17
|
+
|
|
18
|
+
echo "[ruff] Starting installation..."
|
|
19
|
+
|
|
20
|
+
# ---------- USER ----------
|
|
21
|
+
if [[ "${USERNAME}" == "auto" || "${USERNAME}" == "automatic" ]]; then
|
|
22
|
+
for u in vscode node codespace; do
|
|
23
|
+
if id -u "$u" >/dev/null 2>&1; then
|
|
24
|
+
USERNAME="$u"
|
|
25
|
+
break
|
|
26
|
+
fi
|
|
27
|
+
done
|
|
28
|
+
USERNAME="${USERNAME:-root}"
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
USER_HOME="$(eval echo "~${USERNAME}")"
|
|
32
|
+
|
|
33
|
+
echo "[ruff] Target user: ${USERNAME}"
|
|
34
|
+
echo "[ruff] Version: ${RUFF_VERSION}"
|
|
35
|
+
|
|
36
|
+
run_as_user() {
|
|
37
|
+
sudo -u "${USERNAME}" env \
|
|
38
|
+
HOME="${USER_HOME}" \
|
|
39
|
+
"$@"
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
# ---------- UV DISCOVERY ----------
|
|
43
|
+
find_uv() {
|
|
44
|
+
command -v uv 2>/dev/null && return 0
|
|
45
|
+
for p in /usr/local/bin/uv /usr/bin/uv /opt/uv/bin/uv; do
|
|
46
|
+
[[ -x "$p" ]] && echo "$p" && return 0
|
|
47
|
+
done
|
|
48
|
+
find /usr /opt -maxdepth 4 -type f -name uv -executable 2>/dev/null | head -n 1
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
# ---------- INSTALL ----------
|
|
52
|
+
UV_BIN="$(find_uv || true)"
|
|
53
|
+
if [[ -z "${UV_BIN}" ]]; then
|
|
54
|
+
echo "[ruff] ERROR: uv is not installed" >&2
|
|
55
|
+
exit 1
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
echo "[ruff] Using uv at: ${UV_BIN}"
|
|
59
|
+
|
|
60
|
+
if [[ "${RUFF_VERSION}" == "latest" ]]; then
|
|
61
|
+
run_as_user "${UV_BIN}" tool install ruff
|
|
62
|
+
else
|
|
63
|
+
run_as_user "${UV_BIN}" tool install "ruff==${RUFF_VERSION}"
|
|
64
|
+
fi
|
|
65
|
+
|
|
66
|
+
# ---------- VERIFY ----------
|
|
67
|
+
BIN_DIR="${USER_HOME}/.local/bin"
|
|
68
|
+
if [[ -x "${BIN_DIR}/ruff" ]]; then
|
|
69
|
+
INSTALLED="$("${BIN_DIR}/ruff" --version 2>/dev/null || echo "unknown")"
|
|
70
|
+
echo "[ruff] Installed: ${INSTALLED}"
|
|
71
|
+
else
|
|
72
|
+
echo "[ruff] ERROR: ruff not found in ${BIN_DIR}" >&2
|
|
73
|
+
exit 1
|
|
74
|
+
fi
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# ShellCheck
|
|
2
|
+
|
|
3
|
+
Static analysis tool for shell scripts.
|
|
4
|
+
|
|
5
|
+
## What It Does
|
|
6
|
+
|
|
7
|
+
Installs [ShellCheck](https://www.shellcheck.net/) via apt. ShellCheck finds bugs and style issues in bash/sh/zsh scripts, catching common pitfalls like unquoted variables, incorrect test syntax, and POSIX compatibility issues.
|
|
8
|
+
|
|
9
|
+
## Options
|
|
10
|
+
|
|
11
|
+
| Option | Default | Description |
|
|
12
|
+
|--------|---------|-------------|
|
|
13
|
+
| `version` | `latest` | Version to install (or `"none"` to skip). |
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
shellcheck script.sh
|
|
19
|
+
shellcheck -x script.sh # follow source'd files
|
|
20
|
+
shellcheck -f json script.sh # JSON output
|
|
21
|
+
shellcheck -e SC2086 script.sh # exclude specific rule
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Configuration
|
|
25
|
+
|
|
26
|
+
Used by the `auto-linter` plugin to lint shell scripts. For per-file directives, add comments at the top of your script:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
# shellcheck disable=SC2086
|
|
30
|
+
# shellcheck shell=bash
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
For project-wide config, create a `.shellcheckrc`:
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
disable=SC2086,SC2034
|
|
37
|
+
shell=bash
|
|
38
|
+
```
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "shellcheck",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"name": "ShellCheck",
|
|
5
|
+
"description": "Static analysis tool for shell scripts",
|
|
6
|
+
"options": {
|
|
7
|
+
"version": {
|
|
8
|
+
"type": "string",
|
|
9
|
+
"description": "Version to install (or 'none' to skip installation)",
|
|
10
|
+
"default": "latest"
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
# ==============================
|
|
5
|
+
# ShellCheck DevContainer Feature
|
|
6
|
+
# Installed via apt
|
|
7
|
+
# ==============================
|
|
8
|
+
|
|
9
|
+
VERSION="${VERSION:-latest}"
|
|
10
|
+
|
|
11
|
+
# Skip installation if version is "none"
|
|
12
|
+
if [ "${VERSION}" = "none" ]; then
|
|
13
|
+
echo "[shellcheck] Skipping installation (version=none)"
|
|
14
|
+
exit 0
|
|
15
|
+
fi
|
|
16
|
+
|
|
17
|
+
echo "[shellcheck] Starting installation..."
|
|
18
|
+
|
|
19
|
+
apt-get update -y
|
|
20
|
+
apt-get install -y --no-install-recommends shellcheck
|
|
21
|
+
apt-get clean -y
|
|
22
|
+
rm -rf /var/lib/apt/lists/*
|
|
23
|
+
|
|
24
|
+
echo "[shellcheck] Installed: $(shellcheck --version 2>/dev/null | head -2 || echo 'unknown')"
|