@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.
@@ -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="read-config">
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
- STORAGE_REPO="<storage_repo>"
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
- If MOVED > 0, commit the move:
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
- If `auto_push` is true in config, also push.
19
+ Extract `storage_repo`, `daily_folder`, `auto_push` from the JSON.
76
20
 
77
- After processing all pending migrations, update `~/.donna/state.md` with the Write tool: remove the completed entries from `pending_migrations`. If no entries remain, write:
78
- ```markdown
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
- Construct the daily file path: `<storage_repo>/<daily_folder>/<today>.md`.
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 with a 10-second timeout:
148
+ Run via Bash (set the Bash tool's `timeout` parameter to `10000`):
182
149
  ```bash
183
- timeout 10 <cli_invocation> 2>&1
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 with a 10-second timeout:
180
+ 3. For each capability, run via Bash (set the Bash tool's `timeout` parameter to `10000`):
214
181
  ```bash
215
- timeout 10 curl -s -H "<auth_header>: <resolved_secret>" "<base_url><path>" 2>&1
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 with a 10-second timeout:
193
+ 2. For each capability, run via Bash (set the Bash tool's `timeout` parameter to `10000`):
227
194
  ```bash
228
- timeout 10 curl -s -X POST -H "<auth_header>: <resolved_secret>" -H "Content-Type: application/json" -d '{"query":"<graphql_query>"}' "<base_url>" 2>&1
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 `<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.
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
- Run via Bash:
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
- git -C <storage_repo> status --porcelain
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
- If the output is empty, skip the commit and continue.
332
-
333
- Otherwise, run:
296
+ Otherwise (follow-ups.md was not modified), run via Bash:
334
297
  ```bash
335
- git -C <storage_repo> commit -m "donna(begin-the-day): daily brief for <today>"
298
+ node ~/.donna/donna-tools.cjs commit "donna(daily): <today> daily brief" --files <daily_folder>/<today>.md
336
299
  ```
337
300
 
338
- If `auto_push` is true in config, also run:
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="read-config">
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
- STORAGE_REPO="<storage_repo>"
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
- If MOVED > 0, commit the move:
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:
14
+ ```
15
+ x Donna is not configured. Run /donna:setup first.
53
16
  ```
17
+ Stop.
54
18
 
55
- If `auto_push` is true in config, also push.
19
+ Extract `storage_repo`, `daily_folder`, `auto_push` from the JSON.
56
20
 
57
- After processing all pending migrations, update `~/.donna/state.md` with the Write tool: remove the completed entries from `pending_migrations`. If no entries remain, write:
58
- ```markdown
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
- Run via Bash to get today's date:
29
+ Get the daily file path via donna-tools:
67
30
  ```bash
68
- date +%Y-%m-%d
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
- git -C <storage_repo> add -A
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
- If the output is empty, skip the commit and continue.
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">
@@ -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="read-config">
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
- STORAGE_REPO="<storage_repo>"
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
- If MOVED > 0, commit the move:
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
- If `auto_push` is true in config, also push.
19
+ Extract `storage_repo`, `daily_folder`, `auto_push` from the JSON.
76
20
 
77
- After processing all pending migrations, update `~/.donna/state.md` with the Write tool: remove the completed entries from `pending_migrations`. If no entries remain, write:
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 today's date via Bash:
29
+ Get the daily file path via donna-tools:
87
30
  ```bash
88
- date +%Y-%m-%d
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
- timeout 10 <cli_invocation> 2>&1
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 with a 10-second timeout:
107
+ 3. For each capability, run via Bash (set the Bash tool's `timeout` parameter to `10000`):
165
108
  ```bash
166
- timeout 10 curl -s -H "<auth_header>: <resolved_secret>" "<base_url><path>" 2>&1
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 with a 10-second timeout:
114
+ 2. For each capability, run via Bash (set the Bash tool's `timeout` parameter to `10000`):
172
115
  ```bash
173
- timeout 10 curl -s -X POST -H "<auth_header>: <resolved_secret>" -H "Content-Type: application/json" -d '{"query":"<graphql_query>"}' "<base_url>" 2>&1
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
- git -C <storage_repo> add -A
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