gigaclaw 1.4.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 (249) hide show
  1. package/LICENSE +26 -0
  2. package/README.md +237 -0
  3. package/api/CLAUDE.md +19 -0
  4. package/api/index.js +265 -0
  5. package/bin/cli.js +823 -0
  6. package/bin/local.sh +85 -0
  7. package/bin/postinstall.js +63 -0
  8. package/config/index.js +26 -0
  9. package/config/instrumentation.js +62 -0
  10. package/drizzle/0000_initial.sql +52 -0
  11. package/drizzle/0001_nostalgic_sersi.sql +11 -0
  12. package/drizzle/0002_black_daimon_hellstrom.sql +19 -0
  13. package/drizzle/0003_rename_code_workspaces.sql +5 -0
  14. package/drizzle/meta/0000_snapshot.json +321 -0
  15. package/drizzle/meta/0001_snapshot.json +390 -0
  16. package/drizzle/meta/0002_snapshot.json +411 -0
  17. package/drizzle/meta/0003_snapshot.json +419 -0
  18. package/drizzle/meta/_journal.json +34 -0
  19. package/lib/actions.js +44 -0
  20. package/lib/ai/agent.js +86 -0
  21. package/lib/ai/index.js +342 -0
  22. package/lib/ai/model.js +180 -0
  23. package/lib/ai/tools.js +269 -0
  24. package/lib/ai/web-search.js +42 -0
  25. package/lib/auth/actions.js +28 -0
  26. package/lib/auth/config.js +27 -0
  27. package/lib/auth/edge-config.js +27 -0
  28. package/lib/auth/index.js +27 -0
  29. package/lib/auth/middleware.js +62 -0
  30. package/lib/channels/base.js +56 -0
  31. package/lib/channels/index.js +15 -0
  32. package/lib/channels/telegram.js +148 -0
  33. package/lib/chat/actions.js +579 -0
  34. package/lib/chat/api.js +140 -0
  35. package/lib/chat/components/app-sidebar.js +213 -0
  36. package/lib/chat/components/app-sidebar.jsx +279 -0
  37. package/lib/chat/components/chat-header.js +192 -0
  38. package/lib/chat/components/chat-header.jsx +223 -0
  39. package/lib/chat/components/chat-input.js +236 -0
  40. package/lib/chat/components/chat-input.jsx +249 -0
  41. package/lib/chat/components/chat-nav-context.js +11 -0
  42. package/lib/chat/components/chat-nav-context.jsx +11 -0
  43. package/lib/chat/components/chat-page.js +99 -0
  44. package/lib/chat/components/chat-page.jsx +121 -0
  45. package/lib/chat/components/chat.js +153 -0
  46. package/lib/chat/components/chat.jsx +199 -0
  47. package/lib/chat/components/chats-page.js +367 -0
  48. package/lib/chat/components/chats-page.jsx +394 -0
  49. package/lib/chat/components/code-mode-toggle.js +132 -0
  50. package/lib/chat/components/code-mode-toggle.jsx +163 -0
  51. package/lib/chat/components/crons-page.js +172 -0
  52. package/lib/chat/components/crons-page.jsx +244 -0
  53. package/lib/chat/components/greeting.js +11 -0
  54. package/lib/chat/components/greeting.jsx +16 -0
  55. package/lib/chat/components/icons.js +805 -0
  56. package/lib/chat/components/icons.jsx +751 -0
  57. package/lib/chat/components/index.js +20 -0
  58. package/lib/chat/components/message.js +363 -0
  59. package/lib/chat/components/message.jsx +422 -0
  60. package/lib/chat/components/messages.js +65 -0
  61. package/lib/chat/components/messages.jsx +74 -0
  62. package/lib/chat/components/notifications-page.js +56 -0
  63. package/lib/chat/components/notifications-page.jsx +87 -0
  64. package/lib/chat/components/page-layout.js +21 -0
  65. package/lib/chat/components/page-layout.jsx +28 -0
  66. package/lib/chat/components/pull-requests-page.js +103 -0
  67. package/lib/chat/components/pull-requests-page.jsx +113 -0
  68. package/lib/chat/components/settings-layout.js +39 -0
  69. package/lib/chat/components/settings-layout.jsx +53 -0
  70. package/lib/chat/components/settings-secrets-page.js +216 -0
  71. package/lib/chat/components/settings-secrets-page.jsx +264 -0
  72. package/lib/chat/components/sidebar-history-item.js +138 -0
  73. package/lib/chat/components/sidebar-history-item.jsx +119 -0
  74. package/lib/chat/components/sidebar-history.js +167 -0
  75. package/lib/chat/components/sidebar-history.jsx +220 -0
  76. package/lib/chat/components/sidebar-user-nav.js +61 -0
  77. package/lib/chat/components/sidebar-user-nav.jsx +77 -0
  78. package/lib/chat/components/swarm-page.js +157 -0
  79. package/lib/chat/components/swarm-page.jsx +210 -0
  80. package/lib/chat/components/tool-call.js +89 -0
  81. package/lib/chat/components/tool-call.jsx +107 -0
  82. package/lib/chat/components/triggers-page.js +153 -0
  83. package/lib/chat/components/triggers-page.jsx +221 -0
  84. package/lib/chat/components/ui/combobox.js +98 -0
  85. package/lib/chat/components/ui/combobox.jsx +114 -0
  86. package/lib/chat/components/ui/confirm-dialog.js +53 -0
  87. package/lib/chat/components/ui/confirm-dialog.jsx +57 -0
  88. package/lib/chat/components/ui/dropdown-menu.js +194 -0
  89. package/lib/chat/components/ui/dropdown-menu.jsx +215 -0
  90. package/lib/chat/components/ui/rename-dialog.js +78 -0
  91. package/lib/chat/components/ui/rename-dialog.jsx +74 -0
  92. package/lib/chat/components/ui/scroll-area.js +13 -0
  93. package/lib/chat/components/ui/scroll-area.jsx +17 -0
  94. package/lib/chat/components/ui/separator.js +21 -0
  95. package/lib/chat/components/ui/separator.jsx +18 -0
  96. package/lib/chat/components/ui/sheet.js +75 -0
  97. package/lib/chat/components/ui/sheet.jsx +95 -0
  98. package/lib/chat/components/ui/sidebar.js +228 -0
  99. package/lib/chat/components/ui/sidebar.jsx +246 -0
  100. package/lib/chat/components/ui/tooltip.js +56 -0
  101. package/lib/chat/components/ui/tooltip.jsx +66 -0
  102. package/lib/chat/components/upgrade-dialog.js +151 -0
  103. package/lib/chat/components/upgrade-dialog.jsx +170 -0
  104. package/lib/chat/utils.js +11 -0
  105. package/lib/code/actions.js +153 -0
  106. package/lib/code/code-page.js +22 -0
  107. package/lib/code/code-page.jsx +25 -0
  108. package/lib/code/index.js +1 -0
  109. package/lib/code/terminal-view.js +201 -0
  110. package/lib/code/terminal-view.jsx +224 -0
  111. package/lib/code/ws-proxy.js +80 -0
  112. package/lib/cron.js +246 -0
  113. package/lib/db/api-keys.js +163 -0
  114. package/lib/db/chats.js +168 -0
  115. package/lib/db/code-workspaces.js +110 -0
  116. package/lib/db/index.js +52 -0
  117. package/lib/db/notifications.js +99 -0
  118. package/lib/db/schema.js +66 -0
  119. package/lib/db/update-check.js +96 -0
  120. package/lib/db/users.js +89 -0
  121. package/lib/paths.js +42 -0
  122. package/lib/tools/create-job.js +97 -0
  123. package/lib/tools/docker.js +146 -0
  124. package/lib/tools/github.js +271 -0
  125. package/lib/tools/openai.js +35 -0
  126. package/lib/tools/telegram.js +292 -0
  127. package/lib/triggers.js +104 -0
  128. package/lib/utils/render-md.js +111 -0
  129. package/package.json +118 -0
  130. package/setup/lib/auth.mjs +81 -0
  131. package/setup/lib/env.mjs +21 -0
  132. package/setup/lib/fs-utils.mjs +20 -0
  133. package/setup/lib/github.mjs +149 -0
  134. package/setup/lib/prerequisites.mjs +155 -0
  135. package/setup/lib/prompts.mjs +267 -0
  136. package/setup/lib/providers.mjs +105 -0
  137. package/setup/lib/sync.mjs +125 -0
  138. package/setup/lib/targets.mjs +45 -0
  139. package/setup/lib/telegram-verify.mjs +63 -0
  140. package/setup/lib/telegram.mjs +76 -0
  141. package/setup/setup-cloud.mjs +833 -0
  142. package/setup/setup-local.mjs +377 -0
  143. package/setup/setup-telegram.mjs +265 -0
  144. package/setup/setup.mjs +87 -0
  145. package/templates/.dockerignore +5 -0
  146. package/templates/.env.example +104 -0
  147. package/templates/.github/workflows/auto-merge.yml +117 -0
  148. package/templates/.github/workflows/notify-job-failed.yml +64 -0
  149. package/templates/.github/workflows/notify-pr-complete.yml +119 -0
  150. package/templates/.github/workflows/rebuild-event-handler.yml +121 -0
  151. package/templates/.github/workflows/run-job.yml +89 -0
  152. package/templates/.github/workflows/upgrade-event-handler.yml +62 -0
  153. package/templates/.gitignore.template +45 -0
  154. package/templates/.pi/extensions/env-sanitizer/index.ts +48 -0
  155. package/templates/.pi/extensions/env-sanitizer/package.json +5 -0
  156. package/templates/CLAUDE.md +29 -0
  157. package/templates/CLAUDE.md.template +308 -0
  158. package/templates/app/api/[...gigaclaw]/route.js +1 -0
  159. package/templates/app/api/auth/[...nextauth]/route.js +1 -0
  160. package/templates/app/chat/[chatId]/page.js +9 -0
  161. package/templates/app/chats/page.js +7 -0
  162. package/templates/app/code/[codeWorkspaceId]/page.js +9 -0
  163. package/templates/app/components/ascii-logo.jsx +12 -0
  164. package/templates/app/components/login-form.jsx +92 -0
  165. package/templates/app/components/setup-form.jsx +82 -0
  166. package/templates/app/components/theme-provider.jsx +11 -0
  167. package/templates/app/components/theme-toggle.jsx +38 -0
  168. package/templates/app/components/ui/button.jsx +21 -0
  169. package/templates/app/components/ui/card.jsx +23 -0
  170. package/templates/app/components/ui/input.jsx +10 -0
  171. package/templates/app/components/ui/label.jsx +10 -0
  172. package/templates/app/crons/page.js +5 -0
  173. package/templates/app/globals.css +90 -0
  174. package/templates/app/layout.js +33 -0
  175. package/templates/app/login/page.js +15 -0
  176. package/templates/app/notifications/page.js +7 -0
  177. package/templates/app/page.js +7 -0
  178. package/templates/app/pull-requests/page.js +7 -0
  179. package/templates/app/settings/crons/page.js +5 -0
  180. package/templates/app/settings/layout.js +7 -0
  181. package/templates/app/settings/page.js +5 -0
  182. package/templates/app/settings/secrets/page.js +5 -0
  183. package/templates/app/settings/triggers/page.js +5 -0
  184. package/templates/app/stream/chat/route.js +1 -0
  185. package/templates/app/swarm/page.js +7 -0
  186. package/templates/app/triggers/page.js +5 -0
  187. package/templates/config/CODE_PLANNING.md +14 -0
  188. package/templates/config/CRONS.json +56 -0
  189. package/templates/config/HEARTBEAT.md +3 -0
  190. package/templates/config/JOB_AGENT.md +30 -0
  191. package/templates/config/JOB_PLANNING.md +240 -0
  192. package/templates/config/JOB_SUMMARY.md +130 -0
  193. package/templates/config/SKILL_BUILDING_GUIDE.md +96 -0
  194. package/templates/config/SOUL.md +48 -0
  195. package/templates/config/TRIGGERS.json +58 -0
  196. package/templates/config/WEB_SEARCH_AVAILABLE.md +5 -0
  197. package/templates/config/WEB_SEARCH_UNAVAILABLE.md +3 -0
  198. package/templates/docker/claude-code-job/Dockerfile +34 -0
  199. package/templates/docker/claude-code-job/entrypoint.sh +149 -0
  200. package/templates/docker/claude-code-workspace/.tmux.conf +5 -0
  201. package/templates/docker/claude-code-workspace/Dockerfile +61 -0
  202. package/templates/docker/claude-code-workspace/entrypoint.sh +51 -0
  203. package/templates/docker/event-handler/Dockerfile +20 -0
  204. package/templates/docker/event-handler/ecosystem.config.cjs +7 -0
  205. package/templates/docker/pi-coding-agent-job/Dockerfile +51 -0
  206. package/templates/docker/pi-coding-agent-job/entrypoint.sh +164 -0
  207. package/templates/docker-compose.local.yml +78 -0
  208. package/templates/docker-compose.yml +64 -0
  209. package/templates/instrumentation.js +6 -0
  210. package/templates/middleware.js +23 -0
  211. package/templates/next.config.mjs +3 -0
  212. package/templates/postcss.config.mjs +5 -0
  213. package/templates/public/favicon.ico +0 -0
  214. package/templates/server.js +25 -0
  215. package/templates/skills/LICENSE +21 -0
  216. package/templates/skills/README.md +119 -0
  217. package/templates/skills/brave-search/SKILL.md +79 -0
  218. package/templates/skills/brave-search/content.js +86 -0
  219. package/templates/skills/brave-search/package-lock.json +621 -0
  220. package/templates/skills/brave-search/package.json +14 -0
  221. package/templates/skills/brave-search/search.js +199 -0
  222. package/templates/skills/browser-tools/SKILL.md +196 -0
  223. package/templates/skills/browser-tools/browser-content.js +103 -0
  224. package/templates/skills/browser-tools/browser-cookies.js +35 -0
  225. package/templates/skills/browser-tools/browser-eval.js +53 -0
  226. package/templates/skills/browser-tools/browser-hn-scraper.js +108 -0
  227. package/templates/skills/browser-tools/browser-nav.js +44 -0
  228. package/templates/skills/browser-tools/browser-pick.js +162 -0
  229. package/templates/skills/browser-tools/browser-screenshot.js +34 -0
  230. package/templates/skills/browser-tools/browser-start.js +87 -0
  231. package/templates/skills/browser-tools/package-lock.json +2556 -0
  232. package/templates/skills/browser-tools/package.json +19 -0
  233. package/templates/skills/google-docs/SKILL.md +23 -0
  234. package/templates/skills/google-docs/create.sh +69 -0
  235. package/templates/skills/google-drive/SKILL.md +47 -0
  236. package/templates/skills/google-drive/delete.sh +47 -0
  237. package/templates/skills/google-drive/download.sh +50 -0
  238. package/templates/skills/google-drive/list.sh +41 -0
  239. package/templates/skills/google-drive/upload.sh +76 -0
  240. package/templates/skills/kie-ai/SKILL.md +38 -0
  241. package/templates/skills/kie-ai/generate-image.sh +77 -0
  242. package/templates/skills/kie-ai/generate-video.sh +69 -0
  243. package/templates/skills/llm-secrets/SKILL.md +34 -0
  244. package/templates/skills/llm-secrets/llm-secrets.js +33 -0
  245. package/templates/skills/modify-self/SKILL.md +12 -0
  246. package/templates/skills/youtube-transcript/SKILL.md +41 -0
  247. package/templates/skills/youtube-transcript/package-lock.json +24 -0
  248. package/templates/skills/youtube-transcript/package.json +8 -0
  249. package/templates/skills/youtube-transcript/transcript.js +84 -0
