@pingvinen/donna-assistant 0.9.1 → 0.11.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/README.md +33 -3
- package/package.json +1 -1
- package/src/donna-tools.cjs +429 -0
- package/src/installer.cjs +26 -4
- package/stubs/claude-code/donna/add-follow-up-task.md +17 -0
- package/stubs/claude-code/donna/remove-tool.md +17 -0
- package/workflows/add-task.md +15 -75
- package/workflows/add-tool.md +58 -91
- package/workflows/adjust-tool.md +22 -132
- package/workflows/begin-the-day.md +59 -92
- package/workflows/done.md +16 -74
- package/workflows/focus.md +21 -95
- package/workflows/follow-up.md +163 -0
- package/workflows/relearn-tools.md +60 -91
- package/workflows/remove-tool.md +93 -0
- package/workflows/run-tools.md +26 -99
- package/workflows/set-role.md +12 -61
|
@@ -4,82 +4,25 @@
|
|
|
4
4
|
Carry forward open tasks from the previous day, surface recurring tasks due today, deduplicate, and present a concise daily brief.
|
|
5
5
|
</objective>
|
|
6
6
|
|
|
7
|
-
<step name="
|
|
8
|
-
Read `~/.config/donna/config.md`.
|
|
9
|
-
|
|
10
|
-
If the file does not exist, print:
|
|
11
|
-
```
|
|
12
|
-
✗ Donna is not configured. Run /donna:setup first.
|
|
13
|
-
```
|
|
14
|
-
Stop.
|
|
15
|
-
|
|
16
|
-
Extract the `storage_repo`, `daily_folder` (default: `daily`), and `auto_push` (default: false) fields from the YAML frontmatter.
|
|
17
|
-
|
|
18
|
-
**Obsidian sync:** Check if `<storage_repo>/.obsidian/daily-notes.json` exists.
|
|
19
|
-
- If it exists and has a `folder` field that differs from `<daily_folder>`: update `<daily_folder>` to match Obsidian's value, and update `~/.config/donna/config.md` with the new `daily_folder`. Print `✓ Synced daily folder with Obsidian: <daily_folder>`.
|
|
20
|
-
- If `<storage_repo>/.obsidian/` exists but `daily-notes.json` does not exist or has no `folder` field: write `<storage_repo>/.obsidian/daily-notes.json` with `{"folder":"<daily_folder>"}`. Print `✓ Configured Obsidian daily notes to use <daily_folder>/`.
|
|
21
|
-
- Otherwise: do nothing.
|
|
22
|
-
</step>
|
|
23
|
-
|
|
24
|
-
<step name="check-pending-migrations">
|
|
25
|
-
Read `~/.donna/state.md` with the Read tool. If the file does not exist or has no `pending_migrations` field in its YAML frontmatter, skip this step.
|
|
26
|
-
|
|
27
|
-
For each entry in `pending_migrations`:
|
|
28
|
-
|
|
29
|
-
**`move-standing-files`:** Move standing files from storage repo root to donna/ subfolder.
|
|
30
|
-
|
|
7
|
+
<step name="init">
|
|
31
8
|
Run via Bash:
|
|
32
9
|
```bash
|
|
33
|
-
|
|
34
|
-
DONNA_DIR="$STORAGE_REPO/donna"
|
|
35
|
-
MOVED=0
|
|
36
|
-
|
|
37
|
-
mkdir -p "$DONNA_DIR"
|
|
38
|
-
for FILE in role.md recurring.md role-research.md; do
|
|
39
|
-
if [ -f "$STORAGE_REPO/$FILE" ] && [ ! -f "$DONNA_DIR/$FILE" ]; then
|
|
40
|
-
mv "$STORAGE_REPO/$FILE" "$DONNA_DIR/$FILE"
|
|
41
|
-
echo "Moved $FILE to donna/$FILE"
|
|
42
|
-
MOVED=$((MOVED + 1))
|
|
43
|
-
fi
|
|
44
|
-
done
|
|
45
|
-
|
|
46
|
-
echo "MOVED=$MOVED"
|
|
10
|
+
INIT=$(node ~/.donna/donna-tools.cjs init)
|
|
47
11
|
```
|
|
48
12
|
|
|
49
|
-
|
|
50
|
-
```bash
|
|
51
|
-
git -C <storage_repo> add -A
|
|
52
|
-
git -C <storage_repo> diff --cached --quiet || git -C <storage_repo> commit -m "donna(migrate): move standing files to donna/ subfolder"
|
|
13
|
+
Parse the JSON response. If the `error` field is `"not_configured"`, print:
|
|
53
14
|
```
|
|
54
|
-
|
|
55
|
-
If `auto_push` is true in config, also push.
|
|
56
|
-
|
|
57
|
-
**`backfill-tool-type`:** Backfill `type` on existing tool sections in tools.md using heuristic detection.
|
|
58
|
-
|
|
59
|
-
Read `<storage_repo>/donna/tools.md` with the Read tool. If the file does not exist or has no tool sections, skip this handler.
|
|
60
|
-
|
|
61
|
-
For each tool section (starting with `## <tool_name>`), check if a `- type:` line already exists. If the `- type:` line is missing, detect the correct type:
|
|
62
|
-
|
|
63
|
-
1. If the tool section contains a `- command:` line where the value starts with `mcp:` (e.g., `- command: mcp:linear`), insert `- type: mcp` immediately after the `- command:` line.
|
|
64
|
-
2. Else, if the tool section contains a `- base_url:` line:
|
|
65
|
-
- If the capabilities section contains entries that look like GraphQL queries (contain `query {` or `mutation {`), insert `- type: graphql` immediately after `## <tool_name>` (REST/GraphQL tools have no `- command:` line).
|
|
66
|
-
- Otherwise, insert `- type: rest` immediately after `## <tool_name>`.
|
|
67
|
-
3. Else (no `mcp:` prefix, no `base_url` field), insert `- type: cli` immediately after the `- command:` line.
|
|
68
|
-
|
|
69
|
-
Write the updated file back with the Write tool. If any changes were made, commit:
|
|
70
|
-
```bash
|
|
71
|
-
git -C <storage_repo> add -A
|
|
72
|
-
git -C <storage_repo> diff --cached --quiet || git -C <storage_repo> commit -m "donna(migrate): backfill tool types on existing tools"
|
|
15
|
+
x Donna is not configured. Run /donna:setup first.
|
|
73
16
|
```
|
|
17
|
+
Stop.
|
|
74
18
|
|
|
75
|
-
|
|
19
|
+
Extract `storage_repo`, `daily_folder`, `auto_push` from the JSON.
|
|
76
20
|
|
|
77
|
-
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
pending_migrations: []
|
|
81
|
-
---
|
|
21
|
+
If `update_available` is non-null, print:
|
|
22
|
+
```
|
|
23
|
+
Donna v<update_available> available -- run npx @pingvinen/donna-assistant to update
|
|
82
24
|
```
|
|
25
|
+
Continue normally.
|
|
83
26
|
</step>
|
|
84
27
|
|
|
85
28
|
<step name="get-today">
|
|
@@ -99,7 +42,11 @@ date +%-d
|
|
|
99
42
|
```
|
|
100
43
|
Store the result as `<day_of_month>` (e.g., "1" for the 1st).
|
|
101
44
|
|
|
102
|
-
|
|
45
|
+
Get the daily file path via donna-tools:
|
|
46
|
+
```bash
|
|
47
|
+
DAILY_PATH=$(node ~/.donna/donna-tools.cjs daily-path | node -e "process.stdin.resume();let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>console.log(JSON.parse(d).path))")
|
|
48
|
+
```
|
|
49
|
+
Store the result as `<daily_file_path>`.
|
|
103
50
|
</step>
|
|
104
51
|
|
|
105
52
|
<step name="find-previous-file">
|
|
@@ -147,6 +94,26 @@ For each task, determine if it is due today using this logic:
|
|
|
147
94
|
Store the descriptions of all due tasks as `<recurring_tasks>` (just the description text, without the interval suffix).
|
|
148
95
|
</step>
|
|
149
96
|
|
|
97
|
+
<step name="check-follow-ups">
|
|
98
|
+
Read `<storage_repo>/donna/follow-ups.md` with the Read tool. If the file does not exist, set `<follow_up_tasks>` to an empty list, set `<follow_ups_modified>` to `false`, and continue (follow-ups are optional).
|
|
99
|
+
|
|
100
|
+
Parse each line matching the pattern `- [ ] <description> | due: YYYY-MM-DD`. For each matching entry:
|
|
101
|
+
|
|
102
|
+
- Parse the `due` date (YYYY-MM-DD).
|
|
103
|
+
- If `due <= <today>`: add to `<follow_up_tasks>` as: `- [ ] <description>` (no annotation).
|
|
104
|
+
- If `due > <today>`: task is future — leave the line in follow-ups.md. Do not add to `<follow_up_tasks>`.
|
|
105
|
+
|
|
106
|
+
After collecting all due/past-due tasks, remove those matched lines from follow-ups.md (the matched lines are NOT written back — only future lines remain). Write the updated file back with the Write tool. If lines were removed, set `<follow_ups_modified>` to `true`. If no lines were removed, set `<follow_ups_modified>` to `false` and skip the file write. Per D-03: items are removed, not checked off or left with a marker.
|
|
107
|
+
|
|
108
|
+
Store `<follow_up_tasks>` for use in the deduplicate step.
|
|
109
|
+
|
|
110
|
+
CRITICAL constraints:
|
|
111
|
+
- The step reads only one specific named file (`donna/follow-ups.md`) — no directory scan, no wildcard listing
|
|
112
|
+
- File existence check is done via the Read tool (handle missing file gracefully)
|
|
113
|
+
- macOS date command uses the exact same `date -j` pattern as the existing check-recurring step
|
|
114
|
+
- Invalid date strings caught by `date -j`; skip the entry (do not surface, do not remove)
|
|
115
|
+
</step>
|
|
116
|
+
|
|
150
117
|
<step name="pull-tool-data">
|
|
151
118
|
Read `<storage_repo>/donna/tools.md` with the Read tool.
|
|
152
119
|
|
|
@@ -178,9 +145,9 @@ Store the parsed tools and their capabilities as `<registered_tools>`.
|
|
|
178
145
|
|
|
179
146
|
For `type: cli` capabilities (format: `<name>: <cli_invocation>`):
|
|
180
147
|
|
|
181
|
-
Run via Bash
|
|
148
|
+
Run via Bash (set the Bash tool's `timeout` parameter to `10000`):
|
|
182
149
|
```bash
|
|
183
|
-
|
|
150
|
+
<cli_invocation> 2>&1
|
|
184
151
|
```
|
|
185
152
|
|
|
186
153
|
**On success (exit 0):**
|
|
@@ -210,9 +177,9 @@ Add the warning to `<tool_warnings>`. Continue to next capability/tool. Never re
|
|
|
210
177
|
For `type: rest` capabilities (format: `<name>: <METHOD> /path`):
|
|
211
178
|
1. Read `<storage_repo>/donna/secrets.md` with the Read tool. Parse key-value pairs from under the frontmatter.
|
|
212
179
|
2. Resolve the `auth_secret` key to get the actual secret value. If the key is not found in secrets.md or the value is `REPLACE_WITH_YOUR_SECRET`, add warning `! <tool_name>: missing secret <auth_secret> — edit donna/secrets.md` and skip this tool.
|
|
213
|
-
3. For each capability, run via Bash
|
|
180
|
+
3. For each capability, run via Bash (set the Bash tool's `timeout` parameter to `10000`):
|
|
214
181
|
```bash
|
|
215
|
-
|
|
182
|
+
curl -s -H "<auth_header>: <resolved_secret>" "<base_url><path>" 2>&1
|
|
216
183
|
```
|
|
217
184
|
4. Parse the JSON response using Claude's understanding to extract task-like items. Format:
|
|
218
185
|
`- [ ] (<tool_name>) <description> [<identifier>](<url>)`
|
|
@@ -223,9 +190,9 @@ Continue. Never retry.
|
|
|
223
190
|
|
|
224
191
|
For `type: graphql` capabilities (format: `<name>: <graphql_query>`):
|
|
225
192
|
1. Same secrets resolution as REST.
|
|
226
|
-
2. For each capability, run via Bash
|
|
193
|
+
2. For each capability, run via Bash (set the Bash tool's `timeout` parameter to `10000`):
|
|
227
194
|
```bash
|
|
228
|
-
|
|
195
|
+
curl -s -X POST -H "<auth_header>: <resolved_secret>" -H "Content-Type: application/json" -d '{"query":"<graphql_query>"}' "<base_url>" 2>&1
|
|
229
196
|
```
|
|
230
197
|
3. Parse the JSON response to extract task-like items. Same format as REST.
|
|
231
198
|
|
|
@@ -265,7 +232,9 @@ Assemble the full task list using a single-pass deduplication to ensure idempote
|
|
|
265
232
|
|
|
266
233
|
3. Add `<recurring_tasks>` as `- [ ] <description>` — for each recurring task, normalize its description and check whether any task already in the final list normalizes to the same value. If no match, add it. If a match exists, skip it.
|
|
267
234
|
|
|
268
|
-
4. Add `<
|
|
235
|
+
4. Add `<follow_up_tasks>` as-is — for each follow-up task, normalize its description and check whether any task already in the final list normalizes to the same value. If no match, add it. If a match exists, skip it.
|
|
236
|
+
|
|
237
|
+
5. Add `<tool_tasks>` as-is — for each tool task, normalize its description and check whether any task already in the final list normalizes to the same value. If no match, add it. If a match exists, skip it.
|
|
269
238
|
|
|
270
239
|
CRITICAL: A closed task `- [x] Review PRs` must block a recurring `- [ ] Review PRs` from being re-added. Both open AND closed existing tasks count for deduplication.
|
|
271
240
|
|
|
@@ -292,6 +261,7 @@ date: <today>
|
|
|
292
261
|
<existing tasks, preserving their original order and open/closed state>
|
|
293
262
|
<carried-forward tasks not already in existing>
|
|
294
263
|
<recurring tasks not already in existing>
|
|
264
|
+
<follow-up tasks not already in existing>
|
|
295
265
|
|
|
296
266
|
## From Tools
|
|
297
267
|
<tool tasks not already in existing — only if there are tool tasks>
|
|
@@ -303,7 +273,7 @@ date: <today>
|
|
|
303
273
|
<tool warnings — only if there are warnings>
|
|
304
274
|
```
|
|
305
275
|
|
|
306
|
-
Tasks are written in this order: existing tasks first (preserving their original order and state), then carried-forward tasks, then recurring tasks.
|
|
276
|
+
Tasks are written in this order: existing tasks first (preserving their original order and state), then carried-forward tasks, then recurring tasks, then follow-up tasks.
|
|
307
277
|
|
|
308
278
|
If `<tool_tasks>` is empty and there are no resolved items, omit the `## From Tools` and `## Resolved` sections entirely.
|
|
309
279
|
If `<tool_warnings>` is empty, omit the `## Warnings` section entirely. Each warning is written as-is (e.g., `! jira: command not found — install jira first`).
|
|
@@ -318,27 +288,17 @@ If no "every other" recurring tasks were added, skip this step.
|
|
|
318
288
|
</step>
|
|
319
289
|
|
|
320
290
|
<step name="git-commit">
|
|
321
|
-
|
|
322
|
-
```bash
|
|
323
|
-
git -C <storage_repo> add -A
|
|
324
|
-
```
|
|
325
|
-
|
|
326
|
-
Check whether there is anything to commit:
|
|
291
|
+
If `<follow_ups_modified>` is `true` (the check-follow-ups step modified follow-ups.md), run via Bash:
|
|
327
292
|
```bash
|
|
328
|
-
|
|
293
|
+
node ~/.donna/donna-tools.cjs commit "donna(daily): <today> daily brief" --files <daily_folder>/<today>.md donna/follow-ups.md
|
|
329
294
|
```
|
|
330
295
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
Otherwise, run:
|
|
296
|
+
Otherwise (follow-ups.md was not modified), run via Bash:
|
|
334
297
|
```bash
|
|
335
|
-
|
|
298
|
+
node ~/.donna/donna-tools.cjs commit "donna(daily): <today> daily brief" --files <daily_folder>/<today>.md
|
|
336
299
|
```
|
|
337
300
|
|
|
338
|
-
|
|
339
|
-
```bash
|
|
340
|
-
git -C <storage_repo> push
|
|
341
|
-
```
|
|
301
|
+
Per D-07: follow-ups.md is included in the commit when items were surfaced and removed from the standing file.
|
|
342
302
|
</step>
|
|
343
303
|
|
|
344
304
|
<step name="print-brief">
|
|
@@ -363,6 +323,13 @@ If there are recurring tasks due today (tasks from `<recurring_tasks>` that were
|
|
|
363
323
|
- [ ] Review sprint backlog
|
|
364
324
|
```
|
|
365
325
|
|
|
326
|
+
If there are follow-up tasks (tasks from `<follow_up_tasks>` that were added to the final list), print:
|
|
327
|
+
```
|
|
328
|
+
## Follow-ups
|
|
329
|
+
- [ ] Review design doc
|
|
330
|
+
- [ ] Submit expense report
|
|
331
|
+
```
|
|
332
|
+
|
|
366
333
|
If there are tool tasks (tasks from `<tool_tasks>` that were added to the final list), print:
|
|
367
334
|
```
|
|
368
335
|
## From Tools
|
|
@@ -381,7 +348,7 @@ Always end with:
|
|
|
381
348
|
══════════════════════════════════════
|
|
382
349
|
```
|
|
383
350
|
|
|
384
|
-
Show ALL tasks — never truncate. If no carried-forward tasks, omit the "## Carried Forward" section. If no recurring tasks due today, omit the "## Due Today" section. If no tool tasks, omit the "## From Tools" section. If no tool warnings, omit the "## Warnings" section. If carried-forward, recurring, AND tool tasks are all empty and there are no existing tasks, print:
|
|
351
|
+
Show ALL tasks — never truncate. If no carried-forward tasks, omit the "## Carried Forward" section. If no recurring tasks due today, omit the "## Due Today" section. If no follow-up tasks, omit the "## Follow-ups" section. If no tool tasks, omit the "## From Tools" section. If no tool warnings, omit the "## Warnings" section. If carried-forward, recurring, follow-up, AND tool tasks are all empty and there are no existing tasks, print:
|
|
385
352
|
```
|
|
386
353
|
No tasks for today — enjoy your day!
|
|
387
354
|
```
|
package/workflows/done.md
CHANGED
|
@@ -4,71 +4,33 @@
|
|
|
4
4
|
Mark one or more tasks as complete in today's daily journal file and commit the change to git.
|
|
5
5
|
</objective>
|
|
6
6
|
|
|
7
|
-
<step name="
|
|
8
|
-
Read `~/.config/donna/config.md`.
|
|
9
|
-
|
|
10
|
-
If the file does not exist, print:
|
|
11
|
-
```
|
|
12
|
-
✗ Donna is not configured. Run /donna:setup first.
|
|
13
|
-
```
|
|
14
|
-
Stop.
|
|
15
|
-
|
|
16
|
-
Extract the `storage_repo`, `daily_folder` (default: `daily`), and `auto_push` (default: false) fields from the YAML frontmatter.
|
|
17
|
-
|
|
18
|
-
**Obsidian sync:** Check if `<storage_repo>/.obsidian/daily-notes.json` exists.
|
|
19
|
-
- If it exists and has a `folder` field that differs from `<daily_folder>`: update `<daily_folder>` to match Obsidian's value, and update `~/.config/donna/config.md` with the new `daily_folder`. Print `✓ Synced daily folder with Obsidian: <daily_folder>`.
|
|
20
|
-
- If `<storage_repo>/.obsidian/` exists but `daily-notes.json` does not exist or has no `folder` field: write `<storage_repo>/.obsidian/daily-notes.json` with `{"folder":"<daily_folder>"}`. Print `✓ Configured Obsidian daily notes to use <daily_folder>/`.
|
|
21
|
-
- Otherwise: do nothing.
|
|
22
|
-
</step>
|
|
23
|
-
|
|
24
|
-
<step name="check-pending-migrations">
|
|
25
|
-
Read `~/.donna/state.md` with the Read tool. If the file does not exist or has no `pending_migrations` field in its YAML frontmatter, skip this step.
|
|
26
|
-
|
|
27
|
-
For each entry in `pending_migrations`:
|
|
28
|
-
|
|
29
|
-
**`move-standing-files`:** Move standing files from storage repo root to donna/ subfolder.
|
|
30
|
-
|
|
7
|
+
<step name="init">
|
|
31
8
|
Run via Bash:
|
|
32
9
|
```bash
|
|
33
|
-
|
|
34
|
-
DONNA_DIR="$STORAGE_REPO/donna"
|
|
35
|
-
MOVED=0
|
|
36
|
-
|
|
37
|
-
mkdir -p "$DONNA_DIR"
|
|
38
|
-
for FILE in role.md recurring.md role-research.md; do
|
|
39
|
-
if [ -f "$STORAGE_REPO/$FILE" ] && [ ! -f "$DONNA_DIR/$FILE" ]; then
|
|
40
|
-
mv "$STORAGE_REPO/$FILE" "$DONNA_DIR/$FILE"
|
|
41
|
-
echo "Moved $FILE to donna/$FILE"
|
|
42
|
-
MOVED=$((MOVED + 1))
|
|
43
|
-
fi
|
|
44
|
-
done
|
|
45
|
-
|
|
46
|
-
echo "MOVED=$MOVED"
|
|
10
|
+
INIT=$(node ~/.donna/donna-tools.cjs init)
|
|
47
11
|
```
|
|
48
12
|
|
|
49
|
-
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
git -C <storage_repo> diff --cached --quiet || git -C <storage_repo> commit -m "donna(migrate): move standing files to donna/ subfolder"
|
|
13
|
+
Parse the JSON response. If the `error` field is `"not_configured"`, print:
|
|
14
|
+
```
|
|
15
|
+
x Donna is not configured. Run /donna:setup first.
|
|
53
16
|
```
|
|
17
|
+
Stop.
|
|
54
18
|
|
|
55
|
-
|
|
19
|
+
Extract `storage_repo`, `daily_folder`, `auto_push` from the JSON.
|
|
56
20
|
|
|
57
|
-
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
pending_migrations: []
|
|
61
|
-
---
|
|
21
|
+
If `update_available` is non-null, print:
|
|
22
|
+
```
|
|
23
|
+
Donna v<update_available> available -- run npx @pingvinen/donna-assistant to update
|
|
62
24
|
```
|
|
25
|
+
Continue normally.
|
|
63
26
|
</step>
|
|
64
27
|
|
|
65
28
|
<step name="find-daily-file">
|
|
66
|
-
|
|
29
|
+
Get the daily file path via donna-tools:
|
|
67
30
|
```bash
|
|
68
|
-
|
|
31
|
+
DAILY_PATH=$(node ~/.donna/donna-tools.cjs daily-path | node -e "process.stdin.resume();let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>console.log(JSON.parse(d).path))")
|
|
69
32
|
```
|
|
70
|
-
|
|
71
|
-
Store the result as `<date>`. Construct the daily file path: `<storage_repo>/<daily_folder>/<date>.md`.
|
|
33
|
+
Store the result as `<daily_file_path>`. Extract `<date>` from the filename (last path component without `.md`).
|
|
72
34
|
|
|
73
35
|
If the file does not exist, print:
|
|
74
36
|
```
|
|
@@ -135,30 +97,10 @@ Write the updated file with the Write tool.
|
|
|
135
97
|
<step name="git-commit">
|
|
136
98
|
Run via Bash:
|
|
137
99
|
```bash
|
|
138
|
-
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
Check whether there is anything to commit:
|
|
142
|
-
```bash
|
|
143
|
-
git -C <storage_repo> status --porcelain
|
|
100
|
+
node ~/.donna/donna-tools.cjs commit "donna(done): <task_summary>" --files <daily_folder>/<date>.md
|
|
144
101
|
```
|
|
145
102
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
If one task was completed, run:
|
|
149
|
-
```bash
|
|
150
|
-
git -C <storage_repo> commit -m "donna(done): <description>"
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
If multiple tasks were completed, run:
|
|
154
|
-
```bash
|
|
155
|
-
git -C <storage_repo> commit -m "donna(done): <N> tasks completed"
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
If `auto_push` is true in config, also run:
|
|
159
|
-
```bash
|
|
160
|
-
git -C <storage_repo> push
|
|
161
|
-
```
|
|
103
|
+
Where `<task_summary>` is the completed task description (if one task) or `<N> tasks completed` (if multiple tasks).
|
|
162
104
|
</step>
|
|
163
105
|
|
|
164
106
|
<step name="confirm">
|
package/workflows/focus.md
CHANGED
|
@@ -4,92 +4,33 @@
|
|
|
4
4
|
Read today's daily file, score open tasks on urgency and context signals, optionally re-query active tools for enriched data, and produce a short prioritized focus list written to daily/focus.md and printed to the terminal. This is a read-only operation relative to the daily file: only focus.md is written.
|
|
5
5
|
</objective>
|
|
6
6
|
|
|
7
|
-
<step name="
|
|
8
|
-
Read `~/.config/donna/config.md`.
|
|
9
|
-
|
|
10
|
-
If the file does not exist, print:
|
|
11
|
-
```
|
|
12
|
-
✗ Donna is not configured. Run /donna:setup first.
|
|
13
|
-
```
|
|
14
|
-
Stop.
|
|
15
|
-
|
|
16
|
-
Extract the `storage_repo`, `daily_folder` (default: `daily`), and `auto_push` (default: false) fields from the YAML frontmatter.
|
|
17
|
-
|
|
18
|
-
**Obsidian sync:** Check if `<storage_repo>/.obsidian/daily-notes.json` exists.
|
|
19
|
-
- If it exists and has a `folder` field that differs from `<daily_folder>`: update `<daily_folder>` to match Obsidian's value, and update `~/.config/donna/config.md` with the new `daily_folder`. Print `✓ Synced daily folder with Obsidian: <daily_folder>`.
|
|
20
|
-
- If `<storage_repo>/.obsidian/` exists but `daily-notes.json` does not exist or has no `folder` field: write `<storage_repo>/.obsidian/daily-notes.json` with `{"folder":"<daily_folder>"}`. Print `✓ Configured Obsidian daily notes to use <daily_folder>/`.
|
|
21
|
-
- Otherwise: do nothing.
|
|
22
|
-
</step>
|
|
23
|
-
|
|
24
|
-
<step name="check-pending-migrations">
|
|
25
|
-
Read `~/.donna/state.md` with the Read tool. If the file does not exist or has no `pending_migrations` field in its YAML frontmatter, skip this step.
|
|
26
|
-
|
|
27
|
-
For each entry in `pending_migrations`:
|
|
28
|
-
|
|
29
|
-
**`move-standing-files`:** Move standing files from storage repo root to donna/ subfolder.
|
|
30
|
-
|
|
7
|
+
<step name="init">
|
|
31
8
|
Run via Bash:
|
|
32
9
|
```bash
|
|
33
|
-
|
|
34
|
-
DONNA_DIR="$STORAGE_REPO/donna"
|
|
35
|
-
MOVED=0
|
|
36
|
-
|
|
37
|
-
mkdir -p "$DONNA_DIR"
|
|
38
|
-
for FILE in role.md recurring.md role-research.md; do
|
|
39
|
-
if [ -f "$STORAGE_REPO/$FILE" ] && [ ! -f "$DONNA_DIR/$FILE" ]; then
|
|
40
|
-
mv "$STORAGE_REPO/$FILE" "$DONNA_DIR/$FILE"
|
|
41
|
-
echo "Moved $FILE to donna/$FILE"
|
|
42
|
-
MOVED=$((MOVED + 1))
|
|
43
|
-
fi
|
|
44
|
-
done
|
|
45
|
-
|
|
46
|
-
echo "MOVED=$MOVED"
|
|
10
|
+
INIT=$(node ~/.donna/donna-tools.cjs init)
|
|
47
11
|
```
|
|
48
12
|
|
|
49
|
-
|
|
50
|
-
```bash
|
|
51
|
-
git -C <storage_repo> add -A
|
|
52
|
-
git -C <storage_repo> diff --cached --quiet || git -C <storage_repo> commit -m "donna(migrate): move standing files to donna/ subfolder"
|
|
13
|
+
Parse the JSON response. If the `error` field is `"not_configured"`, print:
|
|
53
14
|
```
|
|
54
|
-
|
|
55
|
-
If `auto_push` is true in config, also push.
|
|
56
|
-
|
|
57
|
-
**`backfill-tool-type`:** Backfill `type` on existing tool sections in tools.md using heuristic detection.
|
|
58
|
-
|
|
59
|
-
Read `<storage_repo>/donna/tools.md` with the Read tool. If the file does not exist or has no tool sections, skip this handler.
|
|
60
|
-
|
|
61
|
-
For each tool section (starting with `## <tool_name>`), check if a `- type:` line already exists. If the `- type:` line is missing, detect the correct type:
|
|
62
|
-
|
|
63
|
-
1. If the tool section contains a `- command:` line where the value starts with `mcp:` (e.g., `- command: mcp:linear`), insert `- type: mcp` immediately after the `- command:` line.
|
|
64
|
-
2. Else, if the tool section contains a `- base_url:` line:
|
|
65
|
-
- If the capabilities section contains entries that look like GraphQL queries (contain `query {` or `mutation {`), insert `- type: graphql` immediately after `## <tool_name>` (REST/GraphQL tools have no `- command:` line).
|
|
66
|
-
- Otherwise, insert `- type: rest` immediately after `## <tool_name>`.
|
|
67
|
-
3. Else (no `mcp:` prefix, no `base_url` field), insert `- type: cli` immediately after the `- command:` line.
|
|
68
|
-
|
|
69
|
-
Write the updated file back with the Write tool. If any changes were made, commit:
|
|
70
|
-
```bash
|
|
71
|
-
git -C <storage_repo> add -A
|
|
72
|
-
git -C <storage_repo> diff --cached --quiet || git -C <storage_repo> commit -m "donna(migrate): backfill tool types on existing tools"
|
|
15
|
+
x Donna is not configured. Run /donna:setup first.
|
|
73
16
|
```
|
|
17
|
+
Stop.
|
|
74
18
|
|
|
75
|
-
|
|
19
|
+
Extract `storage_repo`, `daily_folder`, `auto_push` from the JSON.
|
|
76
20
|
|
|
77
|
-
|
|
78
|
-
```markdown
|
|
79
|
-
---
|
|
80
|
-
pending_migrations: []
|
|
81
|
-
---
|
|
21
|
+
If `update_available` is non-null, print:
|
|
82
22
|
```
|
|
23
|
+
Donna v<update_available> available -- run npx @pingvinen/donna-assistant to update
|
|
24
|
+
```
|
|
25
|
+
Continue normally.
|
|
83
26
|
</step>
|
|
84
27
|
|
|
85
28
|
<step name="read-daily-file">
|
|
86
|
-
Get
|
|
29
|
+
Get the daily file path via donna-tools:
|
|
87
30
|
```bash
|
|
88
|
-
|
|
31
|
+
DAILY_PATH=$(node ~/.donna/donna-tools.cjs daily-path | node -e "process.stdin.resume();let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>console.log(JSON.parse(d).path))")
|
|
89
32
|
```
|
|
90
|
-
Store as `<today
|
|
91
|
-
|
|
92
|
-
Construct the daily file path: `<storage_repo>/<daily_folder>/<today>.md`.
|
|
33
|
+
Store the result as `<daily_file_path>`. Extract `<today>` from the filename (last path component without `.md`).
|
|
93
34
|
|
|
94
35
|
Read the daily file with the Read tool. If the file does not exist, print:
|
|
95
36
|
```
|
|
@@ -154,23 +95,25 @@ For each matched tool, extract:
|
|
|
154
95
|
**Type-aware execution within each agent (or direct execution for single tool):**
|
|
155
96
|
|
|
156
97
|
For `type: cli` capabilities (format: `<name>: <cli_invocation>`):
|
|
98
|
+
|
|
99
|
+
Run via Bash (set the Bash tool's `timeout` parameter to `10000`):
|
|
157
100
|
```bash
|
|
158
|
-
|
|
101
|
+
<cli_invocation> 2>&1
|
|
159
102
|
```
|
|
160
103
|
|
|
161
104
|
For `type: rest` capabilities (format: `<name>: <METHOD> /path`):
|
|
162
105
|
1. Read `<storage_repo>/donna/secrets.md` with the Read tool. Parse key-value pairs from under the frontmatter.
|
|
163
106
|
2. Resolve the `auth_secret` key to get the actual secret value. If the key is not found in secrets.md or the value is `REPLACE_WITH_YOUR_SECRET`, add warning `! <tool_name>: missing secret <auth_secret> — edit donna/secrets.md` and skip this tool.
|
|
164
|
-
3. For each capability, run via Bash
|
|
107
|
+
3. For each capability, run via Bash (set the Bash tool's `timeout` parameter to `10000`):
|
|
165
108
|
```bash
|
|
166
|
-
|
|
109
|
+
curl -s -H "<auth_header>: <resolved_secret>" "<base_url><path>" 2>&1
|
|
167
110
|
```
|
|
168
111
|
|
|
169
112
|
For `type: graphql` capabilities (format: `<name>: <graphql_query>`):
|
|
170
113
|
1. Same secrets resolution as REST.
|
|
171
|
-
2. For each capability, run via Bash
|
|
114
|
+
2. For each capability, run via Bash (set the Bash tool's `timeout` parameter to `10000`):
|
|
172
115
|
```bash
|
|
173
|
-
|
|
116
|
+
curl -s -X POST -H "<auth_header>: <resolved_secret>" -H "Content-Type: application/json" -d '{"query":"<graphql_query>"}' "<base_url>" 2>&1
|
|
174
117
|
```
|
|
175
118
|
|
|
176
119
|
For `type: mcp` capabilities (format: `<name>: mcp:<server>/<tool>`):
|
|
@@ -262,24 +205,7 @@ If there are tool warnings from `<tool_warnings>`, append them after the footer:
|
|
|
262
205
|
<step name="git-commit">
|
|
263
206
|
Run via Bash:
|
|
264
207
|
```bash
|
|
265
|
-
|
|
266
|
-
```
|
|
267
|
-
|
|
268
|
-
Check whether there is anything to commit:
|
|
269
|
-
```bash
|
|
270
|
-
git -C <storage_repo> status --porcelain
|
|
271
|
-
```
|
|
272
|
-
|
|
273
|
-
If the output is empty, skip the commit and continue.
|
|
274
|
-
|
|
275
|
-
Otherwise, run:
|
|
276
|
-
```bash
|
|
277
|
-
git -C <storage_repo> commit -m "donna(focus): focus list for <today>"
|
|
278
|
-
```
|
|
279
|
-
|
|
280
|
-
If `auto_push` is true in config, also run:
|
|
281
|
-
```bash
|
|
282
|
-
git -C <storage_repo> push
|
|
208
|
+
node ~/.donna/donna-tools.cjs commit "donna(focus): updated focus list" --files <daily_folder>/<today>.md
|
|
283
209
|
```
|
|
284
210
|
</step>
|
|
285
211
|
|