@hybridlabor-api/aos 4.8.0 → 4.10.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.
Files changed (186) hide show
  1. package/.agents/{agents.md → AGENTS.md} +3 -1
  2. package/.agents/nodes.json +3 -1
  3. package/.agents/vendor-manifest.json +23 -1
  4. package/.claude/agents/godmode-media-eventtech.md +1 -1
  5. package/.claude/hooks/conventional-commits.mjs +125 -0
  6. package/.claude/hooks/env-file-protection.mjs +105 -0
  7. package/.claude/hooks/go-gate.mjs +101 -81
  8. package/.claude/hooks/memb-inject.mjs +29 -1
  9. package/.claude/settings.json +13 -0
  10. package/.claude/workflows/startcycle-dispatch.mjs +23 -1
  11. package/.opencode/agents/godmode-media-eventtech.md +1 -1
  12. package/.opencode/plugins/bdb-aos.js +31 -4
  13. package/CLAUDE.md +0 -571
  14. package/README.de.md +1 -1
  15. package/README.md +1 -1
  16. package/README.pt.md +1 -1
  17. package/THIRD_PARTY_NOTICES.md +126 -0
  18. package/bin/aos-doctor.mjs +1 -1
  19. package/docs/skills_table.md +1 -1
  20. package/installer.js +187 -55
  21. package/package.json +7 -3
  22. package/packages/aos-cli/README.md +80 -0
  23. package/packages/aos-cli/bin/aos-cli.mjs +134 -0
  24. package/packages/aos-cli/core-skills.json +12 -0
  25. package/packages/aos-cli/extensions/aos.ts +321 -0
  26. package/packages/aos-cli/package-lock.json +1923 -0
  27. package/packages/aos-cli/package.json +29 -0
  28. package/packages/aos-cli/scripts/check-theme.mjs +63 -0
  29. package/packages/aos-cli/themes/aos.json +97 -0
  30. package/scripts/build-plugin-manifest.mjs +131 -0
  31. package/scripts/validate-skills.mjs +81 -6
  32. package/skills/basic/ao-orchestrator/SKILL.md +116 -0
  33. package/skills/basic/bdb-eventagency-skill/SKILL.md +252 -0
  34. package/skills/basic/bdb-shipping-skill/SKILL.md +161 -0
  35. package/skills/basic/godmode-eventtech/SKILL.md +4 -1
  36. package/skills/global_config/agenttrail/SKILL.md +6 -1
  37. package/skills/global_config/aos-project-init/SKILL.md +2 -0
  38. package/skills/global_config/aos-project-init/assets/AGENTS.template.md +1 -1
  39. package/skills/global_config/aos-project-init/scripts/aos-project-doctor.mjs +1 -1
  40. package/skills/global_config/aos-setup/SKILL.md +1 -1
  41. package/skills/global_config/aos-setup/scripts/aos-doctor.mjs +1 -1
  42. package/skills/global_config/ask-tim/SKILL.md +7 -7
  43. package/skills/global_config/bash-script-generator/SKILL.md +201 -0
  44. package/skills/global_config/bash-script-generator/assets/templates/standard-template.sh +96 -0
  45. package/skills/global_config/bash-script-generator/docs/bash-scripting-guide.md +729 -0
  46. package/skills/global_config/bash-script-generator/docs/generation-best-practices.md +193 -0
  47. package/skills/global_config/bash-script-generator/docs/script-patterns.md +566 -0
  48. package/skills/global_config/bash-script-generator/docs/text-processing-guide.md +437 -0
  49. package/skills/global_config/bash-script-generator/examples/log-analyzer.sh +92 -0
  50. package/skills/global_config/bash-script-generator/scripts/generate_script_template.sh +123 -0
  51. package/skills/global_config/bash-script-generator/scripts/run_ci_checks.sh +172 -0
  52. package/skills/global_config/bash-script-generator/scripts/test_generator.sh +413 -0
  53. package/skills/global_config/bash-script-validator/SKILL.md +249 -0
  54. package/skills/global_config/bash-script-validator/docs/awk-reference.md +449 -0
  55. package/skills/global_config/bash-script-validator/docs/bash-reference.md +468 -0
  56. package/skills/global_config/bash-script-validator/docs/common-mistakes.md +623 -0
  57. package/skills/global_config/bash-script-validator/docs/grep-reference.md +395 -0
  58. package/skills/global_config/bash-script-validator/docs/regex-reference.md +391 -0
  59. package/skills/global_config/bash-script-validator/docs/sed-reference.md +454 -0
  60. package/skills/global_config/bash-script-validator/docs/shell-reference.md +463 -0
  61. package/skills/global_config/bash-script-validator/docs/shellcheck-reference.md +399 -0
  62. package/skills/global_config/bash-script-validator/examples/bad-bash.sh +55 -0
  63. package/skills/global_config/bash-script-validator/examples/bad-shell.sh +54 -0
  64. package/skills/global_config/bash-script-validator/examples/good-bash.sh +71 -0
  65. package/skills/global_config/bash-script-validator/examples/good-shell.sh +69 -0
  66. package/skills/global_config/bash-script-validator/scripts/run_ci_checks.sh +23 -0
  67. package/skills/global_config/bash-script-validator/scripts/shellcheck_wrapper.sh +174 -0
  68. package/skills/global_config/bash-script-validator/scripts/test_validate.sh +446 -0
  69. package/skills/global_config/bash-script-validator/scripts/validate.sh +512 -0
  70. package/skills/global_config/ci-pipeline/SKILL.md +135 -0
  71. package/skills/global_config/deja-memory/SKILL.md +3 -1
  72. package/skills/global_config/dispatching-parallel-agents/SKILL.md +170 -0
  73. package/skills/global_config/dockerfile-generator/SKILL.md +1038 -0
  74. package/skills/global_config/dockerfile-generator/examples/example.dockerignore +95 -0
  75. package/skills/global_config/dockerfile-generator/examples/golang-distroless.Dockerfile +34 -0
  76. package/skills/global_config/dockerfile-generator/examples/java-springboot.Dockerfile +45 -0
  77. package/skills/global_config/dockerfile-generator/examples/nextjs-production.Dockerfile +49 -0
  78. package/skills/global_config/dockerfile-generator/examples/nodejs-multistage.Dockerfile +55 -0
  79. package/skills/global_config/dockerfile-generator/examples/python-fastapi.Dockerfile +48 -0
  80. package/skills/global_config/dockerfile-generator/references/language_specific_guides.md +510 -0
  81. package/skills/global_config/dockerfile-generator/references/multistage_builds.md +570 -0
  82. package/skills/global_config/dockerfile-generator/references/optimization_patterns.md +492 -0
  83. package/skills/global_config/dockerfile-generator/references/security_best_practices.md +375 -0
  84. package/skills/global_config/dockerfile-generator/scripts/generate_dockerignore.sh +199 -0
  85. package/skills/global_config/dockerfile-generator/scripts/generate_golang.sh +172 -0
  86. package/skills/global_config/dockerfile-generator/scripts/generate_java.sh +185 -0
  87. package/skills/global_config/dockerfile-generator/scripts/generate_nodejs.sh +279 -0
  88. package/skills/global_config/dockerfile-generator/scripts/generate_python.sh +218 -0
  89. package/skills/global_config/dockerfile-generator/scripts/test_generator.sh +210 -0
  90. package/skills/global_config/dockerfile-validator/SKILL.md +300 -0
  91. package/skills/global_config/dockerfile-validator/examples/.dockerignore.example +34 -0
  92. package/skills/global_config/dockerfile-validator/examples/bad-example.Dockerfile +37 -0
  93. package/skills/global_config/dockerfile-validator/examples/golang-distroless.Dockerfile +50 -0
  94. package/skills/global_config/dockerfile-validator/examples/good-example.Dockerfile +52 -0
  95. package/skills/global_config/dockerfile-validator/examples/python-optimized.Dockerfile +53 -0
  96. package/skills/global_config/dockerfile-validator/examples/security-issues.Dockerfile +42 -0
  97. package/skills/global_config/dockerfile-validator/references/docker_best_practices.md +348 -0
  98. package/skills/global_config/dockerfile-validator/references/optimization_guide.md +473 -0
  99. package/skills/global_config/dockerfile-validator/references/security_checklist.md +208 -0
  100. package/skills/global_config/dockerfile-validator/scripts/dockerfile-validate.sh +699 -0
  101. package/skills/global_config/dockerfile-validator/scripts/test_validate.sh +35 -0
  102. package/skills/global_config/dockerfile-validator/tests/fixtures/copy-before-yarn-lock-read.Dockerfile +6 -0
  103. package/skills/global_config/dockerfile-validator/tests/fixtures/copy-before-yarn.Dockerfile +6 -0
  104. package/skills/global_config/dockerfile-validator/tests/fixtures/from-platform-nonroot.Dockerfile +7 -0
  105. package/skills/global_config/dockerfile-validator/tests/test_regression.sh +164 -0
  106. package/skills/global_config/finishing-a-development-branch/SKILL.md +228 -0
  107. package/skills/global_config/github-actions-generator/SKILL.md +353 -0
  108. package/skills/global_config/github-actions-generator/assets/templates/action/composite/action.yml +82 -0
  109. package/skills/global_config/github-actions-generator/assets/templates/action/docker/Dockerfile +25 -0
  110. package/skills/global_config/github-actions-generator/assets/templates/action/docker/action.yml +42 -0
  111. package/skills/global_config/github-actions-generator/assets/templates/action/docker/entrypoint.sh +27 -0
  112. package/skills/global_config/github-actions-generator/assets/templates/action/javascript/action.yml +33 -0
  113. package/skills/global_config/github-actions-generator/assets/templates/action/javascript/index.js +50 -0
  114. package/skills/global_config/github-actions-generator/assets/templates/action/javascript/package.json +27 -0
  115. package/skills/global_config/github-actions-generator/assets/templates/workflow/basic_workflow.yml +242 -0
  116. package/skills/global_config/github-actions-generator/assets/templates/workflow/reusable_workflow.yml +106 -0
  117. package/skills/global_config/github-actions-generator/examples/README.md +147 -0
  118. package/skills/global_config/github-actions-generator/examples/actions/setup-node-cached/action.yml +93 -0
  119. package/skills/global_config/github-actions-generator/examples/caching/docker-buildkit.yml +256 -0
  120. package/skills/global_config/github-actions-generator/examples/security/dependency-review.yml +62 -0
  121. package/skills/global_config/github-actions-generator/examples/security/sbom-attestation.yml +119 -0
  122. package/skills/global_config/github-actions-generator/examples/triggers/chatops-commands.yml +475 -0
  123. package/skills/global_config/github-actions-generator/examples/triggers/repository-dispatch.yml +418 -0
  124. package/skills/global_config/github-actions-generator/examples/triggers/workflow-orchestration.yml +404 -0
  125. package/skills/global_config/github-actions-generator/examples/workflows/docker-build-push.yml +68 -0
  126. package/skills/global_config/github-actions-generator/examples/workflows/go-ci.yml +161 -0
  127. package/skills/global_config/github-actions-generator/examples/workflows/monorepo-ci.yml +340 -0
  128. package/skills/global_config/github-actions-generator/examples/workflows/multi-environment-deploy.yml +406 -0
  129. package/skills/global_config/github-actions-generator/examples/workflows/nodejs-ci.yml +122 -0
  130. package/skills/global_config/github-actions-generator/examples/workflows/python-ci.yml +157 -0
  131. package/skills/global_config/github-actions-generator/examples/workflows/scheduled-tasks.yml +376 -0
  132. package/skills/global_config/github-actions-generator/references/advanced-triggers.md +917 -0
  133. package/skills/global_config/github-actions-generator/references/best-practices.md +755 -0
  134. package/skills/global_config/github-actions-generator/references/common-actions.md +715 -0
  135. package/skills/global_config/github-actions-generator/references/custom-actions.md +320 -0
  136. package/skills/global_config/github-actions-generator/references/expressions-and-contexts.md +688 -0
  137. package/skills/global_config/github-actions-generator/references/modern-features.md +421 -0
  138. package/skills/global_config/github-actions-generator/scripts/test_generator.sh +344 -0
  139. package/skills/global_config/github-actions-templates/SKILL.md +7 -0
  140. package/skills/global_config/github-actions-validator/SKILL.md +576 -0
  141. package/skills/global_config/github-actions-validator/examples/README.md +88 -0
  142. package/skills/global_config/github-actions-validator/examples/outdated-versions.yml +76 -0
  143. package/skills/global_config/github-actions-validator/examples/valid-ci.yml +79 -0
  144. package/skills/global_config/github-actions-validator/examples/with-errors.yml +47 -0
  145. package/skills/global_config/github-actions-validator/references/act_usage.md +233 -0
  146. package/skills/global_config/github-actions-validator/references/action_versions.md +122 -0
  147. package/skills/global_config/github-actions-validator/references/actionlint_usage.md +343 -0
  148. package/skills/global_config/github-actions-validator/references/common_errors.md +512 -0
  149. package/skills/global_config/github-actions-validator/references/modern_features.md +384 -0
  150. package/skills/global_config/github-actions-validator/references/runners.md +317 -0
  151. package/skills/global_config/github-actions-validator/scripts/install_tools.sh +113 -0
  152. package/skills/global_config/github-actions-validator/scripts/validate_workflow.sh +910 -0
  153. package/skills/global_config/github-actions-validator/tests/test_validate_workflow.sh +237 -0
  154. package/skills/global_config/makefile-generator/SKILL.md +614 -0
  155. package/skills/global_config/makefile-generator/assets/templates/.gitkeep +1 -0
  156. package/skills/global_config/makefile-generator/docs/makefile-structure.md +530 -0
  157. package/skills/global_config/makefile-generator/docs/optimization-guide.md +784 -0
  158. package/skills/global_config/makefile-generator/docs/patterns-guide.md +642 -0
  159. package/skills/global_config/makefile-generator/docs/security-guide.md +361 -0
  160. package/skills/global_config/makefile-generator/docs/targets-guide.md +642 -0
  161. package/skills/global_config/makefile-generator/docs/variables-guide.md +596 -0
  162. package/skills/global_config/makefile-generator/scripts/add_standard_targets.sh +539 -0
  163. package/skills/global_config/makefile-generator/scripts/generate_makefile_template.sh +690 -0
  164. package/skills/global_config/makefile-generator/test/test_helper_scripts.sh +190 -0
  165. package/skills/global_config/makefile-validator/SKILL.md +244 -0
  166. package/skills/global_config/makefile-validator/docs/bake-tool.md +1000 -0
  167. package/skills/global_config/makefile-validator/docs/best-practices.md +858 -0
  168. package/skills/global_config/makefile-validator/docs/common-mistakes.md +944 -0
  169. package/skills/global_config/makefile-validator/examples/bad-makefile.mk +77 -0
  170. package/skills/global_config/makefile-validator/examples/good-makefile.mk +103 -0
  171. package/skills/global_config/makefile-validator/scripts/test_validate.sh +382 -0
  172. package/skills/global_config/makefile-validator/scripts/validate_makefile.sh +712 -0
  173. package/skills/global_config/{MCP_Manage → mcp-manage}/SKILL.md +3 -3
  174. package/skills/global_config/plan-canvas/SKILL.md +9 -2
  175. package/skills/global_config/plan-canvas/scripts/lib/plan-canvas/ui.js +10 -2
  176. package/skills/global_config/plan-canvas/scripts/plan-canvas.js +1 -1
  177. package/skills/global_config/read-the-damn-docs/SKILL.md +175 -0
  178. package/skills/global_config/requesting-code-review/SKILL.md +98 -0
  179. package/skills/global_config/requesting-code-review/code-reviewer.md +198 -0
  180. package/skills/global_config/using-git-worktrees/SKILL.md +170 -0
  181. package/skills/global_config/verification-before-completion/SKILL.md +123 -0
  182. package/skills/global_config/writing-plans/SKILL.md +126 -46
  183. package/skills/global_config/writing-plans-legacy/SKILL.md +152 -0
  184. package/.claude/CLAUDE.md +0 -12
  185. package/mcps/RhinoMCP/docs/content/docs/getting-started/gemini.md +0 -61
  186. /package/{GEMINI.md → RULES.md} +0 -0
