@buehnenproduktionsgesellschaft/donna 0.1.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.
- package/LICENSE +73 -0
- package/README.md +253 -0
- package/dist/agents/builtin/research/AGENT.md +53 -0
- package/dist/agents/builtin/review/AGENT.md +58 -0
- package/dist/agents/global.d.ts +19 -0
- package/dist/agents/global.js +54 -0
- package/dist/agents/loader.d.ts +9 -0
- package/dist/agents/loader.js +75 -0
- package/dist/agents/manager.d.ts +52 -0
- package/dist/agents/manager.js +221 -0
- package/dist/agents/pool.d.ts +29 -0
- package/dist/agents/pool.js +159 -0
- package/dist/agents/runner.d.ts +8 -0
- package/dist/agents/runner.js +239 -0
- package/dist/agents/types.d.ts +67 -0
- package/dist/agents/types.js +19 -0
- package/dist/api/account.d.ts +2 -0
- package/dist/api/account.js +32 -0
- package/dist/api/client.d.ts +46 -0
- package/dist/api/client.js +241 -0
- package/dist/api/redact.d.ts +11 -0
- package/dist/api/redact.js +47 -0
- package/dist/api/tools.d.ts +838 -0
- package/dist/api/tools.js +323 -0
- package/dist/api/types.d.ts +56 -0
- package/dist/api/types.js +1 -0
- package/dist/api/usage.d.ts +6 -0
- package/dist/api/usage.js +68 -0
- package/dist/app-raw.d.ts +6 -0
- package/dist/app-raw.js +1607 -0
- package/dist/artifacts.d.ts +16 -0
- package/dist/artifacts.js +70 -0
- package/dist/ask.d.ts +26 -0
- package/dist/ask.js +57 -0
- package/dist/auth.d.ts +17 -0
- package/dist/auth.js +37 -0
- package/dist/banner.d.ts +1 -0
- package/dist/banner.js +130 -0
- package/dist/checker.d.ts +44 -0
- package/dist/checker.js +583 -0
- package/dist/cli/args.d.ts +34 -0
- package/dist/cli/args.js +120 -0
- package/dist/cli/login.d.ts +3 -0
- package/dist/cli/login.js +51 -0
- package/dist/cli/logout.d.ts +3 -0
- package/dist/cli/logout.js +27 -0
- package/dist/cli/prompt.d.ts +15 -0
- package/dist/cli/prompt.js +47 -0
- package/dist/cli/subcommands.d.ts +7 -0
- package/dist/cli/subcommands.js +55 -0
- package/dist/commands.d.ts +20 -0
- package/dist/commands.js +115 -0
- package/dist/compaction.d.ts +8 -0
- package/dist/compaction.js +512 -0
- package/dist/config/memory.d.ts +25 -0
- package/dist/config/memory.js +131 -0
- package/dist/config/permissions.d.ts +14 -0
- package/dist/config/permissions.js +164 -0
- package/dist/config/schema.d.ts +29 -0
- package/dist/config/schema.js +15 -0
- package/dist/config/secure-fs.d.ts +27 -0
- package/dist/config/secure-fs.js +94 -0
- package/dist/config/store.d.ts +33 -0
- package/dist/config/store.js +187 -0
- package/dist/context.d.ts +6 -0
- package/dist/context.js +59 -0
- package/dist/conversation.d.ts +23 -0
- package/dist/conversation.js +338 -0
- package/dist/file-complete.d.ts +9 -0
- package/dist/file-complete.js +41 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1289 -0
- package/dist/init.d.ts +5 -0
- package/dist/init.js +145 -0
- package/dist/markdown.d.ts +23 -0
- package/dist/markdown.js +315 -0
- package/dist/mcp/client.d.ts +26 -0
- package/dist/mcp/client.js +206 -0
- package/dist/mcp/config.d.ts +2 -0
- package/dist/mcp/config.js +90 -0
- package/dist/mcp/manager.d.ts +57 -0
- package/dist/mcp/manager.js +176 -0
- package/dist/mcp/protocol.d.ts +23 -0
- package/dist/mcp/protocol.js +51 -0
- package/dist/mcp/state.d.ts +3 -0
- package/dist/mcp/state.js +32 -0
- package/dist/mcp/types.d.ts +66 -0
- package/dist/mcp/types.js +2 -0
- package/dist/pkg-info.d.ts +4 -0
- package/dist/pkg-info.js +23 -0
- package/dist/promotion.d.ts +2 -0
- package/dist/promotion.js +34 -0
- package/dist/shell-inline.d.ts +9 -0
- package/dist/shell-inline.js +63 -0
- package/dist/skills/builtin/api-design/SKILL.md +70 -0
- package/dist/skills/builtin/code-review/SKILL.md +65 -0
- package/dist/skills/builtin/database/SKILL.md +69 -0
- package/dist/skills/builtin/debugging/SKILL.md +53 -0
- package/dist/skills/builtin/deployment-safety/SKILL.md +57 -0
- package/dist/skills/builtin/documentation/SKILL.md +79 -0
- package/dist/skills/builtin/error-handling/SKILL.md +76 -0
- package/dist/skills/builtin/git-workflow/SKILL.md +65 -0
- package/dist/skills/builtin/performance/SKILL.md +57 -0
- package/dist/skills/builtin/planning/SKILL.md +58 -0
- package/dist/skills/builtin/refactoring/SKILL.md +55 -0
- package/dist/skills/builtin/security-review/SKILL.md +62 -0
- package/dist/skills/builtin/testing/SKILL.md +41 -0
- package/dist/skills/frontmatter.d.ts +10 -0
- package/dist/skills/frontmatter.js +37 -0
- package/dist/skills/loader.d.ts +2 -0
- package/dist/skills/loader.js +104 -0
- package/dist/skills/manager.d.ts +34 -0
- package/dist/skills/manager.js +107 -0
- package/dist/skills/state.d.ts +3 -0
- package/dist/skills/state.js +34 -0
- package/dist/skills/types.d.ts +30 -0
- package/dist/skills/types.js +2 -0
- package/dist/slash-commands.d.ts +34 -0
- package/dist/slash-commands.js +350 -0
- package/dist/snapshot.d.ts +21 -0
- package/dist/snapshot.js +144 -0
- package/dist/state.d.ts +153 -0
- package/dist/state.js +102 -0
- package/dist/theme.d.ts +10 -0
- package/dist/theme.js +10 -0
- package/dist/tools/bash.d.ts +1 -0
- package/dist/tools/bash.js +22 -0
- package/dist/tools/edit.d.ts +6 -0
- package/dist/tools/edit.js +69 -0
- package/dist/tools/file-state.d.ts +10 -0
- package/dist/tools/file-state.js +49 -0
- package/dist/tools/glob.d.ts +1 -0
- package/dist/tools/glob.js +98 -0
- package/dist/tools/grep.d.ts +1 -0
- package/dist/tools/grep.js +100 -0
- package/dist/tools/memory.d.ts +44 -0
- package/dist/tools/memory.js +56 -0
- package/dist/tools/path-policy.d.ts +37 -0
- package/dist/tools/path-policy.js +152 -0
- package/dist/tools/read.d.ts +1 -0
- package/dist/tools/read.js +63 -0
- package/dist/tools/runner.d.ts +46 -0
- package/dist/tools/runner.js +395 -0
- package/dist/tools/search.d.ts +9 -0
- package/dist/tools/search.js +61 -0
- package/dist/tools/todo.d.ts +44 -0
- package/dist/tools/todo.js +221 -0
- package/dist/tools/write.d.ts +6 -0
- package/dist/tools/write.js +48 -0
- package/dist/update-check.d.ts +6 -0
- package/dist/update-check.js +18 -0
- package/dist/utils.d.ts +8 -0
- package/dist/utils.js +25 -0
- package/package.json +69 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
DONNA Code — Proprietary Software License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 dbpg deutsche Bühnenproduktionsgesellschaft mbH & Co. KG.
|
|
4
|
+
All rights reserved.
|
|
5
|
+
|
|
6
|
+
1. Grant of Use
|
|
7
|
+
|
|
8
|
+
Subject to the terms of this License and to a valid, paid subscription or
|
|
9
|
+
account with dbpg where required, dbpg grants you a personal, non-exclusive,
|
|
10
|
+
non-transferable, revocable license to install and use the DONNA Code
|
|
11
|
+
software (the "Software") solely for the purpose of interacting with dbpg
|
|
12
|
+
services through the Software's intended interfaces.
|
|
13
|
+
|
|
14
|
+
2. Restrictions
|
|
15
|
+
|
|
16
|
+
You may NOT, without prior written permission from dbpg:
|
|
17
|
+
|
|
18
|
+
(a) copy, modify, fork, redistribute, sublicense, sell, rent, lease, or
|
|
19
|
+
lend the Software or any portion thereof;
|
|
20
|
+
(b) reverse engineer, decompile, disassemble, or otherwise attempt to
|
|
21
|
+
derive the source code of the Software except to the extent such
|
|
22
|
+
activity is expressly permitted by applicable law;
|
|
23
|
+
(c) remove, alter, or obscure any proprietary notices in the Software;
|
|
24
|
+
(d) use the Software to build a competing product or service;
|
|
25
|
+
(e) circumvent any technical measures designed to control access to or
|
|
26
|
+
use of the Software or dbpg services;
|
|
27
|
+
(f) use the Software in any manner that violates applicable law.
|
|
28
|
+
|
|
29
|
+
3. Ownership
|
|
30
|
+
|
|
31
|
+
The Software is licensed, not sold. dbpg retains all right, title, and
|
|
32
|
+
interest in and to the Software, including all intellectual property rights.
|
|
33
|
+
No rights are granted to you other than those expressly stated in this
|
|
34
|
+
License.
|
|
35
|
+
|
|
36
|
+
4. Third-Party Components
|
|
37
|
+
|
|
38
|
+
The Software incorporates third-party open-source components governed by
|
|
39
|
+
their respective licenses. Such components remain subject to their original
|
|
40
|
+
license terms; nothing in this License modifies those terms.
|
|
41
|
+
|
|
42
|
+
5. No Warranty
|
|
43
|
+
|
|
44
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
45
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
46
|
+
FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. dbpg DOES NOT WARRANT THAT
|
|
47
|
+
THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE.
|
|
48
|
+
|
|
49
|
+
6. Limitation of Liability
|
|
50
|
+
|
|
51
|
+
TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL dbpg
|
|
52
|
+
BE LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL, OR PUNITIVE
|
|
53
|
+
DAMAGES, OR ANY LOSS OF PROFITS OR REVENUE, ARISING OUT OF OR RELATED TO
|
|
54
|
+
YOUR USE OF OR INABILITY TO USE THE SOFTWARE.
|
|
55
|
+
|
|
56
|
+
7. Termination
|
|
57
|
+
|
|
58
|
+
This License terminates automatically if you fail to comply with any of its
|
|
59
|
+
terms. Upon termination, you must cease all use of the Software and remove
|
|
60
|
+
all copies from your systems.
|
|
61
|
+
|
|
62
|
+
8. Governing Law
|
|
63
|
+
|
|
64
|
+
This License is governed by the laws of the Federal Republic of Germany,
|
|
65
|
+
without regard to its conflict-of-law principles. Exclusive jurisdiction
|
|
66
|
+
and venue lie with the competent courts at the registered seat of dbpg.
|
|
67
|
+
|
|
68
|
+
9. Contact
|
|
69
|
+
|
|
70
|
+
For licensing inquiries, please contact:
|
|
71
|
+
support@buehnenproduktionsgesellschaft.de
|
|
72
|
+
|
|
73
|
+
dbpg deutsche Bühnenproduktionsgesellschaft mbH & Co. KG
|
package/README.md
ADDED
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
# DONNA Code
|
|
2
|
+
|
|
3
|
+
A terminal-based AI coding assistant by [dbpg](https://dbpg.io).
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g @buehnenproduktionsgesellschaft/donna
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## First-time setup
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
donna login # paste your API key (validated against the gateway)
|
|
15
|
+
donna login --browser # also opens the portal page in your browser
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Generate keys at https://centra.dbpg.io/dashboard.
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# Start a new session
|
|
24
|
+
donna
|
|
25
|
+
|
|
26
|
+
# Start with a prompt
|
|
27
|
+
donna "fix the bug in auth.ts"
|
|
28
|
+
donna fix the bug # quotes optional
|
|
29
|
+
|
|
30
|
+
# Multi-line prompt from heredoc / pipe
|
|
31
|
+
donna -p - <<'EOF'
|
|
32
|
+
write a function that
|
|
33
|
+
sums two numbers
|
|
34
|
+
EOF
|
|
35
|
+
echo "long prompt..." | donna -p -
|
|
36
|
+
|
|
37
|
+
# Resume last session
|
|
38
|
+
donna resume
|
|
39
|
+
|
|
40
|
+
# Resume specific session
|
|
41
|
+
donna resume abc123
|
|
42
|
+
|
|
43
|
+
# Logout (remove API key from disk)
|
|
44
|
+
donna logout
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Subcommands
|
|
48
|
+
|
|
49
|
+
`login`, `logout`, and `resume` are reserved subcommand names. To use them as
|
|
50
|
+
prompt text, pass them via `-p`:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
donna -p login # chat prompt: "login"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Commands
|
|
57
|
+
|
|
58
|
+
Type `/` in the TUI to see and filter all commands. `/help` lists them in-app.
|
|
59
|
+
|
|
60
|
+
**Session & navigation**
|
|
61
|
+
|
|
62
|
+
| Command | Description |
|
|
63
|
+
|---------|-------------|
|
|
64
|
+
| `/help` | Show all commands and shortcuts |
|
|
65
|
+
| `/clear` | Clear the chat |
|
|
66
|
+
| `/resume [id]` | Resume the last (or a specific) session |
|
|
67
|
+
| `/history` | Show past sessions |
|
|
68
|
+
| `/exit` | Exit donna |
|
|
69
|
+
|
|
70
|
+
**Conversation context**
|
|
71
|
+
|
|
72
|
+
| Command | Description |
|
|
73
|
+
|---------|-------------|
|
|
74
|
+
| `/context` | Show context window usage and breakdown |
|
|
75
|
+
| `/compact` | Compact the conversation into a summary |
|
|
76
|
+
| `/inspect` | Browse past tool calls and compactions |
|
|
77
|
+
|
|
78
|
+
**Workflows**
|
|
79
|
+
|
|
80
|
+
| Command | Description |
|
|
81
|
+
|---------|-------------|
|
|
82
|
+
| `/init` | Analyze the project and create `DONNA.md` |
|
|
83
|
+
| `/plan <goal>` | Create an implementation plan |
|
|
84
|
+
| `/explain <file>` | Explain a file or concept |
|
|
85
|
+
| `/review` | Review recent code changes |
|
|
86
|
+
| `/security` | Full security audit of the project |
|
|
87
|
+
| `/test [filter]` | Run tests and analyze failures |
|
|
88
|
+
| `/diff` | Show the current git diff |
|
|
89
|
+
| `/commit` | Generate a commit message and commit |
|
|
90
|
+
| `/undo` | Undo the last file edit |
|
|
91
|
+
| `/image <path>` | Analyze an image file |
|
|
92
|
+
|
|
93
|
+
**Memory**
|
|
94
|
+
|
|
95
|
+
| Command | Description |
|
|
96
|
+
|---------|-------------|
|
|
97
|
+
| `/memory` | Show or manage project memory |
|
|
98
|
+
| `/clear-memory` | Clear all project memory |
|
|
99
|
+
|
|
100
|
+
**Integrations**
|
|
101
|
+
|
|
102
|
+
| Command | Description |
|
|
103
|
+
|---------|-------------|
|
|
104
|
+
| `/agents` | Show agent status and queue |
|
|
105
|
+
| `/skills` | Enable / disable skills (Space toggles) |
|
|
106
|
+
| `/mcp` | Enable / disable MCP servers (Space toggles); `/mcp restart <name>` |
|
|
107
|
+
|
|
108
|
+
**Settings**
|
|
109
|
+
|
|
110
|
+
| Command | Description |
|
|
111
|
+
|---------|-------------|
|
|
112
|
+
| `/model` | Show the current model |
|
|
113
|
+
| `/thinking` | Set reasoning depth (none / low / medium / high) |
|
|
114
|
+
| `/config` | Show configuration |
|
|
115
|
+
|
|
116
|
+
**Account & permissions**
|
|
117
|
+
|
|
118
|
+
| Command | Description |
|
|
119
|
+
|---------|-------------|
|
|
120
|
+
| `/account` | Show account and credits |
|
|
121
|
+
| `/usage` | Show today's token usage |
|
|
122
|
+
| `/login` | Show login status / how to re-authenticate |
|
|
123
|
+
| `/logout` | Remove the API key from disk |
|
|
124
|
+
| `/permissions` | Show saved permissions |
|
|
125
|
+
| `/reset-permissions` | Reset all saved permissions |
|
|
126
|
+
|
|
127
|
+
## Keyboard Shortcuts
|
|
128
|
+
|
|
129
|
+
| Key | Action |
|
|
130
|
+
|-----|--------|
|
|
131
|
+
| `Ctrl+O` | Expand/collapse tool outputs |
|
|
132
|
+
| `Esc Esc` | Jump to previous message (revert) |
|
|
133
|
+
| `Escape` | Clear input / cancel streaming / close modal |
|
|
134
|
+
| `Alt+Enter` | Newline in input (also in `ask_user` note / `request_input`). On terminals that send a distinct Shift+Enter, that works too |
|
|
135
|
+
| `Tab` | Accept suggestion / file path completion |
|
|
136
|
+
| `Ctrl+C` | Quit |
|
|
137
|
+
|
|
138
|
+
## Shortcuts
|
|
139
|
+
|
|
140
|
+
| Prefix | Action |
|
|
141
|
+
|--------|--------|
|
|
142
|
+
| `!<cmd>` | Run `<cmd>` in your shell. Output is shown to you only — the model never sees it. Useful for quick lookups (`!ls`, `!git status`) without spending a model turn |
|
|
143
|
+
|
|
144
|
+
## Tools
|
|
145
|
+
|
|
146
|
+
DONNA Code has built-in tools that the AI uses automatically:
|
|
147
|
+
|
|
148
|
+
- **read_file** — Read files with optional offset/limit
|
|
149
|
+
- **edit_file** — Diff-based file editing (targeted string replacement)
|
|
150
|
+
- **write_file** — Create new files
|
|
151
|
+
- **glob** — Find files by pattern
|
|
152
|
+
- **grep** — Search file contents by regex
|
|
153
|
+
- **run_bash** — Execute shell commands
|
|
154
|
+
- **web_search** — Search the web
|
|
155
|
+
- **web_fetch** — Fetch full content from URLs
|
|
156
|
+
- **todo_read / todo_write** — Mini-issue task list. Each task has a title, optional description (multi-line, survives compaction), optional priority (low/normal/high/urgent), optional size (XS/S/M/L/XL). `todo_read <id>` returns full detail so the assistant can pick a task up again after a context compaction
|
|
157
|
+
- **ask_user** — Open a structured multi-choice modal for the user to answer
|
|
158
|
+
- **request_input** — Prompt the user for free-text input (with optional masking for secrets)
|
|
159
|
+
- **run_agent** — Delegate a focused sub-task to a sub-agent that runs in parallel
|
|
160
|
+
|
|
161
|
+
## Project Context
|
|
162
|
+
|
|
163
|
+
Create a `DONNA.md` in your project root (or run `/init`) to give the AI context about your project. This file is automatically loaded at the start of each session.
|
|
164
|
+
|
|
165
|
+
Plans in `.plans/*.md` are also loaded automatically.
|
|
166
|
+
|
|
167
|
+
## MCP Servers (optional)
|
|
168
|
+
|
|
169
|
+
[MCP](https://modelcontextprotocol.io) lets you give DONNA extra tools beyond the
|
|
170
|
+
built-ins — GitHub, Linear, databases, custom internal services. Note: for
|
|
171
|
+
plain file access in the current project, the **built-in tools above are
|
|
172
|
+
already enough**. MCP is for paths outside cwd or non-file integrations.
|
|
173
|
+
|
|
174
|
+
Configure servers in either:
|
|
175
|
+
- `~/.config/donna/mcp.json` (global, trusted automatically)
|
|
176
|
+
- `.donna/mcp.json` (per-project, **requires explicit trust on first use**)
|
|
177
|
+
|
|
178
|
+
```json
|
|
179
|
+
{
|
|
180
|
+
"mcpServers": {
|
|
181
|
+
"github": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-github"] }
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Workspace trust
|
|
187
|
+
|
|
188
|
+
When DONNA finds a `.donna/mcp.json` in your current directory it has not
|
|
189
|
+
seen before, you'll be prompted before any subprocess is started:
|
|
190
|
+
|
|
191
|
+
```
|
|
192
|
+
.donna/mcp.json declares the following MCP servers:
|
|
193
|
+
- github
|
|
194
|
+
These run as subprocesses with full filesystem access.
|
|
195
|
+
Trust this configuration? [y/N]
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Answer `y` once and DONNA records the file's content hash in
|
|
199
|
+
`~/.donna/config.json`. Subsequent runs are silent until the file changes.
|
|
200
|
+
This protects you from a hostile cloned repository auto-running a
|
|
201
|
+
subprocess on the first `donna` you type in that directory — the same
|
|
202
|
+
threat model as VS Code's workspace trust.
|
|
203
|
+
|
|
204
|
+
To revoke trust: edit `~/.donna/config.json` and remove the entry from
|
|
205
|
+
`mcpTrust`, or delete the file entirely.
|
|
206
|
+
|
|
207
|
+
## Configuration
|
|
208
|
+
|
|
209
|
+
Config is stored in `~/.donna/config.json`. The API key is set by
|
|
210
|
+
`donna login` — you generally don't edit this file by hand. Other fields:
|
|
211
|
+
|
|
212
|
+
```json
|
|
213
|
+
{
|
|
214
|
+
"endpoint": "https://api.centra.dbpg.io/v1",
|
|
215
|
+
"model": "donna-coda",
|
|
216
|
+
"contextLimit": 180000,
|
|
217
|
+
"autoCompactThreshold": 0.8,
|
|
218
|
+
"reasoningEffort": "high"
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
## Reporting bugs
|
|
223
|
+
|
|
224
|
+
Email: **support@buehnenproduktionsgesellschaft.de**
|
|
225
|
+
|
|
226
|
+
For security issues please use the private channel in [SECURITY.md](SECURITY.md).
|
|
227
|
+
|
|
228
|
+
When reporting, include:
|
|
229
|
+
- Output of `donna --version`
|
|
230
|
+
- `node --version`
|
|
231
|
+
- Operating system
|
|
232
|
+
|
|
233
|
+
## Platform support
|
|
234
|
+
|
|
235
|
+
Officially supported: **macOS** and **Linux**. Windows is not supported in
|
|
236
|
+
this release — `run_bash` uses `/bin/bash` and several path helpers assume
|
|
237
|
+
POSIX semantics, so `npm i -g` refuses to install on Windows (`"os"` field
|
|
238
|
+
in `package.json`). Windows support is tracked as issue #4 and planned for
|
|
239
|
+
a future release.
|
|
240
|
+
|
|
241
|
+
## Development
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
npm install
|
|
245
|
+
npm run build
|
|
246
|
+
node dist/index.js
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
A complete history of changes is in [CHANGELOG.md](CHANGELOG.md).
|
|
250
|
+
|
|
251
|
+
## License
|
|
252
|
+
|
|
253
|
+
Proprietary. Copyright (c) 2026 dbpg deutsche Bühnenproduktionsgesellschaft mbH & Co. KG. All rights reserved.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: research
|
|
3
|
+
description: Deep research agent - reads code and returns structured findings
|
|
4
|
+
allowedTools: [read_file, glob, grep, web_search, web_fetch]
|
|
5
|
+
maxTurns: 19
|
|
6
|
+
timeout: 180000
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
You are a research agent running in an isolated context. You receive ONE task,
|
|
10
|
+
investigate using `read_file` / `glob` / `grep` / `web_search` / `web_fetch`,
|
|
11
|
+
and ALWAYS return a structured report.
|
|
12
|
+
|
|
13
|
+
## Mandatory Contract
|
|
14
|
+
- Every run MUST end with a final response containing the report below.
|
|
15
|
+
- Empty content is a critical violation of the agent contract.
|
|
16
|
+
- If the task is impossible (file missing, ambiguous, blocked) you STILL respond — set `Status: failed` and explain why in `Summary`.
|
|
17
|
+
- Your final turn (the one with no tool calls) IS the report. Do not call tools in that turn.
|
|
18
|
+
|
|
19
|
+
## Workflow
|
|
20
|
+
1. Read the task carefully and extract any paths, symbols, or keywords.
|
|
21
|
+
2. Use `glob`/`grep` to locate relevant files if not given explicitly.
|
|
22
|
+
3. Use `read_file` to inspect them.
|
|
23
|
+
4. Stop investigating after 1–3 evidence-gathering turns and produce the report.
|
|
24
|
+
5. Be concise but specific — quote line numbers, function names, exact paths.
|
|
25
|
+
6. Do NOT write files or execute commands. Read-only.
|
|
26
|
+
|
|
27
|
+
## Required Output Format
|
|
28
|
+
Your final response MUST start with this exact structure:
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
## Status
|
|
32
|
+
success | partial | failed
|
|
33
|
+
|
|
34
|
+
## Summary
|
|
35
|
+
<one sentence directly answering the task>
|
|
36
|
+
|
|
37
|
+
## Findings
|
|
38
|
+
<structured detail; subsections allowed>
|
|
39
|
+
|
|
40
|
+
## Key Files
|
|
41
|
+
- `path/to/file.ts:line` — what it does, why it matters
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
`Key Files` may be empty if no files are central to the answer, but the heading must still be present.
|
|
45
|
+
|
|
46
|
+
## Output Style (strict)
|
|
47
|
+
- Start the response directly with `## Status`. No preamble ("Sure", "I'll investigate", "Let me check"), no greeting.
|
|
48
|
+
- End after the last finding. No closing pleasantries ("Let me know if...", "Hope this helps").
|
|
49
|
+
- No emojis. No decorative characters.
|
|
50
|
+
- No bold/italic for emphasis — only inside section headers if needed.
|
|
51
|
+
- No prose paragraphs where bullets work. Terse over flowing.
|
|
52
|
+
- Quote exact identifiers: file paths, line numbers, function names, error strings. Never paraphrase them.
|
|
53
|
+
- No filler ("It looks like", "It appears that"). State facts directly.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: review
|
|
3
|
+
description: Code review agent - unbiased analysis of changes
|
|
4
|
+
allowedTools: [read_file, grep]
|
|
5
|
+
maxTurns: 19
|
|
6
|
+
timeout: 180000
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
You are a code review agent running in an isolated context with no knowledge of
|
|
10
|
+
the surrounding conversation or the author's intent. You judge only what the
|
|
11
|
+
code does.
|
|
12
|
+
|
|
13
|
+
## Mandatory Contract
|
|
14
|
+
- Every run MUST end with a final response containing the report below.
|
|
15
|
+
- Empty content is a critical violation of the agent contract.
|
|
16
|
+
- If you cannot review (file missing, unreadable, scope unclear) you STILL respond — set `Status: failed` and explain why in `Summary`.
|
|
17
|
+
- Your final turn (no tool calls) IS the report. Do not call tools in that turn.
|
|
18
|
+
|
|
19
|
+
## Workflow
|
|
20
|
+
1. Read the task to identify what to review (file, range, concern).
|
|
21
|
+
2. Use `read_file` and `grep` to inspect the code.
|
|
22
|
+
3. Look for: bugs, security issues, performance problems, readability concerns.
|
|
23
|
+
4. After 1–3 evidence-gathering turns, produce the report.
|
|
24
|
+
5. Be direct — name files, lines, severities. No hedging.
|
|
25
|
+
|
|
26
|
+
## Severity Levels
|
|
27
|
+
- `CRITICAL` — bug, security flaw, data loss risk
|
|
28
|
+
- `WARNING` — likely bug, performance issue, smell
|
|
29
|
+
- `INFO` — style, minor improvement
|
|
30
|
+
|
|
31
|
+
## Required Output Format
|
|
32
|
+
Your final response MUST start with this exact structure:
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
## Status
|
|
36
|
+
success | partial | failed
|
|
37
|
+
|
|
38
|
+
## Summary
|
|
39
|
+
<one sentence: count by severity and overall verdict>
|
|
40
|
+
|
|
41
|
+
## Findings
|
|
42
|
+
### [SEVERITY] <Issue title>
|
|
43
|
+
- **Location**: `file.ts:line`
|
|
44
|
+
- **Problem**: <what's wrong>
|
|
45
|
+
- **Impact**: <why it matters>
|
|
46
|
+
- **Suggestion**: <how to fix, if applicable>
|
|
47
|
+
|
|
48
|
+
(repeat per finding; if none, write "No issues found.")
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Output Style (strict)
|
|
52
|
+
- Start the response directly with `## Status`. No preamble ("Sure", "I'll review", "Let me look"), no greeting.
|
|
53
|
+
- End after the last finding. No closing pleasantries ("Let me know if...", "Hope this helps").
|
|
54
|
+
- No emojis. No decorative characters.
|
|
55
|
+
- No bold/italic for emphasis — only the labels inside finding entries (Location/Problem/Impact/Suggestion) and section headers.
|
|
56
|
+
- No hedging ("might be", "could potentially"). If you flag an issue, state it as fact with severity.
|
|
57
|
+
- Quote exact identifiers: file paths, line numbers, function names. Never paraphrase them.
|
|
58
|
+
- No filler. One issue, one entry, no surrounding prose.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { AgentManager } from './manager.js';
|
|
2
|
+
import type { AppState } from '../state.js';
|
|
3
|
+
import type { Session } from '../config/store.js';
|
|
4
|
+
export declare let globalAgentManager: AgentManager | null;
|
|
5
|
+
export declare function setGlobalAgentManager(manager: AgentManager): void;
|
|
6
|
+
export declare function getGlobalAgentManager(): AgentManager | null;
|
|
7
|
+
export declare let globalAppState: AppState | null;
|
|
8
|
+
export declare function setGlobalAppState(state: AppState): void;
|
|
9
|
+
export declare function getGlobalAppState(): AppState | null;
|
|
10
|
+
/**
|
|
11
|
+
* Drain pending async agent results into the session as a synthetic user
|
|
12
|
+
* turn so the next runConversation call sees them. Returns true if anything
|
|
13
|
+
* was drained.
|
|
14
|
+
*
|
|
15
|
+
* Shared by:
|
|
16
|
+
* - processAgentQueue (idle wake-up from listener)
|
|
17
|
+
* - runConversation end-of-turn check (drained while a turn was in flight)
|
|
18
|
+
*/
|
|
19
|
+
export declare function drainAgentResults(state: AppState, session: Session): boolean;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { markUserTurnStart } from '../state.js';
|
|
2
|
+
import { saveSession } from '../config/store.js';
|
|
3
|
+
export let globalAgentManager = null;
|
|
4
|
+
export function setGlobalAgentManager(manager) {
|
|
5
|
+
globalAgentManager = manager;
|
|
6
|
+
}
|
|
7
|
+
export function getGlobalAgentManager() {
|
|
8
|
+
return globalAgentManager;
|
|
9
|
+
}
|
|
10
|
+
export let globalAppState = null;
|
|
11
|
+
export function setGlobalAppState(state) {
|
|
12
|
+
globalAppState = state;
|
|
13
|
+
}
|
|
14
|
+
export function getGlobalAppState() {
|
|
15
|
+
return globalAppState;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Drain pending async agent results into the session as a synthetic user
|
|
19
|
+
* turn so the next runConversation call sees them. Returns true if anything
|
|
20
|
+
* was drained.
|
|
21
|
+
*
|
|
22
|
+
* Shared by:
|
|
23
|
+
* - processAgentQueue (idle wake-up from listener)
|
|
24
|
+
* - runConversation end-of-turn check (drained while a turn was in flight)
|
|
25
|
+
*/
|
|
26
|
+
export function drainAgentResults(state, session) {
|
|
27
|
+
if (state.agentResultQueue.length === 0)
|
|
28
|
+
return false;
|
|
29
|
+
const results = [...state.agentResultQueue];
|
|
30
|
+
state.agentResultQueue = [];
|
|
31
|
+
const combinedContent = results
|
|
32
|
+
.map((r) => {
|
|
33
|
+
const tokens = `${(r.tokenUsage.prompt / 1000).toFixed(1)}k prompt, ${(r.tokenUsage.completion / 1000).toFixed(1)}k completion`;
|
|
34
|
+
return `## Result from **${r.agent}** agent (${r.turnsUsed} turns, ${tokens}, ${(r.elapsedMs / 1000).toFixed(1)}s)\n${r.task}\n\n${r.response}`;
|
|
35
|
+
})
|
|
36
|
+
.join('\n\n---\n\n');
|
|
37
|
+
state.items.push({
|
|
38
|
+
type: 'message',
|
|
39
|
+
role: 'assistant',
|
|
40
|
+
content: combinedContent,
|
|
41
|
+
});
|
|
42
|
+
// Treat the drained agent results as a real turn boundary: freeze prior
|
|
43
|
+
// display items and capture a git snapshot before the synthetic user
|
|
44
|
+
// message, so point-in-time revert works for agent-result-driven turns
|
|
45
|
+
// (consistent with queued prompts in conversation.ts).
|
|
46
|
+
markUserTurnStart(state, session);
|
|
47
|
+
const agentMsg = {
|
|
48
|
+
role: 'user',
|
|
49
|
+
content: `[Sub-agent results for ${results.length} task(s):\n\n${results.map((r) => `"${r.task}" (${r.agent})`).join('\n')}]\n\n${combinedContent}`,
|
|
50
|
+
};
|
|
51
|
+
session.messages.push(agentMsg);
|
|
52
|
+
saveSession(session);
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import { AGENT_BLOCKED_TOOLS } from './types.js';
|
|
5
|
+
import { parseFrontmatter } from '../skills/frontmatter.js';
|
|
6
|
+
export function loadAgents(cwd) {
|
|
7
|
+
const agents = [];
|
|
8
|
+
const errors = [];
|
|
9
|
+
const dirs = [
|
|
10
|
+
path.join(cwd, '.donna/agents'),
|
|
11
|
+
path.join(os.homedir(), '.donna/agents'),
|
|
12
|
+
path.join(cwd, 'src/agents/builtin'), // Built-in agents from source
|
|
13
|
+
];
|
|
14
|
+
for (const dir of dirs) {
|
|
15
|
+
if (!fs.existsSync(dir))
|
|
16
|
+
continue;
|
|
17
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
18
|
+
if (!entry.isDirectory())
|
|
19
|
+
continue;
|
|
20
|
+
const agentFile = path.join(dir, entry.name, 'AGENT.md');
|
|
21
|
+
if (!fs.existsSync(agentFile))
|
|
22
|
+
continue;
|
|
23
|
+
try {
|
|
24
|
+
const raw = fs.readFileSync(agentFile, 'utf-8');
|
|
25
|
+
const { frontmatter, body } = parseFrontmatter(raw);
|
|
26
|
+
// Validate frontmatter
|
|
27
|
+
const name = String(frontmatter.name || entry.name);
|
|
28
|
+
const description = String(frontmatter.description || '');
|
|
29
|
+
const maxTurns = Math.min(Number(frontmatter.maxTurns) || 10, 20); // Hard cap
|
|
30
|
+
const timeoutMs = Math.min(Number(frontmatter.timeout) || 120000, 300000); // Max 5min
|
|
31
|
+
// Sanitize allowed tools - block dangerous ones
|
|
32
|
+
// Parse allowed tools - handle both array syntax [a, b] and missing frontmatter
|
|
33
|
+
const safeToolsList = ['read_file', 'glob', 'grep', 'web_search', 'web_fetch', 'list_skills'];
|
|
34
|
+
const allowedToolsRaw = frontmatter.allowedTools;
|
|
35
|
+
let allowedTools;
|
|
36
|
+
if (allowedToolsRaw) {
|
|
37
|
+
// Parse YAML array format: [tool1, tool2]
|
|
38
|
+
const match = String(allowedToolsRaw).match(/^\[([^\]]*)\]$/);
|
|
39
|
+
if (match) {
|
|
40
|
+
allowedTools = match[1].split(',').map(s => s.trim().replace(/^["']|["']$/g, ''));
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
allowedTools = [allowedToolsRaw];
|
|
44
|
+
}
|
|
45
|
+
// Filter to only safe tools
|
|
46
|
+
allowedTools = allowedTools.filter((t) => !AGENT_BLOCKED_TOOLS.has(t) && safeToolsList.includes(t));
|
|
47
|
+
// If nothing valid remains, fall back to safe defaults
|
|
48
|
+
if (allowedTools.length === 0) {
|
|
49
|
+
allowedTools = [...safeToolsList];
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
// No explicit tools - use all safe defaults
|
|
54
|
+
allowedTools = [...safeToolsList];
|
|
55
|
+
}
|
|
56
|
+
agents.push({
|
|
57
|
+
name: sanitizeAgentName(name),
|
|
58
|
+
description,
|
|
59
|
+
allowedTools,
|
|
60
|
+
maxTurns,
|
|
61
|
+
timeoutMs,
|
|
62
|
+
filePath: agentFile,
|
|
63
|
+
systemPrompt: body.trim(),
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
catch (e) {
|
|
67
|
+
errors.push({ file: agentFile, message: e.message });
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return { agents, errors };
|
|
72
|
+
}
|
|
73
|
+
function sanitizeAgentName(name) {
|
|
74
|
+
return name.toLowerCase().replace(/[^a-z0-9_-]/g, '_');
|
|
75
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { AgentSpec, AgentResult } from './types.js';
|
|
2
|
+
import { AgentPool } from './pool.js';
|
|
3
|
+
import { DonnaConfig } from '../config/schema.js';
|
|
4
|
+
export interface ToolDef {
|
|
5
|
+
type: 'function';
|
|
6
|
+
function: {
|
|
7
|
+
name: string;
|
|
8
|
+
description: string;
|
|
9
|
+
parameters: Record<string, unknown>;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export declare class AgentManager {
|
|
13
|
+
private cwd;
|
|
14
|
+
private agents;
|
|
15
|
+
private pool;
|
|
16
|
+
private config;
|
|
17
|
+
/** One AbortController per in-flight task, so abortAll() can actually
|
|
18
|
+
* cancel the running turn loop + its API call — not just the pool
|
|
19
|
+
* bookkeeping. */
|
|
20
|
+
private controllers;
|
|
21
|
+
/** Non-fatal errors collected during initial agent load. Exposed so the
|
|
22
|
+
* TUI can surface them via /agents or a status indicator instead of
|
|
23
|
+
* writing to stdout/stderr and corrupting the Ink render. */
|
|
24
|
+
readonly loadErrors: string[];
|
|
25
|
+
constructor(cwd: string, config: DonnaConfig);
|
|
26
|
+
private load;
|
|
27
|
+
getPool(): AgentPool;
|
|
28
|
+
getAgent(name: string): AgentSpec | undefined;
|
|
29
|
+
listAgents(): AgentSpec[];
|
|
30
|
+
/**
|
|
31
|
+
* Submit task and optionally wait for completion.
|
|
32
|
+
* @param options.wait - If true, blocks until completion. If false, returns immediately with task ID.
|
|
33
|
+
* @returns Task ID (async) or AgentResult (sync when wait=true)
|
|
34
|
+
*/
|
|
35
|
+
submitTask(name: string, task: string, files?: string[], options?: {
|
|
36
|
+
wait?: boolean;
|
|
37
|
+
waitTimeoutMs?: number;
|
|
38
|
+
}): Promise<string | AgentResult>;
|
|
39
|
+
private executeWhenReady;
|
|
40
|
+
/** Resolve once the task reaches a terminal-or-running state, driven by
|
|
41
|
+
* pool notifications instead of polling. Also resolves on abort. */
|
|
42
|
+
private waitForRunning;
|
|
43
|
+
/** Get tool definition for API */
|
|
44
|
+
getToolDef(): ToolDef | null;
|
|
45
|
+
/** Wait for task completion and return result (blocking).
|
|
46
|
+
* Event-driven off pool notifications — no polling. */
|
|
47
|
+
waitForResult(taskId: string, timeoutMs?: number): Promise<AgentResult>;
|
|
48
|
+
/** Abort every in-flight and queued agent — cancels the running turn loop
|
|
49
|
+
* and its API call via the per-task AbortController, then clears pool
|
|
50
|
+
* bookkeeping. Call on app exit / Ctrl+C. */
|
|
51
|
+
abortAll(): void;
|
|
52
|
+
}
|