grokbot-kit 0.1.0__tar.gz

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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Rodrigo Pasini
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.
@@ -0,0 +1,88 @@
1
+ Metadata-Version: 2.4
2
+ Name: grokbot-kit
3
+ Version: 0.1.0
4
+ Summary: Grok Bot integration kit: delegate tasks to headless coding agents (opencode, Claude Code, Codex) and wake the right Grok Bot routine when they finish or need input.
5
+ Author: Rodrigo Pasini
6
+ License-Expression: MIT
7
+ License-File: LICENSE
8
+ Classifier: Environment :: Console
9
+ Classifier: Operating System :: POSIX :: Linux
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.11
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: Programming Language :: Python :: 3.13
14
+ Requires-Python: >=3.11
15
+ Project-URL: Repository, https://github.com/rodrigo-pasini/grokbot-kit
16
+ Description-Content-Type: text/markdown
17
+
18
+ # grokbot-kit
19
+
20
+ Grok Bot integration kit: delegate tasks to headless coding agents (opencode, Claude Code, Codex) and wake the right
21
+ Grok Bot routine when they finish or need input.
22
+
23
+ > Leia em português: [docs/pt-BR/README.md](docs/pt-BR/README.md)
24
+
25
+ **Status:** pre-release. The repository scaffold is in place; the commands below are being built and are not usable
26
+ yet.
27
+
28
+ ## What it is
29
+
30
+ A Grok Bot that delegates a long task to a headless coding agent hibernates while the agent runs, and nothing wakes
31
+ it up. The exit code alone does not tell whether the task was done, failed, or stopped at a permission prompt.
32
+
33
+ `grokbot-kit` wraps the agent run (`grokbot-kit run`), listens to each agent's native hooks, and sends exactly one
34
+ terminal event (`completed`, `error` or `timeout`) — plus a `needs_input` event when the agent hits a permission — to
35
+ the webhook trigger of the routine of the bot that delegated the task. Other bots are not woken up.
36
+
37
+ ## Install
38
+
39
+ ```sh
40
+ uv tool install --managed-python grokbot-kit
41
+ ```
42
+
43
+ `pipx install grokbot-kit` also works. Before the first release, install from the repository:
44
+
45
+ ```sh
46
+ uv tool install git+https://github.com/rodrigo-pasini/grokbot-kit
47
+ ```
48
+
49
+ Requires Linux and Python 3.11 or newer (`uv` manages the interpreter). The package has no runtime dependencies.
50
+
51
+ ## Quick start
52
+
53
+ ```sh
54
+ grokbot-kit setup cli add opencode
55
+ grokbot-kit setup default opencode
56
+ grokbot-kit secret set mybot-url
57
+ grokbot-kit secret set mybot-key
58
+ grokbot-kit route add mybot --url-secret mybot-url --key-secret mybot-key
59
+ grokbot-kit route test mybot
60
+ grokbot-kit run --target mybot --label rename-vars -- "Rename the variables in x.py"
61
+ ```
62
+
63
+ ## Grok Bot skill
64
+
65
+ `skills/grokbot-kit/` is a skill for any Grok Bot. Copy the folder into the bot's workflows directory and the bot can
66
+ install the kit, install and log in to the CLIs you choose, create the route to its own routine, and delegate tasks
67
+ choosing CLI and model.
68
+
69
+ ## Configuration
70
+
71
+ The configuration lives in `~/.config/grokbot-kit/config.toml`: installed CLIs and the default one, model tiers
72
+ (`trivial`, `standard`, `complex`) per CLI, timeouts per tier, and one route per target bot. Each task keeps its
73
+ output, logs and events in `~/.grokbot-kit/tasks/<task_id>/` until `grokbot-kit gc` removes it.
74
+
75
+ ## Security
76
+
77
+ - Secrets (routine URL and key, API keys) are written with `grokbot-kit secret set` to `~/.secrets/grokbot-kit/`
78
+ with mode `0600`, never to the config file and never pasted into a chat.
79
+ - `grokbot-kit` never writes a secret to logs, stdout, stderr or events.
80
+ - `~/.claude/settings.json` and `~/.codex/` are never modified; Codex runs in its own `CODEX_HOME`.
81
+
82
+ ## Contributing
83
+
84
+ See [CONTRIBUTING.md](CONTRIBUTING.md).
85
+
86
+ ## License
87
+
88
+ [MIT](LICENSE). Third-party material in this repository is listed in [NOTICE](NOTICE).
@@ -0,0 +1,71 @@
1
+ # grokbot-kit
2
+
3
+ Grok Bot integration kit: delegate tasks to headless coding agents (opencode, Claude Code, Codex) and wake the right
4
+ Grok Bot routine when they finish or need input.
5
+
6
+ > Leia em português: [docs/pt-BR/README.md](docs/pt-BR/README.md)
7
+
8
+ **Status:** pre-release. The repository scaffold is in place; the commands below are being built and are not usable
9
+ yet.
10
+
11
+ ## What it is
12
+
13
+ A Grok Bot that delegates a long task to a headless coding agent hibernates while the agent runs, and nothing wakes
14
+ it up. The exit code alone does not tell whether the task was done, failed, or stopped at a permission prompt.
15
+
16
+ `grokbot-kit` wraps the agent run (`grokbot-kit run`), listens to each agent's native hooks, and sends exactly one
17
+ terminal event (`completed`, `error` or `timeout`) — plus a `needs_input` event when the agent hits a permission — to
18
+ the webhook trigger of the routine of the bot that delegated the task. Other bots are not woken up.
19
+
20
+ ## Install
21
+
22
+ ```sh
23
+ uv tool install --managed-python grokbot-kit
24
+ ```
25
+
26
+ `pipx install grokbot-kit` also works. Before the first release, install from the repository:
27
+
28
+ ```sh
29
+ uv tool install git+https://github.com/rodrigo-pasini/grokbot-kit
30
+ ```
31
+
32
+ Requires Linux and Python 3.11 or newer (`uv` manages the interpreter). The package has no runtime dependencies.
33
+
34
+ ## Quick start
35
+
36
+ ```sh
37
+ grokbot-kit setup cli add opencode
38
+ grokbot-kit setup default opencode
39
+ grokbot-kit secret set mybot-url
40
+ grokbot-kit secret set mybot-key
41
+ grokbot-kit route add mybot --url-secret mybot-url --key-secret mybot-key
42
+ grokbot-kit route test mybot
43
+ grokbot-kit run --target mybot --label rename-vars -- "Rename the variables in x.py"
44
+ ```
45
+
46
+ ## Grok Bot skill
47
+
48
+ `skills/grokbot-kit/` is a skill for any Grok Bot. Copy the folder into the bot's workflows directory and the bot can
49
+ install the kit, install and log in to the CLIs you choose, create the route to its own routine, and delegate tasks
50
+ choosing CLI and model.
51
+
52
+ ## Configuration
53
+
54
+ The configuration lives in `~/.config/grokbot-kit/config.toml`: installed CLIs and the default one, model tiers
55
+ (`trivial`, `standard`, `complex`) per CLI, timeouts per tier, and one route per target bot. Each task keeps its
56
+ output, logs and events in `~/.grokbot-kit/tasks/<task_id>/` until `grokbot-kit gc` removes it.
57
+
58
+ ## Security
59
+
60
+ - Secrets (routine URL and key, API keys) are written with `grokbot-kit secret set` to `~/.secrets/grokbot-kit/`
61
+ with mode `0600`, never to the config file and never pasted into a chat.
62
+ - `grokbot-kit` never writes a secret to logs, stdout, stderr or events.
63
+ - `~/.claude/settings.json` and `~/.codex/` are never modified; Codex runs in its own `CODEX_HOME`.
64
+
65
+ ## Contributing
66
+
67
+ See [CONTRIBUTING.md](CONTRIBUTING.md).
68
+
69
+ ## License
70
+
71
+ [MIT](LICENSE). Third-party material in this repository is listed in [NOTICE](NOTICE).
@@ -0,0 +1,58 @@
1
+ [project]
2
+ name = "grokbot-kit"
3
+ version = "0.1.0"
4
+ description = "Grok Bot integration kit: delegate tasks to headless coding agents (opencode, Claude Code, Codex) and wake the right Grok Bot routine when they finish or need input."
5
+ readme = "README.md"
6
+ license = "MIT"
7
+ license-files = ["LICENSE"]
8
+ requires-python = ">=3.11"
9
+ dependencies = []
10
+ classifiers = [
11
+ "Environment :: Console",
12
+ "Operating System :: POSIX :: Linux",
13
+ "Programming Language :: Python :: 3",
14
+ "Programming Language :: Python :: 3.11",
15
+ "Programming Language :: Python :: 3.12",
16
+ "Programming Language :: Python :: 3.13",
17
+ ]
18
+
19
+ [[project.authors]]
20
+ name = "Rodrigo Pasini"
21
+
22
+ [project.urls]
23
+ Repository = "https://github.com/rodrigo-pasini/grokbot-kit"
24
+
25
+ [project.scripts]
26
+ grokbot-kit = "grokbot_kit.cli:main"
27
+
28
+ [build-system]
29
+ requires = ["uv_build>=0.9.26,<0.14.0"]
30
+ build-backend = "uv_build"
31
+
32
+ [dependency-groups]
33
+ dev = [
34
+ "jsonschema>=4.26.0",
35
+ "mypy>=2.4.0",
36
+ "pre-commit>=4.7.0",
37
+ "pytest>=9.1.1",
38
+ "pyyaml>=6.0.3",
39
+ "ruff>=0.17.1",
40
+ ]
41
+
42
+ [tool.ruff]
43
+ target-version = "py311"
44
+ line-length = 120
45
+ extend-exclude = [
46
+ ".claude",
47
+ ".agents",
48
+ ]
49
+ force-exclude = true
50
+
51
+ [tool.mypy]
52
+ strict = true
53
+ files = ["src"]
54
+
55
+ [tool.pytest.ini_options]
56
+ testpaths = ["tests"]
57
+ addopts = "-m 'not integration'"
58
+ markers = ["integration: roda só no box, com as CLIs reais ou o GitHub"]
@@ -0,0 +1,53 @@
1
+ [project]
2
+ name = "grokbot-kit"
3
+ version = "0.1.0"
4
+ description = "Grok Bot integration kit: delegate tasks to headless coding agents (opencode, Claude Code, Codex) and wake the right Grok Bot routine when they finish or need input."
5
+ readme = "README.md"
6
+ license = "MIT"
7
+ license-files = ["LICENSE"]
8
+ authors = [{ name = "Rodrigo Pasini" }]
9
+ requires-python = ">=3.11"
10
+ dependencies = []
11
+ classifiers = [
12
+ "Environment :: Console",
13
+ "Operating System :: POSIX :: Linux",
14
+ "Programming Language :: Python :: 3",
15
+ "Programming Language :: Python :: 3.11",
16
+ "Programming Language :: Python :: 3.12",
17
+ "Programming Language :: Python :: 3.13",
18
+ ]
19
+
20
+ [project.urls]
21
+ Repository = "https://github.com/rodrigo-pasini/grokbot-kit"
22
+
23
+ [project.scripts]
24
+ grokbot-kit = "grokbot_kit.cli:main"
25
+
26
+ [build-system]
27
+ requires = ["uv_build>=0.9.26,<0.14.0"]
28
+ build-backend = "uv_build"
29
+
30
+ [dependency-groups]
31
+ dev = [
32
+ "jsonschema>=4.26.0",
33
+ "mypy>=2.4.0",
34
+ "pre-commit>=4.7.0",
35
+ "pytest>=9.1.1",
36
+ "pyyaml>=6.0.3",
37
+ "ruff>=0.17.1",
38
+ ]
39
+
40
+ [tool.ruff]
41
+ target-version = "py311"
42
+ line-length = 120
43
+ extend-exclude = [".claude", ".agents"]
44
+ force-exclude = true
45
+
46
+ [tool.mypy]
47
+ strict = true
48
+ files = ["src"]
49
+
50
+ [tool.pytest.ini_options]
51
+ testpaths = ["tests"]
52
+ addopts = "-m 'not integration'"
53
+ markers = ["integration: roda só no box, com as CLIs reais ou o GitHub"]
@@ -0,0 +1,5 @@
1
+ """grokbot-kit: delega tarefas a agentes de código headless e acorda a routine do Grok Bot certo."""
2
+
3
+ from importlib.metadata import version
4
+
5
+ __version__ = version("grokbot-kit")
@@ -0,0 +1,311 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/rodrigo-pasini/grokbot-kit/blob/main/src/grokbot_kit/assets/event.v1.json",
4
+ "title": "grokbot-kit.event/v1",
5
+ "description": "Evento enviado pelo grokbot-kit aos sinks de um target (door 2). Os campos de task só são null em event: test.",
6
+ "type": "object",
7
+ "properties": {
8
+ "schema": {
9
+ "const": "grokbot-kit.event/v1"
10
+ },
11
+ "event": {
12
+ "enum": [
13
+ "completed",
14
+ "error",
15
+ "timeout",
16
+ "needs_input",
17
+ "test"
18
+ ]
19
+ },
20
+ "status": {
21
+ "enum": [
22
+ "ok",
23
+ "denied",
24
+ "failed",
25
+ "interrupted",
26
+ "timeout",
27
+ "permission",
28
+ "question",
29
+ "test"
30
+ ]
31
+ },
32
+ "task_id": {
33
+ "type": [
34
+ "string",
35
+ "null"
36
+ ]
37
+ },
38
+ "task_label": {
39
+ "type": [
40
+ "string",
41
+ "null"
42
+ ]
43
+ },
44
+ "target": {
45
+ "type": "string"
46
+ },
47
+ "tool": {
48
+ "enum": [
49
+ "opencode",
50
+ "claude",
51
+ "codex",
52
+ null
53
+ ]
54
+ },
55
+ "model": {
56
+ "type": [
57
+ "string",
58
+ "null"
59
+ ]
60
+ },
61
+ "model_source": {
62
+ "enum": [
63
+ "user",
64
+ "tier",
65
+ "default",
66
+ null
67
+ ]
68
+ },
69
+ "tier": {
70
+ "enum": [
71
+ "trivial",
72
+ "standard",
73
+ "complex",
74
+ null
75
+ ]
76
+ },
77
+ "session_id": {
78
+ "type": [
79
+ "string",
80
+ "null"
81
+ ]
82
+ },
83
+ "cwd": {
84
+ "type": "string"
85
+ },
86
+ "repo": {
87
+ "oneOf": [
88
+ {
89
+ "type": "null"
90
+ },
91
+ {
92
+ "type": "object",
93
+ "properties": {
94
+ "root": {
95
+ "type": "string"
96
+ },
97
+ "branch": {
98
+ "type": [
99
+ "string",
100
+ "null"
101
+ ]
102
+ },
103
+ "head": {
104
+ "type": "string"
105
+ }
106
+ },
107
+ "required": [
108
+ "root",
109
+ "branch",
110
+ "head"
111
+ ],
112
+ "additionalProperties": false
113
+ }
114
+ ]
115
+ },
116
+ "exit_code": {
117
+ "type": [
118
+ "integer",
119
+ "null"
120
+ ]
121
+ },
122
+ "exit_reason": {
123
+ "enum": [
124
+ "success",
125
+ "permission_denied",
126
+ "agent_error",
127
+ "nonzero_exit",
128
+ "timeout",
129
+ "interrupted",
130
+ "needs_input",
131
+ null
132
+ ]
133
+ },
134
+ "summary": {
135
+ "type": "string"
136
+ },
137
+ "needs_input": {
138
+ "oneOf": [
139
+ {
140
+ "type": "null"
141
+ },
142
+ {
143
+ "type": "object",
144
+ "properties": {
145
+ "kind": {
146
+ "type": "string"
147
+ },
148
+ "tool_name": {
149
+ "type": [
150
+ "string",
151
+ "null"
152
+ ]
153
+ },
154
+ "detail": {
155
+ "type": [
156
+ "string",
157
+ "null"
158
+ ]
159
+ }
160
+ },
161
+ "required": [
162
+ "kind",
163
+ "tool_name",
164
+ "detail"
165
+ ],
166
+ "additionalProperties": false
167
+ }
168
+ ]
169
+ },
170
+ "resume_hint": {
171
+ "type": [
172
+ "string",
173
+ "null"
174
+ ]
175
+ },
176
+ "output_file": {
177
+ "type": [
178
+ "string",
179
+ "null"
180
+ ]
181
+ },
182
+ "transcript_path": {
183
+ "type": [
184
+ "string",
185
+ "null"
186
+ ]
187
+ },
188
+ "log_file": {
189
+ "type": [
190
+ "string",
191
+ "null"
192
+ ]
193
+ },
194
+ "started_at": {
195
+ "type": [
196
+ "string",
197
+ "null"
198
+ ],
199
+ "format": "date-time"
200
+ },
201
+ "timestamp": {
202
+ "type": "string",
203
+ "format": "date-time"
204
+ }
205
+ },
206
+ "required": [
207
+ "schema",
208
+ "event",
209
+ "status",
210
+ "task_id",
211
+ "task_label",
212
+ "target",
213
+ "tool",
214
+ "model",
215
+ "model_source",
216
+ "tier",
217
+ "session_id",
218
+ "cwd",
219
+ "repo",
220
+ "exit_code",
221
+ "exit_reason",
222
+ "summary",
223
+ "needs_input",
224
+ "resume_hint",
225
+ "output_file",
226
+ "transcript_path",
227
+ "log_file",
228
+ "started_at",
229
+ "timestamp"
230
+ ],
231
+ "additionalProperties": false,
232
+ "if": {
233
+ "properties": {
234
+ "event": {
235
+ "const": "test"
236
+ }
237
+ }
238
+ },
239
+ "then": {
240
+ "properties": {
241
+ "task_id": {
242
+ "type": "null"
243
+ },
244
+ "task_label": {
245
+ "type": "null"
246
+ },
247
+ "tool": {
248
+ "type": "null"
249
+ },
250
+ "model": {
251
+ "type": "null"
252
+ },
253
+ "model_source": {
254
+ "type": "null"
255
+ },
256
+ "output_file": {
257
+ "type": "null"
258
+ },
259
+ "log_file": {
260
+ "type": "null"
261
+ },
262
+ "started_at": {
263
+ "type": "null"
264
+ }
265
+ }
266
+ },
267
+ "else": {
268
+ "properties": {
269
+ "task_id": {
270
+ "not": {
271
+ "type": "null"
272
+ }
273
+ },
274
+ "task_label": {
275
+ "not": {
276
+ "type": "null"
277
+ }
278
+ },
279
+ "tool": {
280
+ "not": {
281
+ "type": "null"
282
+ }
283
+ },
284
+ "model": {
285
+ "not": {
286
+ "type": "null"
287
+ }
288
+ },
289
+ "model_source": {
290
+ "not": {
291
+ "type": "null"
292
+ }
293
+ },
294
+ "output_file": {
295
+ "not": {
296
+ "type": "null"
297
+ }
298
+ },
299
+ "log_file": {
300
+ "not": {
301
+ "type": "null"
302
+ }
303
+ },
304
+ "started_at": {
305
+ "not": {
306
+ "type": "null"
307
+ }
308
+ }
309
+ }
310
+ }
311
+ }
@@ -0,0 +1,7 @@
1
+ // Plugin do opencode instalado por `grokbot-kit install opencode`.
2
+ // Fora de uma task (sem GROKBOT_KIT_TASK_ID no ambiente) não faz nada e não chama o grokbot-kit.
3
+ // O repasse de `permission.asked` e `question.asked` para `grokbot-kit emit --from opencode` chega no S3.
4
+ export const GrokbotKit = async () => {
5
+ if (!process.env.GROKBOT_KIT_TASK_ID) return {}
6
+ return {}
7
+ }
@@ -0,0 +1,25 @@
1
+ """Ponto de entrada do executável `grokbot-kit`."""
2
+
3
+ import argparse
4
+
5
+ from grokbot_kit import __version__
6
+
7
+
8
+ def build_parser() -> argparse.ArgumentParser:
9
+ parser = argparse.ArgumentParser(
10
+ prog="grokbot-kit",
11
+ description="Delegate tasks to headless coding agents and wake the right Grok Bot routine.",
12
+ )
13
+ parser.add_argument("--version", action="version", version=f"grokbot-kit {__version__}")
14
+ return parser
15
+
16
+
17
+ def main(argv: list[str] | None = None) -> int:
18
+ parser = build_parser()
19
+ parser.parse_args(argv)
20
+ parser.print_help()
21
+ return 0
22
+
23
+
24
+ if __name__ == "__main__":
25
+ raise SystemExit(main())
@@ -0,0 +1,18 @@
1
+ """`grokbot-kit emit`: chamado pelos hooks dos agentes dentro de uma task.
2
+
3
+ Antes do gate de `GROKBOT_KIT_TASK_ID` só entram `os`, `sys` e `json` (door 6); o resto é
4
+ carregado sob demanda. O registro e o envio de `needs_input` chegam no S3.
5
+ """
6
+
7
+ import os
8
+ import sys
9
+
10
+
11
+ def main() -> int:
12
+ if not os.environ.get("GROKBOT_KIT_TASK_ID"):
13
+ return 0
14
+ return 0
15
+
16
+
17
+ if __name__ == "__main__":
18
+ sys.exit(main())