javi-forge 1.6.0 → 1.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (231) hide show
  1. package/dist/commands/analyze.d.ts +1 -1
  2. package/dist/commands/analyze.js +15 -15
  3. package/dist/commands/atlassian-mcp.d.ts +42 -0
  4. package/dist/commands/atlassian-mcp.js +98 -0
  5. package/dist/commands/ci.d.ts +3 -3
  6. package/dist/commands/ci.js +185 -147
  7. package/dist/commands/crash-recovery.d.ts +34 -0
  8. package/dist/commands/crash-recovery.js +123 -0
  9. package/dist/commands/doctor.d.ts +2 -2
  10. package/dist/commands/doctor.js +113 -61
  11. package/dist/commands/harness-audit.d.ts +35 -0
  12. package/dist/commands/harness-audit.js +277 -0
  13. package/dist/commands/init.d.ts +1 -1
  14. package/dist/commands/init.js +384 -141
  15. package/dist/commands/llmstxt.d.ts +1 -1
  16. package/dist/commands/llmstxt.js +36 -34
  17. package/dist/commands/parallel-batch.d.ts +42 -0
  18. package/dist/commands/parallel-batch.js +90 -0
  19. package/dist/commands/plugin.d.ts +10 -1
  20. package/dist/commands/plugin.js +92 -47
  21. package/dist/commands/secret-scanner.d.ts +30 -0
  22. package/dist/commands/secret-scanner.js +272 -0
  23. package/dist/commands/security-analysis.d.ts +74 -0
  24. package/dist/commands/security-analysis.js +487 -0
  25. package/dist/commands/security.d.ts +11 -5
  26. package/dist/commands/security.js +216 -76
  27. package/dist/commands/skill-scanner.d.ts +63 -0
  28. package/dist/commands/skill-scanner.js +383 -0
  29. package/dist/commands/skills.d.ts +62 -5
  30. package/dist/commands/skills.js +439 -54
  31. package/dist/commands/supply-chain.d.ts +23 -0
  32. package/dist/commands/supply-chain.js +126 -0
  33. package/dist/commands/tdd-pipeline.d.ts +17 -0
  34. package/dist/commands/tdd-pipeline.js +144 -0
  35. package/dist/commands/tdd.d.ts +1 -1
  36. package/dist/commands/tdd.js +21 -18
  37. package/dist/commands/team-presets.d.ts +53 -0
  38. package/dist/commands/team-presets.js +201 -0
  39. package/dist/commands/workflow.d.ts +23 -0
  40. package/dist/commands/workflow.js +114 -0
  41. package/dist/constants.d.ts +15 -1
  42. package/dist/constants.js +161 -122
  43. package/dist/index.js +308 -98
  44. package/dist/lib/agent-skills.d.ts +36 -1
  45. package/dist/lib/agent-skills.js +168 -19
  46. package/dist/lib/auto-skill-install.d.ts +37 -0
  47. package/dist/lib/auto-skill-install.js +92 -0
  48. package/dist/lib/auto-wire.d.ts +20 -0
  49. package/dist/lib/auto-wire.js +240 -0
  50. package/dist/lib/claudemd.d.ts +13 -1
  51. package/dist/lib/claudemd.js +174 -24
  52. package/dist/lib/codex-export.d.ts +1 -1
  53. package/dist/lib/codex-export.js +29 -31
  54. package/dist/lib/common.d.ts +1 -1
  55. package/dist/lib/common.js +52 -44
  56. package/dist/lib/context.d.ts +17 -2
  57. package/dist/lib/context.js +142 -13
  58. package/dist/lib/docker.d.ts +1 -1
  59. package/dist/lib/docker.js +141 -112
  60. package/dist/lib/frontmatter.d.ts +1 -1
  61. package/dist/lib/frontmatter.js +29 -15
  62. package/dist/lib/plugin.d.ts +9 -3
  63. package/dist/lib/plugin.js +128 -69
  64. package/dist/lib/skill-publish.d.ts +40 -0
  65. package/dist/lib/skill-publish.js +146 -0
  66. package/dist/lib/stack-detector.d.ts +38 -0
  67. package/dist/lib/stack-detector.js +207 -0
  68. package/dist/lib/template.d.ts +16 -1
  69. package/dist/lib/template.js +46 -17
  70. package/dist/lib/workflow/discovery.d.ts +19 -0
  71. package/dist/lib/workflow/discovery.js +68 -0
  72. package/dist/lib/workflow/index.d.ts +5 -0
  73. package/dist/lib/workflow/index.js +5 -0
  74. package/dist/lib/workflow/parser.d.ts +16 -0
  75. package/dist/lib/workflow/parser.js +198 -0
  76. package/dist/lib/workflow/renderer.d.ts +9 -0
  77. package/dist/lib/workflow/renderer.js +152 -0
  78. package/dist/lib/workflow/validator.d.ts +10 -0
  79. package/dist/lib/workflow/validator.js +189 -0
  80. package/dist/tasks/index.d.ts +4 -0
  81. package/dist/tasks/index.js +4 -0
  82. package/dist/tasks/scaffold-tasks.d.ts +3 -0
  83. package/dist/tasks/scaffold-tasks.js +14 -0
  84. package/dist/tasks/task-id.d.ts +30 -0
  85. package/dist/tasks/task-id.js +55 -0
  86. package/dist/tasks/task-tracker.d.ts +15 -0
  87. package/dist/tasks/task-tracker.js +81 -0
  88. package/dist/types/index.d.ts +134 -6
  89. package/dist/types/index.js +11 -1
  90. package/dist/ui/AnalyzeUI.d.ts +1 -1
  91. package/dist/ui/AnalyzeUI.js +38 -39
  92. package/dist/ui/App.d.ts +5 -3
  93. package/dist/ui/App.js +86 -46
  94. package/dist/ui/AutoSkills.d.ts +9 -0
  95. package/dist/ui/AutoSkills.js +124 -0
  96. package/dist/ui/CI.d.ts +2 -2
  97. package/dist/ui/CI.js +24 -26
  98. package/dist/ui/CIContext.d.ts +1 -1
  99. package/dist/ui/CIContext.js +3 -2
  100. package/dist/ui/CISelector.d.ts +2 -2
  101. package/dist/ui/CISelector.js +23 -15
  102. package/dist/ui/Doctor.d.ts +1 -1
  103. package/dist/ui/Doctor.js +35 -29
  104. package/dist/ui/Header.d.ts +1 -1
  105. package/dist/ui/Header.js +14 -14
  106. package/dist/ui/HookProfileSelector.d.ts +9 -0
  107. package/dist/ui/HookProfileSelector.js +54 -0
  108. package/dist/ui/LlmsTxt.d.ts +1 -1
  109. package/dist/ui/LlmsTxt.js +31 -22
  110. package/dist/ui/MemorySelector.d.ts +2 -2
  111. package/dist/ui/MemorySelector.js +28 -16
  112. package/dist/ui/NameInput.d.ts +1 -1
  113. package/dist/ui/NameInput.js +21 -21
  114. package/dist/ui/OptionSelector.d.ts +6 -2
  115. package/dist/ui/OptionSelector.js +83 -32
  116. package/dist/ui/Plugin.d.ts +4 -3
  117. package/dist/ui/Plugin.js +78 -35
  118. package/dist/ui/Progress.d.ts +3 -3
  119. package/dist/ui/Progress.js +23 -22
  120. package/dist/ui/Skills.d.ts +2 -2
  121. package/dist/ui/Skills.js +61 -32
  122. package/dist/ui/StackSelector.d.ts +2 -2
  123. package/dist/ui/StackSelector.js +26 -16
  124. package/dist/ui/Summary.d.ts +3 -3
  125. package/dist/ui/Summary.js +60 -50
  126. package/dist/ui/Welcome.d.ts +1 -1
  127. package/dist/ui/Welcome.js +15 -16
  128. package/dist/ui/theme.d.ts +1 -1
  129. package/dist/ui/theme.js +6 -6
  130. package/package.json +9 -6
  131. package/templates/common/atlassian/mcp-atlassian-snippet.json +16 -0
  132. package/templates/common/repoforge/mcp-repoforge-snippet.json +11 -0
  133. package/templates/common/repoforge/repoforge.yaml +34 -0
  134. package/templates/github/deploy-docker-zero-downtime.yml +140 -0
  135. package/templates/github/repoforge-graph.yml +45 -0
  136. package/templates/gitlab/deploy-docker-zero-downtime.yml +57 -0
  137. package/templates/local-ai/.env.example +17 -0
  138. package/templates/local-ai/docker-compose.yml +95 -0
  139. package/templates/security-hooks/claude-settings-security.json +30 -0
  140. package/templates/security-hooks/commit-msg-signing +29 -0
  141. package/templates/security-hooks/pre-commit-permissions +74 -0
  142. package/templates/security-hooks/pre-commit-secrets +74 -0
  143. package/templates/security-hooks/pre-push-branch-protection +62 -0
  144. package/templates/security-hooks/pre-push-deps +83 -0
  145. package/templates/security-hooks/pre-push-signing +67 -0
  146. package/templates/woodpecker/deploy-docker-zero-downtime.yml +50 -0
  147. package/templates/workflows/ci-pipeline.dot +15 -0
  148. package/templates/workflows/feature-flow.dot +21 -0
  149. package/templates/workflows/release.dot +16 -0
  150. package/dist/__integration__/helpers.d.ts +0 -20
  151. package/dist/__integration__/helpers.d.ts.map +0 -1
  152. package/dist/__integration__/helpers.js +0 -31
  153. package/dist/__integration__/helpers.js.map +0 -1
  154. package/dist/commands/analyze.d.ts.map +0 -1
  155. package/dist/commands/analyze.js.map +0 -1
  156. package/dist/commands/ci.d.ts.map +0 -1
  157. package/dist/commands/ci.js.map +0 -1
  158. package/dist/commands/doctor.d.ts.map +0 -1
  159. package/dist/commands/doctor.js.map +0 -1
  160. package/dist/commands/init.d.ts.map +0 -1
  161. package/dist/commands/init.js.map +0 -1
  162. package/dist/commands/llmstxt.d.ts.map +0 -1
  163. package/dist/commands/llmstxt.js.map +0 -1
  164. package/dist/commands/plugin.d.ts.map +0 -1
  165. package/dist/commands/plugin.js.map +0 -1
  166. package/dist/commands/security.d.ts.map +0 -1
  167. package/dist/commands/security.js.map +0 -1
  168. package/dist/commands/skills.d.ts.map +0 -1
  169. package/dist/commands/skills.js.map +0 -1
  170. package/dist/commands/tdd.d.ts.map +0 -1
  171. package/dist/commands/tdd.js.map +0 -1
  172. package/dist/constants.d.ts.map +0 -1
  173. package/dist/constants.js.map +0 -1
  174. package/dist/index.d.ts.map +0 -1
  175. package/dist/index.js.map +0 -1
  176. package/dist/lib/agent-skills.d.ts.map +0 -1
  177. package/dist/lib/agent-skills.js.map +0 -1
  178. package/dist/lib/claudemd.d.ts.map +0 -1
  179. package/dist/lib/claudemd.js.map +0 -1
  180. package/dist/lib/codex-export.d.ts.map +0 -1
  181. package/dist/lib/codex-export.js.map +0 -1
  182. package/dist/lib/common.d.ts.map +0 -1
  183. package/dist/lib/common.js.map +0 -1
  184. package/dist/lib/context.d.ts.map +0 -1
  185. package/dist/lib/context.js.map +0 -1
  186. package/dist/lib/docker.d.ts.map +0 -1
  187. package/dist/lib/docker.js.map +0 -1
  188. package/dist/lib/frontmatter.d.ts.map +0 -1
  189. package/dist/lib/frontmatter.js.map +0 -1
  190. package/dist/lib/plugin.d.ts.map +0 -1
  191. package/dist/lib/plugin.js.map +0 -1
  192. package/dist/lib/template.d.ts.map +0 -1
  193. package/dist/lib/template.js.map +0 -1
  194. package/dist/types/index.d.ts.map +0 -1
  195. package/dist/types/index.js.map +0 -1
  196. package/dist/ui/AnalyzeUI.d.ts.map +0 -1
  197. package/dist/ui/AnalyzeUI.js.map +0 -1
  198. package/dist/ui/App.d.ts.map +0 -1
  199. package/dist/ui/App.js.map +0 -1
  200. package/dist/ui/CI.d.ts.map +0 -1
  201. package/dist/ui/CI.js.map +0 -1
  202. package/dist/ui/CIContext.d.ts.map +0 -1
  203. package/dist/ui/CIContext.js.map +0 -1
  204. package/dist/ui/CISelector.d.ts.map +0 -1
  205. package/dist/ui/CISelector.js.map +0 -1
  206. package/dist/ui/Doctor.d.ts.map +0 -1
  207. package/dist/ui/Doctor.js.map +0 -1
  208. package/dist/ui/Header.d.ts.map +0 -1
  209. package/dist/ui/Header.js.map +0 -1
  210. package/dist/ui/LlmsTxt.d.ts.map +0 -1
  211. package/dist/ui/LlmsTxt.js.map +0 -1
  212. package/dist/ui/MemorySelector.d.ts.map +0 -1
  213. package/dist/ui/MemorySelector.js.map +0 -1
  214. package/dist/ui/NameInput.d.ts.map +0 -1
  215. package/dist/ui/NameInput.js.map +0 -1
  216. package/dist/ui/OptionSelector.d.ts.map +0 -1
  217. package/dist/ui/OptionSelector.js.map +0 -1
  218. package/dist/ui/Plugin.d.ts.map +0 -1
  219. package/dist/ui/Plugin.js.map +0 -1
  220. package/dist/ui/Progress.d.ts.map +0 -1
  221. package/dist/ui/Progress.js.map +0 -1
  222. package/dist/ui/Skills.d.ts.map +0 -1
  223. package/dist/ui/Skills.js.map +0 -1
  224. package/dist/ui/StackSelector.d.ts.map +0 -1
  225. package/dist/ui/StackSelector.js.map +0 -1
  226. package/dist/ui/Summary.d.ts.map +0 -1
  227. package/dist/ui/Summary.js.map +0 -1
  228. package/dist/ui/Welcome.d.ts.map +0 -1
  229. package/dist/ui/Welcome.js.map +0 -1
  230. package/dist/ui/theme.d.ts.map +0 -1
  231. package/dist/ui/theme.js.map +0 -1