@@ -0,0 +1,89 @@
1
+ name: Agent Job
2
+
3
+ on:
4
+ create:
5
+
6
+ jobs:
7
+ run-agent:
8
+ runs-on: ${{ vars.RUNS_ON || 'ubuntu-latest' }}
9
+ if: github.ref_type == 'branch' && startsWith(github.ref_name, 'job/')
10
+ permissions:
11
+ contents: write
12
+ packages: read
13
+
14
+ steps:
15
+ - name: Checkout
16
+ uses: actions/checkout@v4
17
+ with:
18
+ ref: ${{ github.ref_name }}
19
+ sparse-checkout: |
20
+ package-lock.json
21
+ logs/*/job.config.json
22
+ sparse-checkout-cone-mode: false
23
+
24
+ - name: Get gigaclaw version
25
+ id: version
26
+ run: |
27
+ VERSION=$(jq -r '.packages["node_modules/gigaclaw"].version // "latest"' package-lock.json)
28
+ echo "tag=$VERSION" >> $GITHUB_OUTPUT
29
+
30
+ - name: Read job config overrides
31
+ id: job-config
32
+ run: |
33
+ JOB_ID="${{ github.ref_name }}"
34
+ JOB_ID="${JOB_ID#job/}"
35
+ CONFIG_FILE="logs/${JOB_ID}/job.config.json"
36
+ if [ -f "$CONFIG_FILE" ]; then
37
+ echo "llm_provider=$(jq -r '.llm_provider // empty' "$CONFIG_FILE")" >> $GITHUB_OUTPUT
38
+ echo "llm_model=$(jq -r '.llm_model // empty' "$CONFIG_FILE")" >> $GITHUB_OUTPUT
39
+ echo "agent_backend=$(jq -r '.agent_backend // empty' "$CONFIG_FILE")" >> $GITHUB_OUTPUT
40
+ fi
41
+
42
+ - name: Login to GHCR
43
+ if: startsWith(vars.JOB_IMAGE_URL, 'ghcr.io/')
44
+ uses: docker/login-action@v3
45
+ with:
46
+ registry: ghcr.io
47
+ username: ${{ github.actor }}
48
+ password: ${{ secrets.GITHUB_TOKEN }}
49
+
50
+ - name: Run gigaclaw Agent
51
+ env:
52
+ ALL_SECRETS: ${{ toJson(secrets) }}
53
+ JOB_IMAGE_URL: ${{ vars.JOB_IMAGE_URL }}
54
+ GIGACLAW_VERSION: ${{ steps.version.outputs.tag }}
55
+ LLM_MODEL: ${{ steps.job-config.outputs.llm_model || vars.LLM_MODEL }}
56
+ LLM_PROVIDER: ${{ steps.job-config.outputs.llm_provider || vars.LLM_PROVIDER }}
57
+ OPENAI_BASE_URL: ${{ vars.OPENAI_BASE_URL }}
58
+ AGENT_BACKEND: ${{ steps.job-config.outputs.agent_backend || vars.AGENT_BACKEND || '' }}
59
+ run: |
60
+ AGENT_BACKEND="${AGENT_BACKEND:-pi}"
61
+ if [ -n "$JOB_IMAGE_URL" ]; then
62
+ IMAGE="${JOB_IMAGE_URL}:latest"
63
+ elif [ "$AGENT_BACKEND" = "claude-code" ]; then
64
+ IMAGE="gignaati/gigaclaw:claude-code-job-${GIGACLAW_VERSION}"
65
+ else
66
+ IMAGE="gignaati/gigaclaw:pi-coding-agent-job-${GIGACLAW_VERSION}"
67
+ fi
68
+ echo "Using image: $IMAGE"
69
+
70
+ # Build SECRETS JSON from AGENT_* (excluding AGENT_LLM_*) secrets
71
+ export SECRETS=$(echo "$ALL_SECRETS" | jq -c '
72
+ [to_entries[] | select(.key | startswith("AGENT_")) | select(.key | startswith("AGENT_LLM_") | not)]
73
+ | map({key: (.key | sub("^AGENT_"; "")), value: .value}) | from_entries')
74
+
75
+ # Build LLM_SECRETS JSON from AGENT_LLM_* secrets
76
+ export LLM_SECRETS=$(echo "$ALL_SECRETS" | jq -c '
77
+ [to_entries[] | select(.key | startswith("AGENT_LLM_"))]
78
+ | map({key: (.key | sub("^AGENT_LLM_"; "")), value: .value}) | from_entries')
79
+
80
+ docker run --rm \
81
+ -e REPO_URL="${{ github.server_url }}/${{ github.repository }}.git" \
82
+ -e BRANCH="${{ github.ref_name }}" \
83
+ -e SECRETS \
84
+ -e LLM_SECRETS \
85
+ -e LLM_MODEL="${LLM_MODEL}" \
86
+ -e LLM_PROVIDER="${LLM_PROVIDER}" \
87
+ -e OPENAI_BASE_URL="${OPENAI_BASE_URL}" \
88
+ -e AGENT_BACKEND="${AGENT_BACKEND}" \
89
+ "$IMAGE"
@@ -0,0 +1,62 @@
1
+ name: Upgrade Event Handler
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ inputs:
6
+ target_version:
7
+ description: 'Target version to install (empty for latest stable)'
8
+ required: false
9
+ default: ''
10
+
11
+ concurrency:
12
+ group: event-handler-deploy
13
+ cancel-in-progress: false
14
+
15
+ jobs:
16
+ upgrade:
17
+ runs-on: self-hosted
18
+ timeout-minutes: 20
19
+ steps:
20
+ - name: Upgrade gigaclaw
21
+ run: |
22
+ docker exec gigaclaw-event-handler bash -c '
23
+ export GH_TOKEN=$(grep "^GH_TOKEN=" /app/.env | cut -d= -f2-)
24
+ echo "${GH_TOKEN}" | gh auth login --with-token
25
+ gh auth setup-git
26
+
27
+ REPO_URL=$(git -C /app remote get-url origin)
28
+ WORK_DIR=$(mktemp -d)
29
+ git clone --depth 1 "$REPO_URL" "$WORK_DIR"
30
+ cd "$WORK_DIR"
31
+
32
+ git config user.name "gigaclaw"
33
+ git config user.email "gigaclaw@users.noreply.github.com"
34
+
35
+ npm install --omit=dev
36
+ OLD_VERSION=$(node -p "require(\"./node_modules/gigaclaw/package.json\").version")
37
+
38
+ TARGET="${{ github.event.inputs.target_version }}"
39
+ if [ -n "$TARGET" ] && echo "$TARGET" | grep -q "-"; then
40
+ # Beta: npm update cannot upgrade an exact-pinned dependency, must use install
41
+ npm install "gigaclaw@${TARGET}" --prefer-online
42
+ else
43
+ # Stable: npm update resolves to latest within semver range
44
+ npm update gigaclaw --prefer-online
45
+ fi
46
+
47
+ NEW_VERSION=$(node -p "require(\"./node_modules/gigaclaw/package.json\").version")
48
+
49
+ if [ "$OLD_VERSION" != "$NEW_VERSION" ]; then
50
+ BRANCH="upgrade/gigaclaw-${NEW_VERSION}-$(date +%s)"
51
+ git add -A
52
+ git checkout -b "$BRANCH"
53
+ git commit -m "chore: upgrade gigaclaw to $NEW_VERSION"
54
+ git push origin "$BRANCH"
55
+ gh pr create --title "chore: upgrade gigaclaw" --body "Automated upgrade via upgrade-event-handler workflow." --base main --head "$BRANCH"
56
+ gh pr merge "$BRANCH" --squash --auto --delete-branch
57
+ else
58
+ echo "No changes — gigaclaw is already up to date."
59
+ fi
60
+
61
+ rm -rf "$WORK_DIR"
62
+ '
@@ -0,0 +1,45 @@
1
+ # Credentials - NEVER commit these
2
+
3
+ .env
4
+ .env.local
5
+ *.pem
6
+ *.key
7
+
8
+ .claude/*
9
+ !.claude/skills
10
+
11
+ # Pi system prompt (generated at runtime from SOUL.md)
12
+ .pi/SYSTEM.md
13
+
14
+ # Skills dependencies (installed at runtime in Docker for correct arch)
15
+ skills/*/node_modules/
16
+
17
+ # Node
18
+ node_modules/
19
+
20
+ # Next.js
21
+ .next/
22
+ .next-new/
23
+ .next-old/
24
+ out/
25
+
26
+ # OS files
27
+ .DS_Store
28
+ Thumbs.db
29
+
30
+ # IDE
31
+ .idea/
32
+ .vscode/
33
+ *.swp
34
+ *.swo
35
+
36
+ # Logs
37
+ *.log
38
+
39
+ # Temporary files
40
+ tmp/
41
+ temp/
42
+ .tmp/
43
+
44
+ # Data (SQLite memory, etc.)
45
+ data/
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Env Sanitizer Extension - Protects credentials from AI agent access
3
+ *
4
+ * Uses Pi's spawnHook to filter sensitive env vars from bash subprocess calls
5
+ * while keeping them available in the main process for:
6
+ * - Anthropic SDK (needs ANTHROPIC_API_KEY at init)
7
+ * - GitHub CLI (needs GH_TOKEN)
8
+ * - Other extensions that may need credentials
9
+ *
10
+ * Dynamically filters all keys defined in the SECRETS JSON env var.
11
+ */
12
+
13
+ import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
14
+ import { createBashTool } from "@mariozechner/pi-coding-agent";
15
+
16
+ // Parse SECRETS JSON to get list of keys to filter
17
+ function getSecretKeys(): string[] {
18
+ const keys: string[] = [];
19
+ if (process.env.SECRETS) {
20
+ try {
21
+ const secrets = JSON.parse(process.env.SECRETS);
22
+ keys.push(...Object.keys(secrets));
23
+ } catch {
24
+ // Invalid JSON, ignore
25
+ }
26
+ }
27
+ // Always filter SECRETS itself
28
+ keys.push("SECRETS");
29
+ return [...new Set(keys)]; // Dedupe
30
+ }
31
+
32
+ export default function (pi: ExtensionAPI) {
33
+ const secretKeys = getSecretKeys();
34
+
35
+ // Override bash tool with filtered environment for subprocesses
36
+ const bashTool = createBashTool(process.cwd(), {
37
+ spawnHook: ({ command, cwd, env }) => {
38
+ // Filter all secret keys from subprocess environment
39
+ const filteredEnv = { ...env };
40
+ for (const key of secretKeys) {
41
+ delete filteredEnv[key];
42
+ }
43
+ return { command, cwd, env: filteredEnv };
44
+ },
45
+ });
46
+
47
+ pi.registerTool(bashTool);
48
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "name": "env-sanitizer",
3
+ "private": true,
4
+ "type": "module"
5
+ }
@@ -0,0 +1,29 @@
1
+ # Templates Directory — Scaffolding Only
2
+
3
+ This directory contains files that get copied into user projects when they run `npx gigaclaw init`. It is **not** where event handler logic, API routes, or core features live.
4
+
5
+ ## Rules
6
+
7
+ - **NEVER** add event handler code, API route handlers, or core logic here. All of that belongs in the NPM package (`api/`, `lib/`, `config/`, `bin/`).
8
+ - Templates exist solely to scaffold a new user's project folder with thin wiring and user-editable configuration.
9
+ - Files here may be modified to fix wiring, update configuration defaults, or adjust scaffolding — but never to implement features.
10
+
11
+ ## What belongs here
12
+
13
+ - **Next.js wiring**: `next.config.mjs`, `instrumentation.js`, catch-all route, middleware — thin re-exports from `gigaclaw/*`
14
+ - **User-editable config**: `config/SOUL.md`, `config/JOB_PLANNING.md`, `config/CRONS.json`, `config/TRIGGERS.json`, etc.
15
+ - **GitHub Actions workflows**: `.github/workflows/`
16
+ - **Docker files**: `docker/`, `docker-compose.yml`
17
+ - **UI page shells**: `app/` pages that import components from the package
18
+ - **Client components**: `app/components/` for components that must live in the user's project (e.g., `login-form.jsx`, `setup-form.jsx`) because they depend on user-side packages like `next-auth/react`
19
+
20
+ ## What does NOT belong here
21
+
22
+ - Route handlers with business logic
23
+ - Library code (`lib/`)
24
+ - Database operations
25
+ - LLM/AI integrations
26
+ - Tool implementations
27
+ - Anything that should be shared across all users via `npm update gigaclaw`
28
+
29
+ If you're adding a feature to the event handler, put it in the package. Templates just wire into it.
@@ -0,0 +1,308 @@
1
+ # My Giga Bot Agent
2
+ > Powered by **[Giga Bot](https://github.com/gignaati/gigabot)** — India's Autonomous AI Agent Platform by [Gignaati](https://www.gignaati.com)
3
+
4
+ ## Overview
5
+
6
+ This is an autonomous AI agent powered by [Giga Bot](https://github.com/gignaati/gigabot). It uses a **two-layer architecture**:
7
+
8
+ 1. **Event Handler** — A Next.js server that orchestrates everything: web UI, Telegram chat, cron scheduling, webhook triggers, and job creation.
9
+ 2. **Docker Agent** — A container that runs the Pi coding agent for autonomous task execution. Each job gets its own branch, container, and PR.
10
+
11
+ All core logic lives in the `gigabot` npm package. This project is a scaffolded shell — thin Next.js wiring, user-editable configuration, GitHub Actions workflows, and Docker files.
12
+
13
+ ## Directory Structure
14
+
15
+ ```
16
+ project-root/
17
+ ├── CLAUDE.md # This file (project documentation)
18
+ ├── next.config.mjs # Next.js config (wraps withGigabot())
19
+ ├── instrumentation.js # Server startup hook (re-exports from package)
20
+ ├── middleware.js # Auth middleware (re-exports from package)
21
+ ├── .env # API keys and tokens (gitignored)
22
+ ├── package.json
23
+
24
+ ├── app/ # Next.js app directory (page shells + client components)
25
+ │ ├── api/[...gigabot]/route.js # Catch-all API route (re-exports from package)
26
+ │ ├── stream/chat/route.js # Chat streaming endpoint (session auth)
27
+ │ └── components/ # Client-side components
28
+
29
+ ├── config/ # Agent configuration (user-editable)
30
+ │ ├── SOUL.md # Personality, identity, and values
31
+ │ ├── JOB_PLANNING.md # Event handler LLM system prompt
32
+ │ ├── JOB_AGENT.md # Agent runtime environment docs
33
+ │ ├── JOB_SUMMARY.md # Prompt for summarizing completed jobs
34
+ │ ├── HEARTBEAT.md # Self-monitoring / heartbeat behavior
35
+ │ ├── SKILL_BUILDING_GUIDE.md # Guide for building agent skills
36
+ │ ├── CRONS.json # Scheduled job definitions
37
+ │ └── TRIGGERS.json # Webhook trigger definitions
38
+
39
+ ├── .github/workflows/ # GitHub Actions
40
+ ├── docker/ # Docker files (job agent + event handler)
41
+ ├── skills/ # All available agent skills
42
+ │ └── active/ # Symlinks to active skills (shared by Pi + Claude Code)
43
+ ├── .pi/skills → skills/active # Pi reads skills from here
44
+ ├── .claude/skills → skills/active # Claude Code reads skills from here
45
+ ├── cron/ # Scripts for command-type cron actions
46
+ ├── triggers/ # Scripts for command-type trigger actions
47
+ ├── logs/ # Per-job output (logs/<JOB_ID>/job.md + session .jsonl)
48
+ └── data/ # SQLite database (data/gigabot.sqlite)
49
+ ```
50
+
51
+ ## Two-Layer Architecture
52
+
53
+ ```
54
+ ┌─────────────────────────────────────────────────────────────────────────┐
55
+ │ │
56
+ │ ┌──────────────────┐ ┌──────────────────┐ │
57
+ │ │ Event Handler │ ──1──► │ GitHub │ │
58
+ │ │ (creates job) │ │ (job/* branch) │ │
59
+ │ └────────▲─────────┘ └────────┬─────────┘ │
60
+ │ │ │ │
61
+ │ │ 2 (triggers run-job.yml) │
62
+ │ │ │ │
63
+ │ │ ▼ │
64
+ │ │ ┌──────────────────┐ │
65
+ │ │ │ Docker Agent │ │
66
+ │ │ │ (runs Pi, PRs) │ │
67
+ │ │ └────────┬─────────┘ │
68
+ │ │ │ │
69
+ │ │ 3 (creates PR) │
70
+ │ │ │ │
71
+ │ │ ▼ │
72
+ │ │ ┌──────────────────┐ │
73
+ │ │ │ GitHub │ │
74
+ │ │ │ (PR opened) │ │
75
+ │ │ └────────┬─────────┘ │
76
+ │ │ │ │
77
+ │ │ 4a (auto-merge.yml) │
78
+ │ │ 4b (notify-pr-complete.yml) │
79
+ │ │ │ │
80
+ │ 5 (notification → web UI │ │
81
+ │ and Telegram) │ │
82
+ │ └────────────────────────────┘ │
83
+ │ │
84
+ └─────────────────────────────────────────────────────────────────────────┘
85
+ ```
86
+
87
+ **Event Handler** (this Next.js server): Receives requests (web UI, Telegram, webhooks, cron timers), creates jobs by pushing a `job/<uuid>` branch to GitHub, and manages the web interface.
88
+
89
+ **Docker Agent**: A container spun up by GitHub Actions (`run-job.yml`) that clones the job branch, runs the Pi coding agent with the job prompt, commits results, and opens a PR.
90
+
91
+ ## Job Lifecycle
92
+
93
+ 1. **Job created** — Event handler calls `createJob()` (via chat, cron, trigger, or API)
94
+ 2. **Branch pushed** — A `job/<uuid>` branch is created with `logs/<uuid>/job.md` containing the task prompt
95
+ 3. **Workflow triggers** — `run-job.yml` fires on `job/*` branch creation
96
+ 4. **Container runs** — Docker agent clones the branch, builds `SYSTEM.md` from `config/SOUL.md` + `config/AGENT.md`, runs Pi with the job prompt, and logs the session to `logs/<uuid>/`
97
+ 5. **PR created** — Agent commits results and opens a pull request
98
+ 6. **Auto-merge** — `auto-merge.yml` squash-merges the PR if all changed files fall within `ALLOWED_PATHS` prefixes (default: `/logs`)
99
+ 7. **Notification** — `notify-pr-complete.yml` sends job results back to the event handler, which creates a notification in the web UI and sends a Telegram message
100
+
101
+ ## Action Types
102
+
103
+ Both cron jobs and webhook triggers use the same dispatch system. Every action has a `type` field:
104
+
105
+ | | `agent` (default) | `command` | `webhook` |
106
+ |---|---|---|---|
107
+ | **Uses LLM** | Yes — spins up Pi in Docker | No | No |
108
+ | **Runtime** | Minutes to hours | Milliseconds to seconds | Milliseconds to seconds |
109
+ | **Cost** | LLM API calls + GitHub Actions | Free (runs on event handler) | Free (runs on event handler) |
110
+ | **Use case** | Tasks that need to think, reason, write code | Shell scripts, file operations | Call external APIs, forward webhooks |
111
+
112
+ If the task needs to *think*, use `agent`. If it just needs to *do*, use `command`. If it needs to *call an external service*, use `webhook`.
113
+
114
+ ### Agent action
115
+ ```json
116
+ { "type": "agent", "job": "Analyze the logs and write a summary report" }
117
+ ```
118
+ Creates a Docker Agent job. The `job` string is passed as-is to the LLM as its task prompt.
119
+
120
+ ### Command action
121
+ ```json
122
+ { "type": "command", "command": "node cleanup.js --older-than 7d" }
123
+ ```
124
+ Runs a shell command on the event handler. Working directory: `cron/` for crons, `triggers/` for triggers.
125
+
126
+ ### Webhook action
127
+ ```json
128
+ {
129
+ "type": "webhook",
130
+ "url": "https://api.example.com/notify",
131
+ "method": "POST",
132
+ "headers": { "Authorization": "Bearer token" },
133
+ "vars": { "source": "my-agent" }
134
+ }
135
+ ```
136
+ Makes an HTTP request. `GET` skips the body. `POST` (default) sends `{ ...vars }` or `{ ...vars, data: <incoming payload> }` when triggered by a webhook.
137
+
138
+ ## Cron Jobs
139
+
140
+ Defined in `config/CRONS.json`, loaded at server startup by `node-cron`.
141
+
142
+ ```json
143
+ [
144
+ {
145
+ "name": "Daily Check",
146
+ "schedule": "0 9 * * *",
147
+ "type": "agent",
148
+ "job": "Review recent activity and summarize findings",
149
+ "enabled": true
150
+ }
151
+ ]
152
+ ```
153
+
154
+ | Field | Required | Description |
155
+ |-------|----------|-------------|
156
+ | `name` | Yes | Display name |
157
+ | `schedule` | Yes | Cron expression (e.g., `0 9 * * *` = daily at 9am) |
158
+ | `type` | No | `agent` (default), `command`, or `webhook` |
159
+ | `job` | For agent | Task prompt passed to the LLM |
160
+ | `command` | For command | Shell command (runs in `cron/` directory) |
161
+ | `url` | For webhook | Target URL |
162
+ | `method` | For webhook | `GET` or `POST` (default: `POST`) |
163
+ | `headers` | For webhook | Custom request headers |
164
+ | `vars` | For webhook | Key-value pairs merged into request body |
165
+ | `enabled` | No | Set `false` to disable (default: `true`) |
166
+ | `llm_provider` | No | Override LLM provider for this cron (agent type only) |
167
+ | `llm_model` | No | Override LLM model for this cron (agent type only) |
168
+
169
+ ## Webhook Triggers
170
+
171
+ Defined in `config/TRIGGERS.json`, loaded at server startup. Triggers fire on POST requests to watched paths (after auth, before route handler, fire-and-forget).
172
+
173
+ ```json
174
+ [
175
+ {
176
+ "name": "GitHub Push",
177
+ "watch_path": "/webhook/github-push",
178
+ "enabled": true,
179
+ "actions": [
180
+ {
181
+ "type": "agent",
182
+ "job": "Review the push to {{body.ref}}: {{body.head_commit.message}}"
183
+ }
184
+ ]
185
+ }
186
+ ]
187
+ ```
188
+
189
+ | Field | Required | Description |
190
+ |-------|----------|-------------|
191
+ | `name` | Yes | Display name |
192
+ | `watch_path` | Yes | URL path to watch (e.g., `/webhook/github-push`) |
193
+ | `actions` | Yes | Array of actions to fire (same fields as cron actions) |
194
+ | `enabled` | No | Set `false` to disable (default: `true`) |
195
+
196
+ **Template tokens** for `job` and `command` strings:
197
+
198
+ | Token | Resolves to |
199
+ |-------|-------------|
200
+ | `{{body}}` | Entire request body as JSON |
201
+ | `{{body.field}}` | Nested field from request body |
202
+ | `{{query}}` | All query parameters as JSON |
203
+ | `{{query.field}}` | Specific query parameter |
204
+ | `{{headers}}` | All request headers as JSON |
205
+ | `{{headers.field}}` | Specific request header |
206
+
207
+ ## API Endpoints
208
+
209
+ All API routes are under `/api/`, handled by the catch-all route.
210
+
211
+ | Endpoint | Method | Auth | Purpose |
212
+ |----------|--------|------|---------|
213
+ | `/api/create-job` | POST | `x-api-key` | Create a new autonomous agent job |
214
+ | `/api/telegram/webhook` | POST | `TELEGRAM_WEBHOOK_SECRET` | Telegram bot webhook |
215
+ | `/api/telegram/register` | POST | `x-api-key` | Register Telegram webhook URL |
216
+ | `/api/github/webhook` | POST | `GH_WEBHOOK_SECRET` | Receive notifications from GitHub Actions |
217
+ | `/api/jobs/status` | GET | `x-api-key` | Check status of running/queued jobs |
218
+ | `/api/ping` | GET | Public | Health check |
219
+
220
+ **`x-api-key`**: Database-backed API keys generated through the web UI (Settings > Secrets). Keys are SHA-256 hashed, verified with timing-safe comparison. Format: `tpb_` prefix + 64 hex characters.
221
+
222
+ ## Web Interface
223
+
224
+ Accessible after login at `APP_URL`. Routes: `/` (chat), `/chats` (history), `/chat/[chatId]` (resume chat), `/settings/crons`, `/settings/triggers`, `/settings/secrets` (API keys), `/swarm` (job monitor), `/notifications`, `/login` (auth / first-time admin setup).
225
+
226
+ ## Authentication
227
+
228
+ NextAuth v5 with Credentials provider (email/password), JWT in httpOnly cookies. First visit creates admin account. Browser UI uses Server Actions with `requireAuth()`. API routes use `x-api-key` header. Chat streaming uses a dedicated route at `/stream/chat` with `auth()` session check.
229
+
230
+ ## Database
231
+
232
+ SQLite via Drizzle ORM at `data/gigabot.sqlite`. Auto-initialized and auto-migrated on server startup. Tables: `users`, `chats`, `messages`, `notifications`, `subscriptions`, `settings` (key-value store, also stores API keys). Column naming: camelCase in JS → snake_case in SQL.
233
+
234
+ ## GitHub Actions Workflows
235
+
236
+ | Workflow | Trigger | Purpose |
237
+ |----------|---------|---------|
238
+ | `run-job.yml` | `job/*` branch created | Runs the Docker agent container |
239
+ | `rebuild-event-handler.yml` | Push to `main` | Rebuilds server (fast path or Docker restart) |
240
+ | `upgrade-event-handler.yml` | Manual `workflow_dispatch` | Creates PR to upgrade gigabot package |
241
+ | `build-image.yml` | `docker/pi-coding-agent-job/**` changes | Builds Pi coding agent Docker image to GHCR |
242
+ | `auto-merge.yml` | Job PR opened | Squash-merges if changes are within `ALLOWED_PATHS` |
243
+ | `notify-pr-complete.yml` | After `auto-merge.yml` | Sends job completion notification |
244
+ | `notify-job-failed.yml` | `run-job.yml` fails | Sends failure notification |
245
+
246
+ ## GitHub Secrets & Variables
247
+
248
+ ### Secrets (prefix-based naming)
249
+
250
+ | Prefix | Purpose | Visible to LLM? | Example |
251
+ |--------|---------|------------------|---------|
252
+ | `AGENT_` | Protected credentials for Docker agent | No (filtered by env-sanitizer) | `AGENT_GH_TOKEN`, `AGENT_ANTHROPIC_API_KEY` |
253
+ | `AGENT_LLM_` | LLM-accessible credentials for Docker agent | Yes | `AGENT_LLM_BRAVE_API_KEY` |
254
+ | *(none)* | Workflow-only secrets (never passed to container) | N/A | `GH_WEBHOOK_SECRET` |
255
+
256
+ `AGENT_*` secrets are collected into a `SECRETS` JSON object by `run-job.yml` (prefix stripped) and exported as env vars in the container. `AGENT_LLM_*` go into `LLM_SECRETS` and are not filtered from the LLM's bash environment.
257
+
258
+ ### Repository Variables
259
+
260
+ | Variable | Description | Default |
261
+ |----------|-------------|---------|
262
+ | `APP_URL` | Public URL for the event handler | Required |
263
+ | `AUTO_MERGE` | Set to `"false"` to disable auto-merge | Enabled |
264
+ | `ALLOWED_PATHS` | Comma-separated path prefixes for auto-merge | `/logs` |
265
+ | `JOB_IMAGE_URL` | Docker image for job agent (GHCR URLs trigger auto-builds) | Default gigabot image |
266
+ | `EVENT_HANDLER_IMAGE_URL` | Docker image for event handler | Default gigabot image |
267
+ | `RUNS_ON` | GitHub Actions runner label | `ubuntu-latest` |
268
+ | `LLM_PROVIDER` | LLM provider for Docker agent | `anthropic` |
269
+ | `LLM_MODEL` | LLM model name for Docker agent | Provider default |
270
+
271
+ ## Environment Variables
272
+
273
+ | Variable | Description | Required |
274
+ |----------|-------------|----------|
275
+ | `APP_URL` | Public URL for webhooks and Telegram | Yes |
276
+ | `AUTH_SECRET` | NextAuth session encryption (auto-generated) | Yes |
277
+ | `GH_TOKEN` | GitHub PAT for creating branches/files | Yes |
278
+ | `GH_OWNER` | GitHub repository owner | Yes |
279
+ | `GH_REPO` | GitHub repository name | Yes |
280
+ | `TELEGRAM_BOT_TOKEN` | Telegram bot token | For Telegram |
281
+ | `TELEGRAM_WEBHOOK_SECRET` | Telegram webhook validation secret | No |
282
+ | `TELEGRAM_CHAT_ID` | Default chat ID for notifications | For Telegram |
283
+ | `GH_WEBHOOK_SECRET` | GitHub Actions webhook auth | For notifications |
284
+ | `LLM_PROVIDER` | `anthropic`, `openai`, `google`, or `custom` | No (default: `anthropic`) |
285
+ | `LLM_MODEL` | Model name override | No |
286
+ | `LLM_MAX_TOKENS` | Max tokens for LLM responses | No (default: 4096) |
287
+ | `ANTHROPIC_API_KEY` | Anthropic API key | For anthropic provider |
288
+ | `OPENAI_API_KEY` | OpenAI API key / Whisper | For openai provider |
289
+ | `OPENAI_BASE_URL` | Custom OpenAI-compatible base URL | For custom provider |
290
+ | `GOOGLE_API_KEY` | Google API key | For google provider |
291
+ | `CUSTOM_API_KEY` | Custom provider API key | For custom provider |
292
+ | `DATABASE_PATH` | Override SQLite DB location | No |
293
+
294
+ ## Customization
295
+
296
+ User-editable config files in `config/`: `SOUL.md` (personality), `JOB_PLANNING.md` (LLM system prompt), `JOB_AGENT.md` (runtime docs), `JOB_SUMMARY.md` (job summaries), `HEARTBEAT.md` (self-monitoring), `SKILL_BUILDING_GUIDE.md` (skill guide), `CRONS.json` (scheduled jobs), `TRIGGERS.json` (webhook triggers).
297
+
298
+ Skills in `skills/` are activated by symlinking into `skills/active/`. Both `.pi/skills` and `.claude/skills` point to `skills/active/`. Scripts for command-type actions go in `cron/` and `triggers/`.
299
+
300
+ ### Markdown includes and variables
301
+
302
+ Config markdown files support includes and built-in variables (processed by the package's `render-md.js`):
303
+
304
+ | Syntax | Description |
305
+ |--------|-------------|
306
+ | `{{ filepath.md }}` | Include another file (relative to project root, recursive with circular detection) |
307
+ | `{{datetime}}` | Current ISO timestamp |
308
+ | `{{skills}}` | Dynamic bullet list of active skill descriptions from `skills/active/*/SKILL.md` frontmatter — never hardcode skill names, this is resolved at runtime |
@@ -0,0 +1 @@
1
+ export { GET, POST } from 'gigaclaw/api';
@@ -0,0 +1 @@
1
+ export { GET, POST } from 'gigaclaw/auth';
@@ -0,0 +1,9 @@
1
+ import { auth } from 'gigaclaw/auth';
2
+ import { ChatPage } from 'gigaclaw/chat';
3
+
4
+ export default async function ChatRoute({ params }) {
5
+ // Next.js 15: params is synchronous — no await needed
6
+ const { chatId } = params;
7
+ const session = await auth();
8
+ return <ChatPage session={session} needsSetup={false} chatId={chatId} />;
9
+ }
@@ -0,0 +1,7 @@
1
+ import { auth } from 'gigaclaw/auth';
2
+ import { ChatsPage } from 'gigaclaw/chat';
3
+
4
+ export default async function ChatsRoute() {
5
+ const session = await auth();
6
+ return <ChatsPage session={session} />;
7
+ }
@@ -0,0 +1,9 @@
1
+ import { auth } from 'gigaclaw/auth';
2
+ import { CodePage } from 'gigaclaw/code';
3
+
4
+ export default async function CodeRoute({ params }) {
5
+ const session = await auth();
6
+ // Next.js 15: params is synchronous — no await needed
7
+ const { codeWorkspaceId } = params;
8
+ return <CodePage session={session} codeWorkspaceId={codeWorkspaceId} />;
9
+ }
@@ -0,0 +1,12 @@
1
+ export function AsciiLogo() {
2
+ return (
3
+ <pre className="text-foreground text-[clamp(0.45rem,1.5vw,0.85rem)] leading-snug text-left mb-8 select-none">{` _____ _ ____ _
4
+ / ____(_) | _ \ | |
5
+ | | __ _ __ _ __ _| |_) | ___ | |_
6
+ | | |_ | |/ _\` |/ _\` | _ < / _ \| __|
7
+ | |__| | | (_| | (_| | |_) | (_) | |_
8
+ \_____|_|\__, |\__,_|____/ \___/ \__|
9
+ __/ |
10
+ |___/ Powered by Gignaati`}</pre>
11
+ );
12
+ }