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
package/LICENSE ADDED
@@ -0,0 +1,26 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Gignaati (https://www.gignaati.com)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
23
+ ---
24
+
25
+ This project is based on the open-source agent framework by the original authors,
26
+ also licensed under the MIT License.
package/README.md ADDED
@@ -0,0 +1,237 @@
1
+ <div align="center">
2
+
3
+ # Giga Bot
4
+
5
+ ### Autonomous AI Agent Platform — Powered by Gignaati
6
+
7
+ [![npm version](https://img.shields.io/npm/v/gigaclaw?color=000&labelColor=000&logo=npm&label=gigaclaw)](https://www.npmjs.com/package/gigaclaw)
8
+ [![License: MIT](https://img.shields.io/badge/License-MIT-000?labelColor=000)](LICENSE)
9
+ [![GitHub Stars](https://img.shields.io/github/stars/gignaati/gigaclaw?color=000&labelColor=000)](https://github.com/gignaati/gigaclaw/stargazers)
10
+ [![Made in India](https://img.shields.io/badge/Made%20in-India-FF9933?labelColor=000)](https://www.gignaati.com)
11
+
12
+ **Build, deploy, and run autonomous AI agents 24/7.**
13
+ India-first. Edge-native. Zero vendor lock-in.
14
+
15
+ [Website](https://www.gignaati.com) · [Documentation](https://github.com/gignaati/gigaclaw/wiki) · [Issues](https://github.com/gignaati/gigaclaw/issues) · [Discussions](https://github.com/gignaati/gigaclaw/discussions)
16
+
17
+ </div>
18
+
19
+ ---
20
+
21
+ ## What is Giga Bot?
22
+
23
+ Giga Bot is a self-hosted, autonomous AI agent platform. You deploy it to your own server or VPS, and it runs 24/7 — responding to messages, executing scheduled jobs, handling webhooks, writing code, managing files, and completing complex multi-step tasks.
24
+
25
+ It is built on a two-layer architecture:
26
+
27
+ - **Event Handler** — A Next.js server that handles real-time chat (web UI + Telegram), manages your agent's configuration, and creates jobs for the agent to execute.
28
+ - **Agent Engine** — A Docker container that runs your agent jobs using GitHub Actions or a local Docker daemon. The agent can write code, run shell commands, browse the web, and interact with GitHub.
29
+
30
+ Giga Bot is the only autonomous agent platform with **native PragatiGPT support** — India's indigenous Small Language Model for edge deployment, delivering 100% data privacy and zero foreign cloud dependency.
31
+
32
+ ---
33
+
34
+ ## One-Line Install
35
+
36
+ ### Linux / macOS
37
+ ```bash
38
+ curl -fsSL https://raw.githubusercontent.com/gignaati/gigaclaw/main/install.sh | bash
39
+ ```
40
+
41
+ ### Windows (PowerShell)
42
+ ```powershell
43
+ irm https://raw.githubusercontent.com/gignaati/gigaclaw/main/install.ps1 | iex
44
+ ```
45
+
46
+ ### All Platforms (npm / npx)
47
+ ```bash
48
+ # Create a new Giga Bot project
49
+ mkdir my-gigaclaw && cd my-gigaclaw
50
+ npx gigaclaw@latest init
51
+
52
+ # Then run the interactive setup wizard
53
+ npm run setup
54
+ ```
55
+
56
+ > **Prerequisites:** [Node.js 18+](https://nodejs.org), [Docker](https://docs.docker.com/get-docker/), [Git](https://git-scm.com)
57
+
58
+ ---
59
+
60
+ ## Quick Start (5 Steps)
61
+
62
+ **Step 1 — Create a new GitHub repository** for your agent (e.g., `my-gigaclaw`).
63
+
64
+ **Step 2 — Install Giga Bot** into a local folder with the same name:
65
+ ```bash
66
+ mkdir my-gigaclaw && cd my-gigaclaw
67
+ npx gigaclaw@latest init
68
+ npm install
69
+ ```
70
+
71
+ **Step 3 — Run the setup wizard:**
72
+ ```bash
73
+ npm run setup
74
+ ```
75
+ The wizard will ask for:
76
+ - Your GitHub Personal Access Token
77
+ - Your public URL (domain or ngrok URL)
78
+ - Your LLM provider and API key (Claude, GPT, Gemini, PragatiGPT, or Ollama)
79
+
80
+ **Step 4 — Start your agent:**
81
+ ```bash
82
+ docker compose up -d
83
+ ```
84
+
85
+ **Step 5 — Chat with your agent** at your APP_URL.
86
+
87
+ ---
88
+
89
+ ## Supported LLM Providers
90
+
91
+ Giga Bot supports **6 LLM providers** — more than any other self-hosted agent platform:
92
+
93
+ | Provider | Description | Data Privacy |
94
+ |---|---|---|
95
+ | **PragatiGPT** | Gignaati's India-first SLM — edge-native, on-premise | 100% — no foreign cloud |
96
+ | **Ollama** | Run any open-source model locally (Llama, Mistral, Qwen, Phi) | 100% — fully local |
97
+ | **Claude (Anthropic)** | claude-opus-4, claude-sonnet-4, claude-haiku-4 | Anthropic's servers |
98
+ | **GPT (OpenAI)** | gpt-5.2, gpt-4o, o4-mini | OpenAI's servers |
99
+ | **Gemini (Google)** | gemini-3.1-pro, gemini-2.5-flash | Google's servers |
100
+ | **Custom API** | Any OpenAI-compatible endpoint (vLLM, LM Studio, Together AI) | Depends on endpoint |
101
+
102
+ Set your provider in `.env`:
103
+ ```bash
104
+ LLM_PROVIDER=pragatigpt # India-first, edge-native
105
+ LLM_PROVIDER=ollama # Fully local, zero cloud
106
+ LLM_PROVIDER=anthropic # Claude (default)
107
+ LLM_PROVIDER=openai # GPT
108
+ LLM_PROVIDER=google # Gemini
109
+ LLM_PROVIDER=custom # Any OpenAI-compatible API
110
+ ```
111
+
112
+ ---
113
+
114
+ ## Features
115
+
116
+ ### Agent Capabilities
117
+ - **Web Chat** — Chat with your agent at your APP_URL
118
+ - **Telegram** — Connect a Telegram bot with `npm run setup-telegram`
119
+ - **Scheduled Jobs** — Cron-based recurring tasks via `config/CRONS.json`
120
+ - **Webhook Triggers** — POST to `/api/create-job` to trigger jobs programmatically
121
+ - **Code Workspace** — Full terminal and code editor in the browser
122
+ - **File Uploads** — Upload images, PDFs, and text files to the chat
123
+
124
+ ### Agent Tools
125
+ - **Code execution** — Write and run code in any language
126
+ - **Shell commands** — Execute terminal commands
127
+ - **Web search** — Search the internet for up-to-date information
128
+ - **GitHub integration** — Create PRs, manage issues, push commits
129
+ - **File system** — Read, write, and manage files in the repository
130
+
131
+ ### Infrastructure
132
+ - **Docker Compose** — One-command deployment with Traefik reverse proxy
133
+ - **Auto SSL** — Let's Encrypt certificates via Traefik
134
+ - **GitHub Actions** — Agent jobs run in isolated Docker containers
135
+ - **Auto-merge** — Agent can merge its own PRs after review
136
+ - **Hot reload** — Push to `main` triggers automatic rebuild and restart
137
+
138
+ ### Giga Bot Exclusive Features
139
+ - **PragatiGPT** — India's indigenous SLM for edge deployment
140
+ - **Ollama** — Run any open-source model with zero cloud dependency
141
+ - **Multi-LLM routing** — Different LLMs for chat vs. agent jobs
142
+ - **Per-job LLM override** — Specify `llm_provider` and `llm_model` per cron job
143
+
144
+ ---
145
+
146
+ ## CLI Commands
147
+
148
+ ```bash
149
+ npx gigaclaw init # Scaffold or update project files
150
+ npx gigaclaw setup # Run interactive setup wizard
151
+ npx gigaclaw setup-telegram # Configure Telegram bot
152
+ npx gigaclaw upgrade [@beta|version] # Upgrade to latest version
153
+ npx gigaclaw reset-auth # Regenerate AUTH_SECRET
154
+ npx gigaclaw reset [file] # Restore a template file
155
+ npx gigaclaw diff [file] # Show differences vs. templates
156
+ npx gigaclaw set-agent-secret <KEY> [VALUE] # Set GitHub secret (AGENT_ prefix)
157
+ npx gigaclaw set-agent-llm-secret <KEY> [VALUE] # Set LLM secret (AGENT_LLM_ prefix)
158
+ npx gigaclaw set-var <KEY> [VALUE] # Set GitHub repository variable
159
+ ```
160
+
161
+ ---
162
+
163
+ ## Configuration Files
164
+
165
+ These files in `config/` define your agent's personality and behavior. They are **yours to customize** — Giga Bot will never overwrite them:
166
+
167
+ | File | Purpose |
168
+ |---|---|
169
+ | `SOUL.md` | Your agent's identity, personality, and values |
170
+ | `JOB_PLANNING.md` | How your agent plans and breaks down jobs |
171
+ | `JOB_AGENT.md` | Instructions for executing jobs |
172
+ | `CRONS.json` | Scheduled recurring jobs |
173
+ | `TRIGGERS.json` | Webhook trigger definitions |
174
+ | `HEARTBEAT.md` | Tasks for the periodic heartbeat cron |
175
+
176
+ ---
177
+
178
+ ## Updating
179
+
180
+ ```bash
181
+ npx gigaclaw upgrade # Latest stable
182
+ npx gigaclaw upgrade @beta # Latest beta
183
+ npx gigaclaw upgrade 1.2.72 # Specific version
184
+ ```
185
+
186
+ ---
187
+
188
+ ## Deployment
189
+
190
+ Giga Bot runs on any Linux server with Docker. Recommended:
191
+
192
+ | Provider | Spec | Monthly Cost |
193
+ |---|---|---|
194
+ | Hetzner CX22 | 2 vCPU, 4 GB RAM | ~€4 |
195
+ | DigitalOcean Droplet | 2 vCPU, 4 GB RAM | ~$24 |
196
+ | AWS EC2 t3.small | 2 vCPU, 2 GB RAM | ~$15 |
197
+ | Your own hardware | Any Linux machine | ₹0 |
198
+
199
+ For local development, use [ngrok](https://ngrok.com) to expose your machine:
200
+ ```bash
201
+ ngrok http 80
202
+ # Then update APP_URL: npx gigaclaw set-var APP_URL https://your-url.ngrok.io
203
+ ```
204
+
205
+ ---
206
+
207
+ ## Privacy & Legal
208
+
209
+ - [Privacy Policy](https://www.gignaati.com/privacy-policy)
210
+ - [Terms of Service](https://www.gignaati.com/terms-of-service)
211
+ - [Security Policy](SECURITY.md)
212
+ - [License](LICENSE) — MIT
213
+
214
+ ---
215
+
216
+ ## Contributing
217
+
218
+ Contributions are welcome! Please read [CONTRIBUTING.md](CONTRIBUTING.md) before submitting a pull request.
219
+
220
+ ---
221
+
222
+ ## Support
223
+
224
+ - **GitHub Issues:** [github.com/gignaati/gigaclaw/issues](https://github.com/gignaati/gigaclaw/issues)
225
+ - **Discussions:** [github.com/gignaati/gigaclaw/discussions](https://github.com/gignaati/gigaclaw/discussions)
226
+ - **Email:** support@gignaati.com
227
+ - **Website:** [www.gignaati.com](https://www.gignaati.com)
228
+
229
+ ---
230
+
231
+ <div align="center">
232
+
233
+ **Built with care by [Gignaati](https://www.gignaati.com) — India's Edge AI Ecosystem**
234
+
235
+ [Privacy Policy](https://www.gignaati.com/privacy-policy) · [Terms of Service](https://www.gignaati.com/terms-of-service) · [Security](SECURITY.md)
236
+
237
+ </div>
package/api/CLAUDE.md ADDED
@@ -0,0 +1,19 @@
1
+ # /api — External API Routes
2
+
3
+ This directory contains the route handlers for all `/api/*` endpoints. These routes are for **external callers only** — GitHub Actions, Telegram, cURL, third-party webhooks.
4
+
5
+ ## Auth
6
+
7
+ All routes (except `/telegram/webhook` and `/github/webhook`, which use their own webhook secrets) require a valid API key passed via the `x-api-key` header. API keys are stored in the SQLite database and managed through the admin UI — they are NOT environment variables.
8
+
9
+ Auth flow: `x-api-key` header -> `verifyApiKey()` -> database lookup (hashed, timing-safe comparison).
10
+
11
+ ## Do NOT use these routes for browser UI
12
+
13
+ Browser-facing features must use **Server Actions** (`'use server'` functions) with `requireAuth()` session checks — never `/api` fetch calls. The only exception is chat streaming, which has its own dedicated route at `/stream/chat` with session auth.
14
+
15
+ | Caller | Mechanism | Auth |
16
+ |--------|-----------|------|
17
+ | External (cURL, GitHub Actions, Telegram) | `/api` route | `x-api-key` header |
18
+ | Browser UI (data/mutations) | Server Action | `requireAuth()` session |
19
+ | Browser UI (chat streaming) | `/stream/chat` | `auth()` session |
package/api/index.js ADDED
@@ -0,0 +1,265 @@
1
+ import { createHash, timingSafeEqual } from 'crypto';
2
+ import { createJob } from '../lib/tools/create-job.js';
3
+ import { setWebhook } from '../lib/tools/telegram.js';
4
+ import { getJobStatus, fetchJobLog } from '../lib/tools/github.js';
5
+ import { getTelegramAdapter } from '../lib/channels/index.js';
6
+ import { chat, summarizeJob } from '../lib/ai/index.js';
7
+ import { createNotification } from '../lib/db/notifications.js';
8
+ import { loadTriggers } from '../lib/triggers.js';
9
+ import { verifyApiKey } from '../lib/db/api-keys.js';
10
+
11
+ // Bot token from env, can be overridden by /telegram/register
12
+ let telegramBotToken = null;
13
+
14
+ // Cached trigger firing function (initialized on first request)
15
+ let _fireTriggers = null;
16
+
17
+ function getTelegramBotToken() {
18
+ if (!telegramBotToken) {
19
+ telegramBotToken = process.env.TELEGRAM_BOT_TOKEN || null;
20
+ }
21
+ return telegramBotToken;
22
+ }
23
+
24
+ function getFireTriggers() {
25
+ if (!_fireTriggers) {
26
+ const result = loadTriggers();
27
+ _fireTriggers = result.fireTriggers;
28
+ }
29
+ return _fireTriggers;
30
+ }
31
+
32
+ // Routes that have their own authentication
33
+ const PUBLIC_ROUTES = ['/telegram/webhook', '/github/webhook', '/ping'];
34
+
35
+ /**
36
+ * Timing-safe string comparison.
37
+ * @param {string} a
38
+ * @param {string} b
39
+ * @returns {boolean}
40
+ */
41
+ function safeCompare(a, b) {
42
+ if (!a || !b) return false;
43
+ const bufA = Buffer.from(a);
44
+ const bufB = Buffer.from(b);
45
+ if (bufA.length !== bufB.length) return false;
46
+ return timingSafeEqual(bufA, bufB);
47
+ }
48
+
49
+ /**
50
+ * Centralized auth gate for all API routes.
51
+ * Public routes pass through; everything else requires a valid API key from the database.
52
+ * @param {string} routePath - The route path
53
+ * @param {Request} request - The incoming request
54
+ * @returns {Response|null} - Error response or null if authorized
55
+ */
56
+ function checkAuth(routePath, request) {
57
+ if (PUBLIC_ROUTES.includes(routePath)) return null;
58
+
59
+ const apiKey = request.headers.get('x-api-key');
60
+ if (!apiKey) {
61
+ return Response.json({ error: 'Unauthorized' }, { status: 401 });
62
+ }
63
+
64
+ const record = verifyApiKey(apiKey);
65
+ if (!record) {
66
+ return Response.json({ error: 'Unauthorized' }, { status: 401 });
67
+ }
68
+
69
+ return null;
70
+ }
71
+
72
+ /**
73
+ * Extract job ID from branch name (e.g., "job/abc123" -> "abc123")
74
+ */
75
+ function extractJobId(branchName) {
76
+ if (!branchName || !branchName.startsWith('job/')) return null;
77
+ return branchName.slice(4);
78
+ }
79
+
80
+ // ─────────────────────────────────────────────────────────────────────────────
81
+ // Route handlers
82
+ // ─────────────────────────────────────────────────────────────────────────────
83
+
84
+ async function handleWebhook(request) {
85
+ const body = await request.json();
86
+ const { job } = body;
87
+ if (!job) return Response.json({ error: 'Missing job field' }, { status: 400 });
88
+
89
+ try {
90
+ const result = await createJob(job);
91
+ return Response.json(result);
92
+ } catch (err) {
93
+ console.error(err);
94
+ return Response.json({ error: 'Failed to create job' }, { status: 500 });
95
+ }
96
+ }
97
+
98
+ async function handleTelegramRegister(request) {
99
+ const body = await request.json();
100
+ const { bot_token, webhook_url } = body;
101
+ if (!bot_token || !webhook_url) {
102
+ return Response.json({ error: 'Missing bot_token or webhook_url' }, { status: 400 });
103
+ }
104
+
105
+ try {
106
+ const result = await setWebhook(bot_token, webhook_url, process.env.TELEGRAM_WEBHOOK_SECRET);
107
+ telegramBotToken = bot_token;
108
+ return Response.json({ success: true, result });
109
+ } catch (err) {
110
+ console.error(err);
111
+ return Response.json({ error: 'Failed to register webhook' }, { status: 500 });
112
+ }
113
+ }
114
+
115
+ async function handleTelegramWebhook(request) {
116
+ const botToken = getTelegramBotToken();
117
+ if (!botToken) return Response.json({ ok: true });
118
+
119
+ const adapter = getTelegramAdapter(botToken);
120
+ const normalized = await adapter.receive(request);
121
+ if (!normalized) return Response.json({ ok: true });
122
+
123
+ // Process message asynchronously (don't block the webhook response)
124
+ processChannelMessage(adapter, normalized).catch((err) => {
125
+ console.error('Failed to process message:', err);
126
+ });
127
+
128
+ return Response.json({ ok: true });
129
+ }
130
+
131
+ /**
132
+ * Process a normalized message through the AI layer with channel UX.
133
+ * Message persistence is handled centrally by the AI layer.
134
+ */
135
+ async function processChannelMessage(adapter, normalized) {
136
+ await adapter.acknowledge(normalized.metadata);
137
+ const stopIndicator = adapter.startProcessingIndicator(normalized.metadata);
138
+
139
+ try {
140
+ const response = await chat(
141
+ normalized.threadId,
142
+ normalized.text,
143
+ normalized.attachments,
144
+ { userId: 'telegram', chatTitle: 'Telegram' }
145
+ );
146
+ await adapter.sendResponse(normalized.threadId, response, normalized.metadata);
147
+ } catch (err) {
148
+ console.error('Failed to process message with AI:', err);
149
+ await adapter
150
+ .sendResponse(
151
+ normalized.threadId,
152
+ 'Sorry, I encountered an error processing your message.',
153
+ normalized.metadata
154
+ )
155
+ .catch(() => {});
156
+ } finally {
157
+ stopIndicator();
158
+ }
159
+ }
160
+
161
+ async function handleGithubWebhook(request) {
162
+ const { GH_WEBHOOK_SECRET } = process.env;
163
+
164
+ // Validate webhook secret (timing-safe, required)
165
+ if (!GH_WEBHOOK_SECRET || !safeCompare(request.headers.get('x-github-webhook-secret-token'), GH_WEBHOOK_SECRET)) {
166
+ return Response.json({ error: 'Unauthorized' }, { status: 401 });
167
+ }
168
+
169
+ const payload = await request.json();
170
+ const jobId = payload.job_id || extractJobId(payload.branch);
171
+ if (!jobId) return Response.json({ ok: true, skipped: true, reason: 'not a job' });
172
+
173
+ try {
174
+ // Fetch log from repo via API (no longer sent in payload)
175
+ let log = payload.log || '';
176
+ if (!log) {
177
+ log = await fetchJobLog(jobId, payload.commit_sha);
178
+ }
179
+
180
+ const results = {
181
+ job: payload.job || '',
182
+ pr_url: payload.pr_url || payload.run_url || '',
183
+ run_url: payload.run_url || '',
184
+ status: payload.status || '',
185
+ merge_result: payload.merge_result || '',
186
+ log,
187
+ changed_files: payload.changed_files || [],
188
+ commit_message: payload.commit_message || '',
189
+ };
190
+
191
+ const message = await summarizeJob(results);
192
+ await createNotification(message, payload);
193
+
194
+ console.log(`Notification saved for job ${jobId.slice(0, 8)}`);
195
+
196
+ return Response.json({ ok: true, notified: true });
197
+ } catch (err) {
198
+ console.error('Failed to process GitHub webhook:', err);
199
+ return Response.json({ error: 'Failed to process webhook' }, { status: 500 });
200
+ }
201
+ }
202
+
203
+ async function handleJobStatus(request) {
204
+ try {
205
+ const url = new URL(request.url);
206
+ const jobId = url.searchParams.get('job_id');
207
+ const result = await getJobStatus(jobId);
208
+ return Response.json(result);
209
+ } catch (err) {
210
+ console.error('Failed to get job status:', err);
211
+ return Response.json({ error: 'Failed to get job status' }, { status: 500 });
212
+ }
213
+ }
214
+
215
+ // ─────────────────────────────────────────────────────────────────────────────
216
+ // Next.js Route Handlers (catch-all)
217
+ // ─────────────────────────────────────────────────────────────────────────────
218
+
219
+ async function POST(request) {
220
+ const url = new URL(request.url);
221
+ const routePath = url.pathname.replace(/^\/api/, '');
222
+
223
+ // Auth check
224
+ const authError = checkAuth(routePath, request);
225
+ if (authError) return authError;
226
+
227
+ // Fire triggers (non-blocking)
228
+ try {
229
+ const fireTriggers = getFireTriggers();
230
+ // Clone request to read body for triggers without consuming it for the handler
231
+ const clonedRequest = request.clone();
232
+ const body = await clonedRequest.json().catch(() => ({}));
233
+ const query = Object.fromEntries(url.searchParams);
234
+ const headers = Object.fromEntries(request.headers);
235
+ fireTriggers(routePath, body, query, headers);
236
+ } catch (e) {
237
+ // Trigger errors are non-fatal
238
+ }
239
+
240
+ // Route to handler
241
+ switch (routePath) {
242
+ case '/create-job': return handleWebhook(request);
243
+ case '/telegram/webhook': return handleTelegramWebhook(request);
244
+ case '/telegram/register': return handleTelegramRegister(request);
245
+ case '/github/webhook': return handleGithubWebhook(request);
246
+ default: return Response.json({ error: 'Not found' }, { status: 404 });
247
+ }
248
+ }
249
+
250
+ async function GET(request) {
251
+ const url = new URL(request.url);
252
+ const routePath = url.pathname.replace(/^\/api/, '');
253
+
254
+ // Auth check
255
+ const authError = checkAuth(routePath, request);
256
+ if (authError) return authError;
257
+
258
+ switch (routePath) {
259
+ case '/ping': return Response.json({ message: 'Pong!' });
260
+ case '/jobs/status': return handleJobStatus(request);
261
+ default: return Response.json({ error: 'Not found' }, { status: 404 });
262
+ }
263
+ }
264
+
265
+ export { GET, POST };