@@ -0,0 +1,140 @@
1
+ # ===========================================
2
+ # Zero-Downtime Docker Deploy (docker rollout)
3
+ # ===========================================
4
+ # Copy to: .github/workflows/deploy.yml
5
+ #
6
+ # Requires:
7
+ # - SSH access to the deploy target (secrets.DEPLOY_HOST, secrets.DEPLOY_USER, secrets.DEPLOY_KEY)
8
+ # - docker-rollout installed on the target: https://github.com/Wowu/docker-rollout
9
+ # - A docker-compose.yml on the target with healthcheck-enabled services
10
+ #
11
+ # Flow:
12
+ # 1. Build & push image to registry
13
+ # 2. SSH into deploy target
14
+ # 3. Pull new image
15
+ # 4. `docker rollout <service>` — spins up new container, waits for healthcheck, drains old
16
+ # ===========================================
17
+
18
+ name: Deploy (Zero-Downtime)
19
+
20
+ on:
21
+ push:
22
+ branches: [main]
23
+ paths-ignore:
24
+ - '**/*.md'
25
+ - '.gitignore'
26
+ workflow_dispatch:
27
+ inputs:
28
+ service:
29
+ description: 'Service to deploy (from docker-compose.yml)'
30
+ required: true
31
+ default: '__SERVICE_NAME__'
32
+ skip_build:
33
+ description: 'Skip image build (deploy existing latest)'
34
+ default: false
35
+ type: boolean
36
+
37
+ permissions:
38
+ contents: read
39
+ packages: write
40
+
41
+ concurrency:
42
+ group: deploy-${{ github.ref }}
43
+ cancel-in-progress: false # Never cancel in-progress deploys
44
+
45
+ env:
46
+ REGISTRY: ghcr.io
47
+ IMAGE_NAME: ${{ github.repository }}
48
+ DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
49
+ DEPLOY_USER: ${{ secrets.DEPLOY_USER }}
50
+
51
+ jobs:
52
+ build-and-push:
53
+ if: ${{ github.event.inputs.skip_build != 'true' }}
54
+ runs-on: ubuntu-latest
55
+ outputs:
56
+ image_tag: ${{ steps.meta.outputs.tags }}
57
+ steps:
58
+ - uses: actions/checkout@v4
59
+
60
+ - name: Log in to Container Registry
61
+ uses: docker/login-action@v3
62
+ with:
63
+ registry: ${{ env.REGISTRY }}
64
+ username: ${{ github.actor }}
65
+ password: ${{ secrets.GITHUB_TOKEN }}
66
+
67
+ - name: Extract metadata
68
+ id: meta
69
+ uses: docker/metadata-action@v5
70
+ with:
71
+ images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
72
+ tags: |
73
+ type=sha
74
+ type=raw,value=latest
75
+
76
+ - name: Build and push
77
+ uses: docker/build-push-action@v5
78
+ with:
79
+ context: .
80
+ push: true
81
+ tags: ${{ steps.meta.outputs.tags }}
82
+ labels: ${{ steps.meta.outputs.labels }}
83
+
84
+ deploy:
85
+ needs: [build-and-push]
86
+ if: always() && (needs.build-and-push.result == 'success' || github.event.inputs.skip_build == 'true')
87
+ runs-on: ubuntu-latest
88
+ environment: production
89
+ steps:
90
+ - name: Deploy via SSH + docker rollout
91
+ uses: appleboy/ssh-action@v1
92
+ with:
93
+ host: ${{ env.DEPLOY_HOST }}
94
+ username: ${{ env.DEPLOY_USER }}
95
+ key: ${{ secrets.DEPLOY_KEY }}
96
+ script: |
97
+ set -euo pipefail
98
+
99
+ cd ${{ secrets.DEPLOY_DIR || '~/app' }}
100
+
101
+ # Pull latest images
102
+ docker compose pull
103
+
104
+ # Zero-downtime rollout for the target service
105
+ SERVICE="${{ github.event.inputs.service || '__SERVICE_NAME__' }}"
106
+ echo "::group::Rolling out ${SERVICE}"
107
+ docker rollout "${SERVICE}"
108
+ echo "::endgroup::"
109
+
110
+ # Cleanup dangling images
111
+ docker image prune -f
112
+
113
+ - name: Verify deployment
114
+ uses: appleboy/ssh-action@v1
115
+ with:
116
+ host: ${{ env.DEPLOY_HOST }}
117
+ username: ${{ env.DEPLOY_USER }}
118
+ key: ${{ secrets.DEPLOY_KEY }}
119
+ script: |
120
+ set -euo pipefail
121
+ cd ${{ secrets.DEPLOY_DIR || '~/app' }}
122
+ SERVICE="${{ github.event.inputs.service || '__SERVICE_NAME__' }}"
123
+
124
+ # Wait for healthcheck (max 60s)
125
+ TIMEOUT=60
126
+ ELAPSED=0
127
+ while [ $ELAPSED -lt $TIMEOUT ]; do
128
+ HEALTH=$(docker compose ps "${SERVICE}" --format json | jq -r '.[0].Health // "none"' 2>/dev/null || echo "unknown")
129
+ if [ "$HEALTH" = "healthy" ]; then
130
+ echo "✅ ${SERVICE} is healthy"
131
+ exit 0
132
+ fi
133
+ sleep 5
134
+ ELAPSED=$((ELAPSED + 5))
135
+ echo "⏳ Waiting for healthcheck... (${ELAPSED}s/${TIMEOUT}s)"
136
+ done
137
+
138
+ echo "❌ ${SERVICE} did not become healthy within ${TIMEOUT}s"
139
+ docker compose logs --tail=50 "${SERVICE}"
140
+ exit 1
@@ -0,0 +1,45 @@
1
+ # ===========================================
2
+ # RepoForge Call Graph — keep graph fresh on every push
3
+ # ===========================================
4
+ # Copy to: .github/workflows/repoforge-graph.yml
5
+ # ===========================================
6
+
7
+ name: RepoForge Graph
8
+
9
+ on:
10
+ push:
11
+ branches: [main]
12
+ paths-ignore:
13
+ - '**/*.md'
14
+ - '.gitignore'
15
+ pull_request:
16
+ branches: [main]
17
+ paths-ignore:
18
+ - '**/*.md'
19
+ - '.gitignore'
20
+
21
+ permissions:
22
+ contents: read
23
+
24
+ concurrency:
25
+ group: repoforge-graph-${{ github.ref }}
26
+ cancel-in-progress: true
27
+
28
+ jobs:
29
+ graph:
30
+ runs-on: ubuntu-latest
31
+ steps:
32
+ - uses: actions/checkout@v4
33
+
34
+ - name: Install repoforge
35
+ run: npm install -g repoforge
36
+
37
+ - name: Generate call graph
38
+ run: repoforge graph --type calls --output .repoforge/call-graph.json
39
+
40
+ - name: Upload graph artifact
41
+ uses: actions/upload-artifact@v4
42
+ with:
43
+ name: call-graph
44
+ path: .repoforge/call-graph.json
45
+ retention-days: 30
@@ -0,0 +1,57 @@
1
+ # ===========================================
2
+ # Zero-Downtime Docker Deploy (docker rollout)
3
+ # ===========================================
4
+ # Merge into: .gitlab-ci.yml
5
+ #
6
+ # Requires:
7
+ # - CI/CD variables: DEPLOY_HOST, DEPLOY_USER, DEPLOY_KEY, DEPLOY_DIR
8
+ # - docker-rollout installed on target: https://github.com/Wowu/docker-rollout
9
+ # - A docker-compose.yml on the target with healthcheck-enabled services
10
+ # ===========================================
11
+
12
+ stages:
13
+ - build
14
+ - deploy
15
+
16
+ variables:
17
+ SERVICE_NAME: "__SERVICE_NAME__"
18
+
19
+ build-image:
20
+ stage: build
21
+ image: docker:latest
22
+ services:
23
+ - docker:dind
24
+ before_script:
25
+ - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"
26
+ script:
27
+ - docker build -t "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA" -t "$CI_REGISTRY_IMAGE:latest" .
28
+ - docker push "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA"
29
+ - docker push "$CI_REGISTRY_IMAGE:latest"
30
+ only:
31
+ - main
32
+
33
+ deploy-zero-downtime:
34
+ stage: deploy
35
+ image: alpine:latest
36
+ needs: ["build-image"]
37
+ before_script:
38
+ - apk add --no-cache openssh-client
39
+ - eval "$(ssh-agent -s)"
40
+ - echo "$DEPLOY_KEY" | ssh-add -
41
+ - mkdir -p ~/.ssh && chmod 700 ~/.ssh
42
+ - ssh-keyscan "$DEPLOY_HOST" >> ~/.ssh/known_hosts
43
+ script:
44
+ - |
45
+ ssh "$DEPLOY_USER@$DEPLOY_HOST" << 'ENDSSH'
46
+ set -euo pipefail
47
+ cd ${DEPLOY_DIR:-~/app}
48
+ docker compose pull
49
+ docker rollout "${SERVICE_NAME}"
50
+ docker image prune -f
51
+ echo "Deploy complete"
52
+ ENDSSH
53
+ environment:
54
+ name: production
55
+ only:
56
+ - main
57
+ when: manual
@@ -0,0 +1,17 @@
1
+ # Local AI Stack — Environment Variables
2
+ # Copy to .env in your project: cp .env.example .env
3
+
4
+ # ── Ollama ──────────────────────────────────────────────────────────────────
5
+ OLLAMA_PORT=11434
6
+
7
+ # ── Open WebUI ──────────────────────────────────────────────────────────────
8
+ WEBUI_PORT=3000
9
+ WEBUI_AUTH=false
10
+
11
+ # ── n8n ─────────────────────────────────────────────────────────────────────
12
+ N8N_PORT=5678
13
+
14
+ # ── Supabase (Postgres) ────────────────────────────────────────────────────
15
+ SUPABASE_DB_PORT=5432
16
+ SUPABASE_DB_PASSWORD=postgres
17
+ SUPABASE_DB_NAME=app
@@ -0,0 +1,95 @@
1
+ # Local AI Development Stack
2
+ # Generated by javi-forge — https://github.com/JNZader/javi-forge
3
+ #
4
+ # Usage:
5
+ # docker compose up -d # Start Ollama (core)
6
+ # docker compose --profile ui up -d # Start Ollama + Open WebUI
7
+ # docker compose --profile auto up -d # Start Ollama + n8n + Open WebUI
8
+ # docker compose --profile full up -d # Start everything
9
+ #
10
+ # Pull a model after starting:
11
+ # docker exec ollama ollama pull llama3.2
12
+ # docker exec ollama ollama pull codellama
13
+
14
+ services:
15
+ # ── Core: Ollama (local LLM inference) ────────────────────────────────────
16
+ ollama:
17
+ image: ollama/ollama:latest
18
+ container_name: ollama
19
+ restart: unless-stopped
20
+ ports:
21
+ - "${OLLAMA_PORT:-11434}:11434"
22
+ volumes:
23
+ - ollama_data:/root/.ollama
24
+ environment:
25
+ - OLLAMA_HOST=0.0.0.0
26
+ # Uncomment for NVIDIA GPU support:
27
+ # deploy:
28
+ # resources:
29
+ # reservations:
30
+ # devices:
31
+ # - driver: nvidia
32
+ # count: all
33
+ # capabilities: [gpu]
34
+ healthcheck:
35
+ test: ["CMD-SHELL", "curl -f http://localhost:11434/api/tags || exit 1"]
36
+ interval: 30s
37
+ timeout: 10s
38
+ retries: 3
39
+ start_period: 10s
40
+
41
+ # ── Optional: Open WebUI (chat interface) ─────────────────────────────────
42
+ open-webui:
43
+ image: ghcr.io/open-webui/open-webui:main
44
+ container_name: open-webui
45
+ profiles: ["ui", "auto", "full"]
46
+ restart: unless-stopped
47
+ ports:
48
+ - "${WEBUI_PORT:-3000}:8080"
49
+ volumes:
50
+ - open_webui_data:/app/backend/data
51
+ environment:
52
+ - OLLAMA_BASE_URL=http://ollama:11434
53
+ - WEBUI_AUTH=${WEBUI_AUTH:-false}
54
+ depends_on:
55
+ ollama:
56
+ condition: service_healthy
57
+
58
+ # ── Optional: n8n (workflow automation) ───────────────────────────────────
59
+ n8n:
60
+ image: n8nio/n8n:latest
61
+ container_name: n8n
62
+ profiles: ["auto", "full"]
63
+ restart: unless-stopped
64
+ ports:
65
+ - "${N8N_PORT:-5678}:5678"
66
+ volumes:
67
+ - n8n_data:/home/node/.n8n
68
+ environment:
69
+ - N8N_SECURE_COOKIE=false
70
+ - OLLAMA_HOST=http://ollama:11434
71
+
72
+ # ── Optional: Supabase (Postgres + Auth + Realtime) ───────────────────────
73
+ supabase-db:
74
+ image: supabase/postgres:15.6.1.145
75
+ container_name: supabase-db
76
+ profiles: ["full"]
77
+ restart: unless-stopped
78
+ ports:
79
+ - "${SUPABASE_DB_PORT:-5432}:5432"
80
+ volumes:
81
+ - supabase_db_data:/var/lib/postgresql/data
82
+ environment:
83
+ POSTGRES_PASSWORD: ${SUPABASE_DB_PASSWORD:-postgres}
84
+ POSTGRES_DB: ${SUPABASE_DB_NAME:-app}
85
+ healthcheck:
86
+ test: ["CMD-SHELL", "pg_isready -U postgres"]
87
+ interval: 10s
88
+ timeout: 5s
89
+ retries: 5
90
+
91
+ volumes:
92
+ ollama_data:
93
+ open_webui_data:
94
+ n8n_data:
95
+ supabase_db_data:
@@ -0,0 +1,30 @@
1
+ {
2
+ "$schema": "https://raw.githubusercontent.com/anthropics/claude-code/main/settings-schema.json",
3
+ "_comment": "Runtime security hooks (kiteguard-style) — scaffolded by javi-forge",
4
+ "hooks": {
5
+ "PreToolUse": [
6
+ {
7
+ "matcher": "Bash",
8
+ "hook": "COMMAND=\"$CLAUDE_TOOL_INPUT\"\nBLOCKED_PATTERNS=(\n 'rm -rf /'\n 'rm -rf ~'\n 'chmod 777'\n 'curl.*|.*sh'\n 'wget.*|.*sh'\n 'eval.*\\$'\n 'base64.*-d.*|.*sh'\n ':(){:|:&};:'\n)\nfor pattern in \"${BLOCKED_PATTERNS[@]}\"; do\n if echo \"$COMMAND\" | grep -qE \"$pattern\"; then\n echo \"BLOCKED: Dangerous command pattern detected: $pattern\"\n exit 2\n fi\ndone\nexit 0",
9
+ "description": "Block dangerous shell commands (rm -rf /, chmod 777, pipe-to-sh, fork bombs)"
10
+ },
11
+ {
12
+ "matcher": "Bash",
13
+ "hook": "COMMAND=\"$CLAUDE_TOOL_INPUT\"\nSENSITIVE_PATHS=(\n '.env'\n '.env.local'\n '.env.production'\n 'credentials'\n 'secrets'\n '.ssh'\n '.gnupg'\n '.aws/credentials'\n)\nfor path in \"${SENSITIVE_PATHS[@]}\"; do\n if echo \"$COMMAND\" | grep -qE \"(cat|less|head|tail|bat|read).*$path\"; then\n echo \"BLOCKED: Attempt to read sensitive file: $path\"\n exit 2\n fi\ndone\nexit 0",
14
+ "description": "Prevent reading sensitive files (.env, credentials, SSH keys)"
15
+ },
16
+ {
17
+ "matcher": "Write|Edit",
18
+ "hook": "INPUT=\"$CLAUDE_TOOL_INPUT\"\nPROTECTED_FILES=(\n '.env'\n '.env.production'\n 'credentials.json'\n 'serviceAccountKey.json'\n '.ssh/'\n '.gnupg/'\n)\nfor pf in \"${PROTECTED_FILES[@]}\"; do\n if echo \"$INPUT\" | grep -q \"$pf\"; then\n echo \"BLOCKED: Cannot modify protected file: $pf\"\n exit 2\n fi\ndone\nexit 0",
19
+ "description": "Prevent writing to credential and secret files"
20
+ }
21
+ ],
22
+ "PostToolUse": [
23
+ {
24
+ "matcher": "Bash",
25
+ "hook": "OUTPUT=\"$CLAUDE_TOOL_OUTPUT\"\nLEAK_PATTERNS=(\n 'AKIA[0-9A-Z]{16}'\n 'ghp_[A-Za-z0-9]{36}'\n 'sk_live_[0-9a-zA-Z]{24,}'\n 'xox[baprs]-[0-9a-zA-Z-]+'\n '-----BEGIN.*PRIVATE KEY-----'\n)\nfor pattern in \"${LEAK_PATTERNS[@]}\"; do\n if echo \"$OUTPUT\" | grep -qE \"$pattern\"; then\n echo \"WARNING: Command output may contain secrets. Review carefully.\"\n exit 0\n fi\ndone\nexit 0",
26
+ "description": "Warn if command output contains potential secrets"
27
+ }
28
+ ]
29
+ }
30
+ }
@@ -0,0 +1,29 @@
1
+ #!/bin/bash
2
+ # =============================================================================
3
+ # SECURITY LAYER 6: Commit Message Signing Reminder (commit-msg)
4
+ # =============================================================================
5
+ # Reminds developers to sign commits if signing is configured but the
6
+ # current commit is not signed. Non-blocking — just a nudge.
7
+ #
8
+ # This complements layer 4 (pre-push signing) with an earlier reminder.
9
+ # =============================================================================
10
+
11
+ set -e
12
+
13
+ YELLOW='\033[1;33m'
14
+ CYAN='\033[0;36m'
15
+ GREEN='\033[0;32m'
16
+ NC='\033[0m'
17
+
18
+ echo "SECURITY [6/6]: Commit signing reminder..."
19
+
20
+ GPG_SIGN=$(git config --get commit.gpgsign 2>/dev/null || echo "false")
21
+
22
+ if [ "$GPG_SIGN" = "true" ]; then
23
+ echo -e "${GREEN} Commit signing is enabled. Good.${NC}"
24
+ else
25
+ echo -e "${YELLOW} Tip: Enable commit signing for supply-chain security.${NC}"
26
+ echo -e "${CYAN} git config commit.gpgsign true${NC}"
27
+ fi
28
+
29
+ exit 0
@@ -0,0 +1,74 @@
1
+ #!/bin/bash
2
+ # =============================================================================
3
+ # SECURITY LAYER 3: Permission Boundaries (pre-commit)
4
+ # =============================================================================
5
+ # Validates that staged files don't introduce overly permissive file modes,
6
+ # executable flags on non-script files, or world-writable permissions.
7
+ #
8
+ # To skip: git commit --no-verify (NOT recommended)
9
+ # =============================================================================
10
+
11
+ set -e
12
+
13
+ RED='\033[0;31m'
14
+ YELLOW='\033[1;33m'
15
+ GREEN='\033[0;32m'
16
+ NC='\033[0m'
17
+
18
+ echo "SECURITY [3/6]: Permission boundary check..."
19
+
20
+ STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM)
21
+
22
+ if [ -z "$STAGED_FILES" ]; then
23
+ echo -e "${GREEN} No staged files to check.${NC}"
24
+ exit 0
25
+ fi
26
+
27
+ ISSUES=0
28
+
29
+ # Check for world-writable files (o+w)
30
+ for file in $STAGED_FILES; do
31
+ if [ -f "$file" ]; then
32
+ PERMS=$(stat -c '%a' "$file" 2>/dev/null || stat -f '%Lp' "$file" 2>/dev/null || echo "")
33
+ if [ -n "$PERMS" ]; then
34
+ # Check if last digit (other permissions) has write (2, 3, 6, 7)
35
+ OTHERS=${PERMS: -1}
36
+ if [[ "$OTHERS" =~ [2367] ]]; then
37
+ echo -e "${RED} World-writable: $file (mode $PERMS)${NC}"
38
+ ISSUES=$((ISSUES + 1))
39
+ fi
40
+ fi
41
+ fi
42
+ done
43
+
44
+ # Check for executable flag on non-script files
45
+ SCRIPT_EXTENSIONS='\.sh$|\.bash$|\.zsh$|\.py$|\.rb$|\.pl$'
46
+ for file in $STAGED_FILES; do
47
+ if [ -f "$file" ] && [ -x "$file" ]; then
48
+ # Allow scripts and hooks (no extension = likely a hook)
49
+ BASENAME=$(basename "$file")
50
+ if echo "$file" | grep -qE "$SCRIPT_EXTENSIONS"; then
51
+ continue
52
+ fi
53
+ # Allow files in hooks/ directories
54
+ if echo "$file" | grep -q '/hooks/'; then
55
+ continue
56
+ fi
57
+ # Allow if it has a shebang
58
+ if head -1 "$file" 2>/dev/null | grep -q '^#!'; then
59
+ continue
60
+ fi
61
+ echo -e "${YELLOW} Unexpected executable: $file${NC}"
62
+ ISSUES=$((ISSUES + 1))
63
+ fi
64
+ done
65
+
66
+ if [ "$ISSUES" -gt 0 ]; then
67
+ echo -e ""
68
+ echo -e "${RED}COMMIT BLOCKED: $ISSUES permission issue(s) found.${NC}"
69
+ echo -e "${YELLOW} Fix file permissions before committing.${NC}"
70
+ exit 1
71
+ fi
72
+
73
+ echo -e "${GREEN} Permissions OK.${NC}"
74
+ exit 0
@@ -0,0 +1,74 @@
1
+ #!/bin/bash
2
+ # =============================================================================
3
+ # SECURITY LAYER 1: Secret Scanning (pre-commit)
4
+ # =============================================================================
5
+ # Scans staged files for hardcoded secrets, API keys, and credentials.
6
+ # Runs on every commit to prevent accidental secret leaks.
7
+ #
8
+ # Requires: git
9
+ # To skip: git commit --no-verify (NOT recommended)
10
+ # =============================================================================
11
+
12
+ set -e
13
+
14
+ RED='\033[0;31m'
15
+ YELLOW='\033[1;33m'
16
+ GREEN='\033[0;32m'
17
+ NC='\033[0m'
18
+
19
+ echo "SECURITY [1/6]: Secret scanning..."
20
+
21
+ # Patterns that indicate hardcoded secrets
22
+ SECRET_PATTERNS=(
23
+ # AWS
24
+ 'AKIA[0-9A-Z]{16}'
25
+ # Generic API keys (long hex/base64 strings assigned to key-like vars)
26
+ '(?i)(api[_-]?key|api[_-]?secret|access[_-]?token|auth[_-]?token)\s*[:=]\s*["\x27][A-Za-z0-9+/=_-]{20,}["\x27]'
27
+ # Private keys
28
+ '-----BEGIN (RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----'
29
+ # GitHub tokens
30
+ 'gh[pousr]_[A-Za-z0-9_]{36,}'
31
+ # Generic password assignments
32
+ '(?i)(password|passwd|pwd)\s*[:=]\s*["\x27][^\s"'\'']{8,}["\x27]'
33
+ # Slack tokens
34
+ 'xox[baprs]-[0-9a-zA-Z-]+'
35
+ # Stripe keys
36
+ 'sk_live_[0-9a-zA-Z]{24,}'
37
+ 'rk_live_[0-9a-zA-Z]{24,}'
38
+ # SendGrid
39
+ 'SG\.[A-Za-z0-9_-]{22}\.[A-Za-z0-9_-]{43}'
40
+ )
41
+
42
+ STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM)
43
+
44
+ if [ -z "$STAGED_FILES" ]; then
45
+ echo -e "${GREEN} No staged files to scan.${NC}"
46
+ exit 0
47
+ fi
48
+
49
+ FOUND=0
50
+ for pattern in "${SECRET_PATTERNS[@]}"; do
51
+ # Use grep -P for perl-compatible regex, fall back to -E
52
+ MATCHES=$(echo "$STAGED_FILES" | xargs git diff --cached -- | grep -nP "$pattern" 2>/dev/null || true)
53
+ if [ -n "$MATCHES" ]; then
54
+ if [ "$FOUND" -eq 0 ]; then
55
+ echo -e "${RED} Potential secrets detected in staged changes:${NC}"
56
+ fi
57
+ echo -e "${YELLOW} Pattern: $pattern${NC}"
58
+ echo "$MATCHES" | head -5 | while read -r line; do
59
+ echo -e "${RED} $line${NC}"
60
+ done
61
+ FOUND=$((FOUND + 1))
62
+ fi
63
+ done
64
+
65
+ if [ "$FOUND" -gt 0 ]; then
66
+ echo -e ""
67
+ echo -e "${RED}COMMIT BLOCKED: $FOUND secret pattern(s) detected.${NC}"
68
+ echo -e "${YELLOW} Remove secrets and use environment variables instead.${NC}"
69
+ echo -e "${YELLOW} If this is a false positive, add to .secret-scan-ignore${NC}"
70
+ exit 1
71
+ fi
72
+
73
+ echo -e "${GREEN} No secrets found.${NC}"
74
+ exit 0
@@ -0,0 +1,62 @@
1
+ #!/bin/bash
2
+ # =============================================================================
3
+ # SECURITY LAYER 5: Branch Protection (pre-push)
4
+ # =============================================================================
5
+ # Prevents direct pushes to protected branches (main, master, release/*).
6
+ # Forces use of pull requests for protected branches.
7
+ #
8
+ # To skip: git push --no-verify (NOT recommended)
9
+ # =============================================================================
10
+
11
+ set -e
12
+
13
+ RED='\033[0;31m'
14
+ YELLOW='\033[1;33m'
15
+ GREEN='\033[0;32m'
16
+ NC='\033[0m'
17
+
18
+ echo "SECURITY [5/6]: Branch protection check..."
19
+
20
+ # Protected branch patterns
21
+ PROTECTED_BRANCHES=(
22
+ "main"
23
+ "master"
24
+ "release/*"
25
+ "production"
26
+ "staging"
27
+ )
28
+
29
+ CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "")
30
+
31
+ if [ -z "$CURRENT_BRANCH" ]; then
32
+ echo -e "${YELLOW} Could not determine current branch. Skipping.${NC}"
33
+ exit 0
34
+ fi
35
+
36
+ for pattern in "${PROTECTED_BRANCHES[@]}"; do
37
+ # Support glob patterns
38
+ if [[ "$CURRENT_BRANCH" == $pattern ]]; then
39
+ # Check if we're on CI (allow CI pushes)
40
+ if [ -n "$CI" ] || [ -n "$GITHUB_ACTIONS" ] || [ -n "$GITLAB_CI" ]; then
41
+ echo -e "${GREEN} CI environment detected. Allowing push to $CURRENT_BRANCH.${NC}"
42
+ exit 0
43
+ fi
44
+
45
+ echo -e ""
46
+ echo -e "${RED}PUSH BLOCKED: Direct push to protected branch '$CURRENT_BRANCH'.${NC}"
47
+ echo -e ""
48
+ echo -e "${YELLOW} Protected branches require pull requests:${NC}"
49
+ for b in "${PROTECTED_BRANCHES[@]}"; do
50
+ echo -e "${YELLOW} - $b${NC}"
51
+ done
52
+ echo -e ""
53
+ echo -e "${YELLOW} Create a feature branch and open a PR instead:${NC}"
54
+ echo -e "${GREEN} git checkout -b feat/my-feature${NC}"
55
+ echo -e "${GREEN} git push -u origin feat/my-feature${NC}"
56
+ echo -e "${GREEN} gh pr create${NC}"
57
+ exit 1
58
+ fi
59
+ done
60
+
61
+ echo -e "${GREEN} Branch '$CURRENT_BRANCH' is not protected. OK.${NC}"
62
+ exit 0