@@ -0,0 +1,172 @@
1
+ #!/usr/bin/env bash
2
+ # Generate a production-ready Go Dockerfile with multi-stage build
3
+
4
+ set -euo pipefail
5
+
6
+ # Default values
7
+ GO_VERSION="${GO_VERSION:-1.21}"
8
+ PORT="${PORT:-8080}"
9
+ OUTPUT_FILE="${OUTPUT_FILE:-Dockerfile}"
10
+ BINARY_NAME="${BINARY_NAME:-app}"
11
+ USE_DISTROLESS="${USE_DISTROLESS:-true}"
12
+
13
+ # Usage
14
+ usage() {
15
+ cat <<EOF
16
+ Usage: $0 [OPTIONS]
17
+
18
+ Generate a production-ready Go Dockerfile with multi-stage build.
19
+
20
+ OPTIONS:
21
+ -v, --version VERSION Go version (default: 1.21)
22
+ -p, --port PORT Port to expose (default: 8080)
23
+ -o, --output FILE Output file (default: Dockerfile)
24
+ -b, --binary NAME Binary name (default: app)
25
+ --alpine Use Alpine instead of distroless
26
+ -h, --help Show this help message
27
+
28
+ EXAMPLES:
29
+ # Basic Go app with distroless
30
+ $0
31
+
32
+ # Go app with Alpine base
33
+ $0 --alpine --port 8080
34
+
35
+ # Custom binary name
36
+ $0 --binary myapp --version 1.22
37
+
38
+ EOF
39
+ exit 0
40
+ }
41
+
42
+ # Parse arguments
43
+ while [[ $# -gt 0 ]]; do
44
+ case $1 in
45
+ -v|--version)
46
+ GO_VERSION="$2"
47
+ shift 2
48
+ ;;
49
+ -p|--port)
50
+ PORT="$2"
51
+ shift 2
52
+ ;;
53
+ -o|--output)
54
+ OUTPUT_FILE="$2"
55
+ shift 2
56
+ ;;
57
+ -b|--binary)
58
+ BINARY_NAME="$2"
59
+ shift 2
60
+ ;;
61
+ --alpine)
62
+ USE_DISTROLESS="false"
63
+ shift
64
+ ;;
65
+ -h|--help)
66
+ usage
67
+ ;;
68
+ *)
69
+ echo "Unknown option: $1"
70
+ usage
71
+ ;;
72
+ esac
73
+ done
74
+
75
+ # Generate Dockerfile based on base image choice
76
+ if [ "$USE_DISTROLESS" = "true" ]; then
77
+ cat > "$OUTPUT_FILE" <<'EOF'
78
+ # syntax=docker/dockerfile:1
79
+
80
+ # Build stage
81
+ FROM golang:GO_VERSION-alpine AS builder
82
+ WORKDIR /app
83
+
84
+ # Copy go mod files
85
+ COPY go.mod go.sum ./
86
+ RUN go mod download
87
+
88
+ # Copy source code
89
+ COPY . .
90
+
91
+ # Build the application
92
+ RUN CGO_ENABLED=0 GOOS=linux go build -a -ldflags="-s -w" -o /BINARY_NAME .
93
+
94
+ # Production stage (using distroless for minimal image)
95
+ # gcr.io/distroless/static-debian12 IS a specific tag; hadolint DL3006 is a
96
+ # false positive for non-Docker-Hub registries.
97
+ # hadolint ignore=DL3006
98
+ FROM gcr.io/distroless/static-debian12 AS production
99
+ WORKDIR /
100
+
101
+ # Copy binary from builder
102
+ COPY --from=builder /BINARY_NAME /BINARY_NAME
103
+
104
+ # Expose port
105
+ EXPOSE PORT_NUMBER
106
+
107
+ # Switch to non-root user (distroless runs as nonroot by default)
108
+ USER nonroot:nonroot
109
+
110
+ # Start application
111
+ ENTRYPOINT ["/BINARY_NAME"]
112
+ EOF
113
+ else
114
+ cat > "$OUTPUT_FILE" <<'EOF'
115
+ # syntax=docker/dockerfile:1
116
+
117
+ # Build stage
118
+ FROM golang:GO_VERSION-alpine AS builder
119
+ WORKDIR /app
120
+
121
+ # Copy go mod files
122
+ COPY go.mod go.sum ./
123
+ RUN go mod download
124
+
125
+ # Copy source code
126
+ COPY . .
127
+
128
+ # Build the application
129
+ RUN CGO_ENABLED=0 GOOS=linux go build -a -ldflags="-s -w" -o /BINARY_NAME .
130
+
131
+ # Production stage (using Alpine)
132
+ FROM alpine:3.21 AS production
133
+ WORKDIR /app
134
+
135
+ # Install ca-certificates for HTTPS
136
+ RUN apk --no-cache add ca-certificates
137
+
138
+ # Create non-root user
139
+ RUN addgroup -g 1001 -S appgroup && \
140
+ adduser -S app -u 1001 -G appgroup
141
+
142
+ # Copy binary from builder
143
+ COPY --from=builder /BINARY_NAME /app/BINARY_NAME
144
+
145
+ # Switch to non-root user
146
+ USER app
147
+
148
+ # Expose port
149
+ EXPOSE PORT_NUMBER
150
+
151
+ # Health check
152
+ HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
153
+ CMD wget --no-verbose --tries=1 --spider http://localhost:PORT_NUMBER/health || exit 1
154
+
155
+ # Start application
156
+ ENTRYPOINT ["/app/BINARY_NAME"]
157
+ EOF
158
+ fi
159
+
160
+ # Replace placeholders
161
+ sed -i.bak "s/GO_VERSION/$GO_VERSION/g" "$OUTPUT_FILE"
162
+ sed -i.bak "s/PORT_NUMBER/$PORT/g" "$OUTPUT_FILE"
163
+ sed -i.bak "s/BINARY_NAME/$BINARY_NAME/g" "$OUTPUT_FILE"
164
+
165
+ # Clean up backup files
166
+ rm -f "${OUTPUT_FILE}.bak"
167
+
168
+ echo "✓ Generated Go Dockerfile: $OUTPUT_FILE"
169
+ echo " Go version: $GO_VERSION"
170
+ echo " Port: $PORT"
171
+ echo " Binary name: $BINARY_NAME"
172
+ echo " Base image: $([ "$USE_DISTROLESS" = "true" ] && echo "distroless" || echo "alpine")"
@@ -0,0 +1,185 @@
1
+ #!/usr/bin/env bash
2
+ # Generate a production-ready Java Dockerfile with multi-stage build
3
+
4
+ set -euo pipefail
5
+
6
+ # Default values
7
+ JAVA_VERSION="${JAVA_VERSION:-21}"
8
+ PORT="${PORT:-8080}"
9
+ OUTPUT_FILE="${OUTPUT_FILE:-Dockerfile}"
10
+ BUILD_TOOL="${BUILD_TOOL:-maven}"
11
+
12
+ # Usage
13
+ usage() {
14
+ cat <<EOF
15
+ Usage: $0 [OPTIONS]
16
+
17
+ Generate a production-ready Java Dockerfile with multi-stage build.
18
+
19
+ OPTIONS:
20
+ -v, --version VERSION Java version (default: 21)
21
+ -p, --port PORT Port to expose (default: 8080)
22
+ -o, --output FILE Output file (default: Dockerfile)
23
+ -t, --tool TOOL Build tool: maven or gradle (default: maven)
24
+ -h, --help Show this help message
25
+
26
+ EXAMPLES:
27
+ # Spring Boot with Maven
28
+ $0
29
+
30
+ # Spring Boot with Gradle
31
+ $0 --tool gradle --version 21
32
+
33
+ # Custom port
34
+ $0 --port 9090 --tool maven
35
+
36
+ EOF
37
+ exit 0
38
+ }
39
+
40
+ # Parse arguments
41
+ while [[ $# -gt 0 ]]; do
42
+ case $1 in
43
+ -v|--version)
44
+ JAVA_VERSION="$2"
45
+ shift 2
46
+ ;;
47
+ -p|--port)
48
+ PORT="$2"
49
+ shift 2
50
+ ;;
51
+ -o|--output)
52
+ OUTPUT_FILE="$2"
53
+ shift 2
54
+ ;;
55
+ -t|--tool)
56
+ BUILD_TOOL="$2"
57
+ shift 2
58
+ ;;
59
+ -h|--help)
60
+ usage
61
+ ;;
62
+ *)
63
+ echo "Unknown option: $1"
64
+ usage
65
+ ;;
66
+ esac
67
+ done
68
+
69
+ # Validate build tool
70
+ if [ "$BUILD_TOOL" != "maven" ] && [ "$BUILD_TOOL" != "gradle" ]; then
71
+ echo "Error: Build tool must be 'maven' or 'gradle'"
72
+ exit 1
73
+ fi
74
+
75
+ # Generate Dockerfile based on build tool
76
+ if [ "$BUILD_TOOL" = "maven" ]; then
77
+ cat > "$OUTPUT_FILE" <<'EOF'
78
+ # syntax=docker/dockerfile:1
79
+
80
+ # Build stage
81
+ FROM eclipse-temurin:JAVA_VERSION-jdk-jammy AS builder
82
+ WORKDIR /app
83
+
84
+ # Copy Maven wrapper and pom.xml
85
+ COPY mvnw pom.xml ./
86
+ COPY .mvn .mvn
87
+
88
+ # Download dependencies (cached layer)
89
+ RUN ./mvnw dependency:go-offline
90
+
91
+ # Copy source code
92
+ COPY src ./src
93
+
94
+ # Build application
95
+ RUN ./mvnw clean package -DskipTests && \
96
+ mv target/*.jar target/app.jar
97
+
98
+ # Production stage (using JRE instead of JDK)
99
+ FROM eclipse-temurin:JAVA_VERSION-jre-jammy AS production
100
+ WORKDIR /app
101
+
102
+ # Install healthcheck dependency and create non-root user
103
+ # hadolint ignore=DL3008
104
+ RUN apt-get update && apt-get install -y --no-install-recommends curl && \
105
+ rm -rf /var/lib/apt/lists/* && \
106
+ useradd -m -u 1001 app
107
+
108
+ # Copy JAR from builder
109
+ COPY --from=builder --chown=app:app /app/target/app.jar ./app.jar
110
+
111
+ # Switch to non-root user
112
+ USER app
113
+
114
+ # Expose port
115
+ EXPOSE PORT_NUMBER
116
+
117
+ # Health check
118
+ HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \
119
+ CMD curl -f http://localhost:PORT_NUMBER/actuator/health || exit 1
120
+
121
+ # Start application
122
+ ENTRYPOINT ["java", "-jar", "app.jar"]
123
+ EOF
124
+ else
125
+ cat > "$OUTPUT_FILE" <<'EOF'
126
+ # syntax=docker/dockerfile:1
127
+
128
+ # Build stage
129
+ FROM eclipse-temurin:JAVA_VERSION-jdk-jammy AS builder
130
+ WORKDIR /app
131
+
132
+ # Copy Gradle wrapper and build files
133
+ COPY gradlew ./
134
+ COPY gradle gradle
135
+ COPY build.gradle settings.gradle ./
136
+
137
+ # Download dependencies (cached layer)
138
+ RUN ./gradlew dependencies --no-daemon
139
+
140
+ # Copy source code
141
+ COPY src ./src
142
+
143
+ # Build application
144
+ RUN ./gradlew build -x test --no-daemon && \
145
+ mv build/libs/*.jar build/libs/app.jar
146
+
147
+ # Production stage (using JRE instead of JDK)
148
+ FROM eclipse-temurin:JAVA_VERSION-jre-jammy AS production
149
+ WORKDIR /app
150
+
151
+ # Install healthcheck dependency and create non-root user
152
+ # hadolint ignore=DL3008
153
+ RUN apt-get update && apt-get install -y --no-install-recommends curl && \
154
+ rm -rf /var/lib/apt/lists/* && \
155
+ useradd -m -u 1001 app
156
+
157
+ # Copy JAR from builder
158
+ COPY --from=builder --chown=app:app /app/build/libs/app.jar ./app.jar
159
+
160
+ # Switch to non-root user
161
+ USER app
162
+
163
+ # Expose port
164
+ EXPOSE PORT_NUMBER
165
+
166
+ # Health check
167
+ HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \
168
+ CMD curl -f http://localhost:PORT_NUMBER/actuator/health || exit 1
169
+
170
+ # Start application
171
+ ENTRYPOINT ["java", "-jar", "app.jar"]
172
+ EOF
173
+ fi
174
+
175
+ # Replace placeholders
176
+ sed -i.bak "s/JAVA_VERSION/$JAVA_VERSION/g" "$OUTPUT_FILE"
177
+ sed -i.bak "s/PORT_NUMBER/$PORT/g" "$OUTPUT_FILE"
178
+
179
+ # Clean up backup files
180
+ rm -f "${OUTPUT_FILE}.bak"
181
+
182
+ echo "✓ Generated Java Dockerfile: $OUTPUT_FILE"
183
+ echo " Java version: $JAVA_VERSION"
184
+ echo " Port: $PORT"
185
+ echo " Build tool: $BUILD_TOOL"
@@ -0,0 +1,279 @@
1
+ #!/usr/bin/env bash
2
+ # Generate a production-ready Node.js Dockerfile with multi-stage build
3
+
4
+ set -euo pipefail
5
+
6
+ # Default values
7
+ NODE_VERSION="${NODE_VERSION:-20}"
8
+ PORT="${PORT:-3000}"
9
+ OUTPUT_FILE="${OUTPUT_FILE:-Dockerfile}"
10
+ LEGACY_ENTRY="${APP_ENTRY:-index.js}"
11
+ LEGACY_ENTRY_SET="false"
12
+ ENTRY_CMD="${ENTRY_CMD:-}"
13
+ ENTRY_ARGS=()
14
+ BUILD_STAGE="${BUILD_STAGE:-false}"
15
+
16
+ # Usage
17
+ usage() {
18
+ cat <<EOF
19
+ Usage: $0 [OPTIONS]
20
+
21
+ Generate a production-ready Node.js Dockerfile with multi-stage build.
22
+
23
+ OPTIONS:
24
+ -v, --version VERSION Node.js version (default: 20)
25
+ -p, --port PORT Port to expose (default: 3000)
26
+ -o, --output FILE Output file (default: Dockerfile)
27
+ -e, --entry COMMAND Legacy entry syntax (simple whitespace split only)
28
+ --entry-cmd COMMAND Preferred command binary/executable
29
+ --entry-arg ARG Preferred command argument (repeatable; preserves spaces)
30
+ -b, --build Include build stage for compilation (installs all deps, runs npm run build, prunes dev deps)
31
+ -h, --help Show this help message
32
+
33
+ EXAMPLES:
34
+ # Basic Node.js app
35
+ $0
36
+
37
+ # Next.js app with build stage
38
+ $0 --version 20 --port 3000 --build --entry "npm start"
39
+
40
+ # Preferred structured entrypoint (preserves quoted args exactly)
41
+ $0 --entry-cmd node --entry-arg server.js --entry-arg --message --entry-arg "hello world"
42
+
43
+ # Custom port and legacy entry point
44
+ $0 --port 8080 --entry "server.js"
45
+
46
+ EOF
47
+ exit 0
48
+ }
49
+
50
+ # Parse arguments
51
+ while [[ $# -gt 0 ]]; do
52
+ case $1 in
53
+ -v|--version)
54
+ NODE_VERSION="$2"
55
+ shift 2
56
+ ;;
57
+ -p|--port)
58
+ PORT="$2"
59
+ shift 2
60
+ ;;
61
+ -o|--output)
62
+ OUTPUT_FILE="$2"
63
+ shift 2
64
+ ;;
65
+ -e|--entry)
66
+ LEGACY_ENTRY="$2"
67
+ LEGACY_ENTRY_SET="true"
68
+ shift 2
69
+ ;;
70
+ --entry-cmd)
71
+ ENTRY_CMD="$2"
72
+ shift 2
73
+ ;;
74
+ --entry-arg)
75
+ ENTRY_ARGS+=("$2")
76
+ shift 2
77
+ ;;
78
+ -b|--build)
79
+ BUILD_STAGE="true"
80
+ shift
81
+ ;;
82
+ -h|--help)
83
+ usage
84
+ ;;
85
+ *)
86
+ echo "Unknown option: $1"
87
+ usage
88
+ ;;
89
+ esac
90
+ done
91
+
92
+ # Escape values that are inserted into JSON-form CMD arrays.
93
+ escape_json_string() {
94
+ local input="$1"
95
+ input="${input//\\/\\\\}"
96
+ input="${input//\"/\\\"}"
97
+ printf '%s' "$input"
98
+ }
99
+
100
+ # Escape values that are inserted into sed replacement strings.
101
+ escape_sed_replacement() {
102
+ local input="$1"
103
+ input="${input//\\/\\\\}"
104
+ input="${input//&/\\&}"
105
+ input="${input//|/\\|}"
106
+ printf '%s' "$input"
107
+ }
108
+
109
+ # Validate mutually exclusive entrypoint interfaces.
110
+ if [[ -n "$ENTRY_CMD" && "$LEGACY_ENTRY_SET" == "true" ]]; then
111
+ echo "ERROR: use either --entry or --entry-cmd/--entry-arg, not both." >&2
112
+ exit 1
113
+ fi
114
+
115
+ if [[ -z "$ENTRY_CMD" && ${#ENTRY_ARGS[@]} -gt 0 ]]; then
116
+ echo "ERROR: --entry-arg requires --entry-cmd." >&2
117
+ exit 1
118
+ fi
119
+
120
+ # Build CMD instruction.
121
+ # Preferred mode:
122
+ # --entry-cmd <cmd> --entry-arg <arg> --entry-arg <arg>
123
+ # Legacy mode:
124
+ # --entry "<simple whitespace-delimited command>"
125
+ # Quoted legacy entries are rejected because they cannot be parsed safely.
126
+ if [[ -n "$ENTRY_CMD" ]]; then
127
+ CMD_PARTS=("$ENTRY_CMD" "${ENTRY_ARGS[@]}")
128
+ else
129
+ if [[ "$LEGACY_ENTRY" == *"\""* || "$LEGACY_ENTRY" == *"'"* ]]; then
130
+ echo "ERROR: quoted --entry values are not supported. Use --entry-cmd/--entry-arg." >&2
131
+ exit 1
132
+ fi
133
+
134
+ if [[ "$LEGACY_ENTRY" =~ [[:space:]] ]]; then
135
+ read -r -a CMD_PARTS <<< "$LEGACY_ENTRY"
136
+ else
137
+ CMD_PARTS=("node" "$LEGACY_ENTRY")
138
+ fi
139
+ fi
140
+
141
+ if [[ -z "${CMD_PARTS[0]:-}" ]]; then
142
+ echo "ERROR: entry command cannot be empty." >&2
143
+ exit 1
144
+ fi
145
+
146
+ _json_parts=()
147
+ for _token in "${CMD_PARTS[@]}"; do
148
+ _json_parts+=("\"$(escape_json_string "$_token")\"")
149
+ done
150
+ CMD_INSTRUCTION="CMD [$(IFS=', '; echo "${_json_parts[*]}")]"
151
+ CMD_INSTRUCTION_SED="$(escape_sed_replacement "$CMD_INSTRUCTION")"
152
+
153
+ # Generate Dockerfile — two templates to avoid complex sed escaping around &&.
154
+ # The build template installs ALL deps (including dev) so that build tools like
155
+ # tsc, vite, webpack etc. are available, then prunes dev deps after the build so
156
+ # the production stage receives a clean node_modules.
157
+ if [ "$BUILD_STAGE" = "true" ]; then
158
+ cat > "$OUTPUT_FILE" <<'EOF'
159
+ # syntax=docker/dockerfile:1
160
+
161
+ # Build stage — install all deps (including devDependencies) required by the
162
+ # build step, compile the application, then prune to production-only deps.
163
+ FROM node:NODE_VERSION-alpine AS builder
164
+ WORKDIR /app
165
+
166
+ # Copy dependency files for caching
167
+ COPY package*.json ./
168
+
169
+ # Install all dependencies (including devDependencies needed for build)
170
+ RUN npm ci && \
171
+ npm cache clean --force
172
+
173
+ # Copy application code
174
+ COPY . .
175
+
176
+ # Build application and prune dev dependencies so the production stage
177
+ # receives only what is needed at runtime.
178
+ RUN npm run build && \
179
+ npm prune --omit=dev
180
+
181
+ # Production stage
182
+ FROM node:NODE_VERSION-alpine AS production
183
+ WORKDIR /app
184
+
185
+ # Set production environment
186
+ ENV NODE_ENV=production
187
+
188
+ # Create non-root user
189
+ RUN addgroup -g 1001 -S nodejs && \
190
+ adduser -S nodejs -u 1001
191
+
192
+ # Copy pruned node_modules and built application from builder
193
+ COPY --from=builder --chown=nodejs:nodejs /app/node_modules ./node_modules
194
+ COPY --from=builder --chown=nodejs:nodejs /app .
195
+
196
+ # Switch to non-root user
197
+ USER nodejs
198
+
199
+ # Expose port
200
+ EXPOSE PORT_NUMBER
201
+
202
+ # Health check
203
+ HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
204
+ CMD node -e "require('http').get('http://localhost:PORT_NUMBER/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})" || exit 1
205
+
206
+ # Start application
207
+ CMD_INSTRUCTION_PLACEHOLDER
208
+ EOF
209
+ else
210
+ cat > "$OUTPUT_FILE" <<'EOF'
211
+ # syntax=docker/dockerfile:1
212
+
213
+ # Build stage
214
+ FROM node:NODE_VERSION-alpine AS builder
215
+ WORKDIR /app
216
+
217
+ # Copy dependency files for caching
218
+ COPY package*.json ./
219
+
220
+ # Install production dependencies only
221
+ RUN npm ci --omit=dev && \
222
+ npm cache clean --force
223
+
224
+ # Copy application code
225
+ COPY . .
226
+
227
+ # Production stage
228
+ FROM node:NODE_VERSION-alpine AS production
229
+ WORKDIR /app
230
+
231
+ # Set production environment
232
+ ENV NODE_ENV=production
233
+
234
+ # Create non-root user
235
+ RUN addgroup -g 1001 -S nodejs && \
236
+ adduser -S nodejs -u 1001
237
+
238
+ # Copy dependencies from builder
239
+ COPY --from=builder --chown=nodejs:nodejs /app/node_modules ./node_modules
240
+
241
+ # Copy application from builder
242
+ COPY --chown=nodejs:nodejs . .
243
+
244
+ # Switch to non-root user
245
+ USER nodejs
246
+
247
+ # Expose port
248
+ EXPOSE PORT_NUMBER
249
+
250
+ # Health check
251
+ HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
252
+ CMD node -e "require('http').get('http://localhost:PORT_NUMBER/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})" || exit 1
253
+
254
+ # Start application
255
+ CMD_INSTRUCTION_PLACEHOLDER
256
+ EOF
257
+ fi
258
+
259
+ # Replace placeholders
260
+ sed -i.bak "s/NODE_VERSION/$NODE_VERSION/g" "$OUTPUT_FILE"
261
+ sed -i.bak "s/PORT_NUMBER/$PORT/g" "$OUTPUT_FILE"
262
+ sed -i.bak "s|CMD_INSTRUCTION_PLACEHOLDER|$CMD_INSTRUCTION_SED|g" "$OUTPUT_FILE"
263
+
264
+ # Clean up backup files
265
+ rm -f "${OUTPUT_FILE}.bak"
266
+
267
+ echo "✓ Generated Node.js Dockerfile: $OUTPUT_FILE"
268
+ echo " Node version: $NODE_VERSION"
269
+ echo " Port: $PORT"
270
+ if [[ -n "$ENTRY_CMD" ]]; then
271
+ ENTRY_DISPLAY="$ENTRY_CMD"
272
+ for _arg in "${ENTRY_ARGS[@]}"; do
273
+ ENTRY_DISPLAY+=" $(printf '%q' "$_arg")"
274
+ done
275
+ else
276
+ ENTRY_DISPLAY="$LEGACY_ENTRY"
277
+ fi
278
+ echo " Entry point: $ENTRY_DISPLAY"
279
+ echo " Build stage: $BUILD_STAGE"