daily-focus 1.1.1-dev.3 → 1.2.0-dev.11

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 CHANGED
@@ -35,9 +35,11 @@ To use your own data:
35
35
  npx daily-focus
36
36
  ```
37
37
 
38
- Until the first brief exists, the Today tab walks you through the rest: what it
39
- briefs, your objective, which coding-agent CLI writes the brief (Claude Code or
40
- Codex), and where it should look. Everything stays on the settings page afterwards.
38
+ A new store opens on the setup screen: a few questions, one at a time, each with
39
+ the likely answer already ticked. Once you've chosen the coding-agent CLI that writes
40
+ the brief (Claude Code or Codex), it looks into the rest for you, such as which of
41
+ your calendars are work ones, so most answers are a click. Everything stays on the
42
+ settings page afterwards.
41
43
  To keep it running in the background on macOS, install it and run it as a service:
42
44
 
43
45
  ```sh
@@ -64,13 +66,6 @@ since you completed something that advanced your objective.
64
66
  - Mark tasks **Done** when you've handled them.
65
67
  - **Snooze** an item until a date, or **Dismiss** it if it doesn't need attention.
66
68
  - Leave a **Note** for the next brief, such as "already replied on Slack".
67
- - Press **f** for focus mode, which shows your top item and agenda.
68
- - Press **p** on an item to start a focus timer. Its countdown appears in the tab
69
- title, and the session becomes part of the next brief's context.
70
-
71
- The timer keeps counting after its target time. On macOS, it ends a session when
72
- you've been away from the machine, excluding the time you were away. On systems
73
- without idle detection, a two-hour limit caps the recorded session.
74
69
 
75
70
  You can undo item actions except notes. The page updates as new data arrives, and
76
71
  the theme button switches between system, light, and dark mode.
@@ -90,8 +85,10 @@ The second tab shows your open pull requests in seven buckets:
90
85
  | Drafts | Pull requests you haven't marked ready for review. |
91
86
 
92
87
  Park a pull request until a date, leave a note, or click **Nudged** after asking
93
- for a review. Nudged records a note; it doesn't send a message. Completing a task
94
- about a pull request in the brief doesn't remove that pull request from the board.
88
+ for a review. Nudged records that you asked; it doesn't send a message. The pull
89
+ request moves to a Nudged section for a day, then goes back to Waiting on reviewers
90
+ with "time to ask" if nobody has reviewed it. Completing a task about a pull
91
+ request in the brief doesn't remove that pull request from the board.
95
92
 
96
93
  Cancelled checks appear as "cancelled, no verdict" rather than failures.
97
94
  When a check is rerun, the board uses its newest workflow run or attempt.
@@ -111,6 +108,14 @@ Draft pull requests count as open. Closed pull requests don't prove that a ticke
111
108
  is finished, so the board leaves that decision to you. Park a reminder or leave a
112
109
  note when there's more work planned.
113
110
 
111
+ Jira can take days to hear that a pull request merged, so the board also checks
112
+ GitHub. It searches your open pull requests and the ones closed in the last 60
113
+ days, and matches them to tickets by the key in the title, branch, description
114
+ or commit messages. An open pull request on GitHub always counts. GitHub can
115
+ also mark a ticket's pull requests as all closed, but only when it found at least
116
+ as many as Jira has linked. A row that GitHub changed lists those pull requests
117
+ under **GitHub, ahead of Jira**.
118
+
114
119
  Switch to **Working on** to see your in-progress tickets grouped by status,
115
120
  including ones that also need a status check. You can narrow this view in
116
121
  [SETUP.md](SETUP.md#jira).
@@ -127,15 +132,28 @@ why is CI red, what does this thread actually want from me. With
127
132
  `DAILY_FOCUS_ASSISTANT` set to `claude` or `codex`, every item's panel gets an
128
133
  assistant that runs that CLI headless against the item, with quick actions for the
129
134
  common asks and a field for anything else. Click a card to open its panel, where its
130
- notes live too; the reply streams in there, and you can follow up in the same
131
- conversation. The panel stays on the item it was opened for while you move through
132
- the list.
133
-
134
- It reads and drafts, and that is all. An email reply is created as a Gmail draft on
135
- the thread, so it is waiting there when you open the mail; a reply to a reviewer is
136
- handed back as text for you to post. It never sends, posts, or edits a file, and it
137
- has no checkout: fixing conflicts or a build is work for a real coding session, and
138
- this is for the questions you would otherwise answer by opening six tabs.
135
+ notes live too. While the assistant works, the panel shows what it is doing: each
136
+ command it runs and each page, thread or ticket it reads, with a clock, and a cross
137
+ on anything that failed, such as a repository it couldn't see. Once it answers,
138
+ that trail folds away under the answer. The answer has buttons to copy it, or any
139
+ block in it meant for pasting, and to open a draft it created. The field stays at
140
+ the foot of the panel, so you can follow up in the same conversation. The panel
141
+ stays on the item it was opened for while you move through the list.
142
+
143
+ It can also answer before you ask. With **Answer ahead** on in the settings, when a
144
+ pull request starts waiting on you because someone reviewed it or a check failed,
145
+ the assistant assesses the review or explains the failure on its own. The first
146
+ line of its answer appears on the row, such as "Flaky, not yours: the Safari job
147
+ timed out", so the card already says what to do. It asks about each state once,
148
+ one at a time, and no more than ten times a day unless you change the limit.
149
+
150
+ It is told to read and draft, and nothing more. An email reply is created as a Gmail
151
+ draft on the thread, so it is waiting there when you open the mail; a reply to a
152
+ reviewer is handed back as text for you to post. It is told never to send, post, or
153
+ edit a file, and it has no checkout: fixing conflicts or a build is work for a real
154
+ coding session, and this is for the questions you would otherwise answer by opening
155
+ six tabs. How much of that the CLI itself enforces differs between Claude Code and
156
+ Codex; see [What the assistant can do](SETUP.md#what-the-assistant-can-do).
139
157
 
140
158
  ## The morning agent
141
159
 
@@ -165,8 +183,6 @@ Press **?** in the dashboard to see the shortcuts.
165
183
  | `a` | Open the panel, ready to ask the assistant |
166
184
  | `o` | Open the source link |
167
185
  | `u` | Undo the last action |
168
- | `f` | Toggle focus mode |
169
- | `p` | Start / stop a focus session |
170
186
  | `r` | Refresh the current board |
171
187
  | `w` | Switch Jira views |
172
188
  | `,` | Settings |
package/SETUP.md CHANGED
@@ -27,18 +27,56 @@ and `npm start` runs it in the terminal. Each `daily-focus <command>` below is
27
27
  `npm run <command>` in a checkout, with two differences: `build-calendar` is
28
28
  `build:calendar`, and flags go after `--`, as in `npm run audit -- --against <file>`.
29
29
 
30
- Until the first brief exists, the Today tab walks you through setting it up:
31
-
32
- 1. **What it briefs**: your work, or your personal life. See
30
+ A new store opens on the setup screen. It first looks for Codex and Claude Code:
31
+ on your login shell's PATH, then where their installers put them, and checks that
32
+ the one it finds is logged in. With one ready it doesn't ask: it uses Codex if
33
+ that is ready, otherwise Claude Code, and says so in a line you can **Change**.
34
+ With neither ready, it says what is wrong with each and the command that fixes it
35
+ (`codex login`, `claude auth login`), links to the installers, and takes the path
36
+ to one it couldn't find.
37
+
38
+ Then it asks a few questions, one at a time, and each comes with the answer you
39
+ most likely want already ticked: confirm it or change it. A list can be left
40
+ unticked and a field empty. Two questions can be left, by a button that says what
41
+ that does: **Decide later** for the agent, and **Leave this out** for who you are.
42
+ **Change** reopens an earlier answer.
43
+
44
+ 1. **Who writes the brief**, only when it couldn't pick for you.
45
+ 2. **What it briefs**: your work, or your personal life. See
33
46
  [A personal instance](#a-personal-instance) for running both.
34
- 2. **Your objective**: the one thing you're trying to achieve, which the agent
35
- ranks the day against.
36
- 3. **Who writes the brief**: Claude Code or Codex, whichever it finds installed.
37
- 4. **Where it should look**: your source list, which starts from a template with
38
- what `gh` and `git` know about you filled in.
39
- 5. **What else to show**: the pull request board, the Jira board and the live
40
- agenda, each with its status and a button to turn it off.
41
- 6. **Write my first brief**, which runs the agent once while you watch.
47
+ 3. **When it runs**, and on which days.
48
+ 4. **Who you are**: your name as meeting notes write it, your email, and each
49
+ GitHub account `gh` is logged in to, with what it's for.
50
+ 5. **What else to show**: the pull request board and the Jira board, each with
51
+ its status.
52
+ 6. **Which calendars** the brief reads, which the live agenda follows too.
53
+ 7. **Your objective**, which the agent ranks the day against, and what's in the
54
+ way. It suggests a few from what you've been doing, when something stands
55
+ out, and writes one up from whatever you tell it, however rough.
56
+
57
+ The [assistant](#ask-the-assistant) isn't asked about: it comes on with the CLI
58
+ that writes the brief, unless you've set it already.
59
+
60
+ Once you've said what it briefs, the CLI looks into the others in the background,
61
+ one short session each, so the slow ones are ready when you get to them. It reads
62
+ `gh`, your mail and your calendars to tell work from personal, and says in a
63
+ sentence why it ticked what it did. Reply under that sentence with what to change,
64
+ such as "also the on-call rota", and it tries again, answering in the same place.
65
+ Continue before it has finished and it asks first, then stops and keeps what the
66
+ card holds.
67
+
68
+ The sessions run on the newest flagship model at low effort (Opus for Claude Code,
69
+ the first model in Codex's own list for Codex), which measured as fast as the
70
+ lighter models and, unlike them, told your calendars from other people's. They
71
+ only read, in an empty directory. Claude Code is given read tools by name, and
72
+ under Codex every connector write is refused, drafts included; `gh` and `acli` are
73
+ held to reading by their instructions, as
74
+ [the assistant's](#what-the-assistant-can-do) are.
75
+
76
+ Nothing is saved until the last step, **Write my first brief**. It saves the
77
+ settings, writes your source list from the answers (unless you already have one,
78
+ which it leaves alone) and your objective, restarts the dashboard to apply them,
79
+ and runs the agent once while you watch.
42
80
 
43
81
  Everything in it stays on the settings page afterwards: the gear in the header, or
44
82
  <kbd>,</kbd>. The dashboard keeps its files in `~/.daily-focus/`, and links the
@@ -52,6 +90,8 @@ terminal open while you use the dashboard. `daily-focus --help` lists the rest.
52
90
 
53
91
  If you'd rather write the files by hand, `daily-focus init` creates the store with
54
92
  templates for both. It preserves existing files, so you can safely run it again.
93
+ A setting given in the environment, such as `DAILY_FOCUS_PROFILE`, is shown on the
94
+ setup screen as answered and isn't asked.
55
95
 
56
96
  ## Set your objective and sources
57
97
 
@@ -91,7 +131,7 @@ Keep real names, account handles, and work details in this private store, outsid
91
131
 
92
132
  The dashboard runs the agent through a coding-agent CLI you already have. Install
93
133
  and log in to the [Codex CLI](https://developers.openai.com/codex/cli) or
94
- [Claude Code](https://code.claude.com/docs), and choose it in the setup steps or
134
+ [Claude Code](https://code.claude.com/docs), and choose it on the setup screen or
95
135
  under **Morning agent** in the settings. In `.env` or the environment that is:
96
136
 
97
137
  ```dotenv
@@ -108,7 +148,8 @@ half minute. The days are Monday to Friday unless `DAILY_FOCUS_AGENT_DAYS` says
108
148
  otherwise; see [Match your working week](#match-your-working-week).
109
149
  `DAILY_FOCUS_AGENT_AT=off` means the dashboard never starts a run on its own; the
110
150
  refresh icon still does. A new store's first brief always comes from the setup
111
- steps' button, so the clock never runs the agent before you've told it where to look.
151
+ screen's last button, so the clock never runs the agent before you've told it where
152
+ to look.
112
153
 
113
154
  "Your time" is the time zone of the browser you last looked at the dashboard
114
155
  in. The page tells the dashboard when it loads, reconnects or comes back into view,
@@ -126,21 +167,30 @@ it finishes, and a chat where you can ask it why it did what it did. See
126
167
  The agent reaches your sources the way the CLI does:
127
168
 
128
169
  - **Codex** runs in its workspace-write sandbox with network access, confined to the
129
- store. Connectors from the Codex app are found through its plugin catalogue. There
130
- is nobody to approve a command outside the sandbox, so the agent reports that
131
- restriction for any `gh` command that needs it, such as switching accounts.
170
+ store. Connectors from the Codex app are found through its plugin catalogue, and
171
+ every write through one is refused: a connector tool counts as a write unless it
172
+ is marked read-only. A command that needs to leave the sandbox, such as `gh`
173
+ switching accounts, is decided by your own Codex approval settings, as it would be
174
+ in your Codex. With nobody set to approve, the agent reports that restriction; with
175
+ Codex's automatic reviewer, the reviewer decides. The dashboard won't start a run
176
+ on a Codex older than 0.144.0, which would ignore the refusal of connector writes;
177
+ update Codex if a run fails saying so.
132
178
  - **Claude Code** may write `items.json` and nothing else in the store, and reach
133
179
  its sources with only what `DAILY_FOCUS_AGENT_TOOLS` allows. The default covers
134
180
  GitHub, Jira, web pages and the claude.ai Gmail connector. Add your calendar, chat
135
181
  and document connectors to the list by name, or the brief will report them as
136
- unreachable.
182
+ unreachable. The default allows every Gmail tool, sending included, and `gh` and
183
+ `acli` can write as well as read; the agent's instructions forbid changing
184
+ anything. To narrow Gmail to reading, name its tools instead of the connector, as
185
+ [What the assistant can do](#what-the-assistant-can-do) shows, without the two
186
+ draft tools.
137
187
 
138
188
  Set `DAILY_FOCUS_AGENT_MODEL` and `DAILY_FOCUS_AGENT_EFFORT` if the CLI's own
139
189
  defaults are not what you want for a brief; a brief is worth a high effort. If the
140
190
  server can't find the CLI, set `DAILY_FOCUS_AGENT_BIN`.
141
191
 
142
- The agent writes `items.json`. The dashboard records your actions and focus sessions
143
- for the next run to read.
192
+ The agent writes `items.json`. The dashboard records your actions for the next run
193
+ to read.
144
194
 
145
195
  After the first run, read its report (click "updated … ago"): it says which sources
146
196
  it couldn't reach. To check the brief against the payload contract, run:
@@ -228,6 +278,11 @@ Clicking a status in the dashboard writes one transition to Jira. All other Jira
228
278
  access is read-only. See the [ticket board guide](README.md#the-jira-ticket-board)
229
279
  for workflow limits and undo behavior.
230
280
 
281
+ The board also asks GitHub about your pull requests, because Jira can learn of
282
+ them days late. It uses the pull request board's accounts and scope, and nothing
283
+ else needs to be configured. With `DAILY_FOCUS_GITHUB=off`, the ticket board uses
284
+ Jira alone.
285
+
231
286
  Set `DAILY_FOCUS_JIRA=off` to disable the board.
232
287
 
233
288
  ### Live calendar on macOS
@@ -277,14 +332,72 @@ the CLI is configured with; `DAILY_FOCUS_ASSISTANT_MODEL` and
277
332
  `DAILY_FOCUS_ASSISTANT_EFFORT` override them. If the server can't find the CLI,
278
333
  set `DAILY_FOCUS_ASSISTANT_BIN` to its path.
279
334
 
280
- The assistant reads and drafts; it never sends, posts or edits anything, and it has
281
- no checkout to work in. That is deliberate. Fixing merge conflicts or a failing build
282
- belongs in a real coding session; this panel is for the questions you'd otherwise
283
- answer by opening six tabs. The Gmail draft is the one thing it creates, through the
284
- Gmail tool the CLI has: with Claude Code that is the claude.ai Gmail connector, which
285
- `DAILY_FOCUS_ASSISTANT_TOOLS` allows by default; with Codex it is the Gmail plugin
286
- from the Codex app, which the CLI finds through its plugin catalogue. Without either,
287
- the assistant hands you the text instead and says so.
335
+ The assistant is told to read and draft, and never to send, post or edit anything,
336
+ and it has no checkout to work in. That is deliberate. Fixing merge conflicts or a
337
+ failing build belongs in a real coding session; this panel is for the questions you'd
338
+ otherwise answer by opening six tabs. The Gmail draft is the one thing it creates,
339
+ and revises when you ask, through the Gmail tool the CLI has: with Claude Code that
340
+ is the claude.ai Gmail connector, which `DAILY_FOCUS_ASSISTANT_TOOLS` allows by
341
+ default; with Codex it is the Gmail app linked to your ChatGPT account, which the CLI
342
+ finds through its plugin catalogue. Without either, the assistant hands you the text
343
+ instead and says so.
344
+
345
+ ### What the assistant can do
346
+
347
+ The assistant runs the CLI you already use, with the access that CLI already has.
348
+ The dashboard narrows some of that, and leaves the rest to the assistant's
349
+ instructions. What the CLI itself enforces:
350
+
351
+ - **Claude Code** may use only the tools in `DAILY_FOCUS_ASSISTANT_TOOLS`, and never
352
+ its file-editing tools, whatever the list says; anything else is refused rather
353
+ than asked about. Rules in your own Claude Code settings that allow a tool still
354
+ apply. The default list is broader than the assistant needs:
355
+ `mcp__claude_ai_Gmail` allows every tool on the Gmail connector, sending and
356
+ deleting included, and `gh` and `acli` can comment, merge and move tickets as well
357
+ as read. Only the instructions keep it from doing those. To hold it to reading
358
+ mail and drafting replies, name the Gmail tools instead of the connector:
359
+
360
+ ```dotenv
361
+ DAILY_FOCUS_ASSISTANT_TOOLS=Bash(gh *),Bash(acli *),WebFetch,mcp__claude_ai_Gmail__search_threads,mcp__claude_ai_Gmail__get_thread,mcp__claude_ai_Gmail__get_message,mcp__claude_ai_Gmail__list_labels,mcp__claude_ai_Gmail__list_drafts,mcp__claude_ai_Gmail__get_draft,mcp__claude_ai_Gmail__create_draft,mcp__claude_ai_Gmail__update_draft
362
+ ```
363
+
364
+ A tool left off the list is refused, so if the connector renames one, the
365
+ assistant reports that it can't reach your mail rather than working around it.
366
+ - **Codex** refuses every write through a connector (Gmail, Calendar, Drive, GitHub
367
+ and the other apps your ChatGPT account links) except creating and revising a
368
+ Gmail draft. A connector tool counts as a write unless it is marked read-only. A
369
+ tool you have told Codex to always allow, or an app given approval settings of its
370
+ own in your Codex config, keeps them. Computer use, the plugins that act in your
371
+ apps and browser with your sign-ins, is off unless you turn on
372
+ `DAILY_FOCUS_ASSISTANT_COMPUTER_USE`; the dashboard checks with Codex that it is
373
+ off before each session, and refuses to start one it can't confirm. Shell
374
+ commands follow your own Codex config: the sandbox keeps writes in the
375
+ assistant's working directory, and a command that needs to leave it is decided
376
+ by your Codex approval settings, as it would be in your own Codex. That keeps
377
+ `gh` working, and means it can write. All of this needs Codex 0.149.0 or
378
+ newer, and the page warns when yours is older. Before 0.144.0 Codex silently
379
+ ignores the refusal of connector writes, so the dashboard won't start the
380
+ assistant or the morning agent on it at all; before 0.149.0 it can't switch
381
+ computer use off, so the assistant won't answer while that setting is off.
382
+
383
+ ### Answer ahead
384
+
385
+ With `DAILY_FOCUS_ASSISTANT_AUTO=on`, the dashboard asks the assistant before you
386
+ do. When a pull request lands in *Waiting on you* because someone reviewed or
387
+ commented, it asks the assistant to assess the review. When a check fails, it asks
388
+ for an explanation of the failure. The first line of the answer appears on the row,
389
+ on the board and on the brief item for the same pull request, while it still
390
+ matches the pull request's state. The whole answer is in the panel, as a turn you
391
+ can follow up on.
392
+
393
+ It asks about each state once. A new comment or a new failure is a new question;
394
+ the same checks failing again on the same commit are not. It runs one question at a
395
+ time and never on a row you're asking about, and it starts no more than
396
+ `DAILY_FOCUS_ASSISTANT_AUTO_LIMIT` a day (10 by default). It uses only those two
397
+ quick actions, which read and answer, and never one that drafts. It follows the
398
+ board, which reads only while a tab is open, so it asks while you have the
399
+ dashboard open. It is off by default because it spends the CLI's usage without
400
+ you pressing anything.
288
401
 
289
402
  Its instructions live in `prompts/assistant.md`, linked into the store as
290
403
  `assistant.md` each time the dashboard starts. What it says stays in the chat in the panel: it
@@ -398,8 +511,8 @@ daily-focus service --remove
398
511
 
399
512
  Daily Focus can brief your personal life as well as your work: email, family
400
513
  calendars, Apple Reminders, Apple Messages, e-Boks and your own GitHub projects. Run it as a second instance
401
- with its own store, server and morning agent, and choose **Personal life** in its
402
- setup steps, or set:
514
+ with its own store, server and morning agent, and choose **Personal life** on its
515
+ setup screen, or set:
403
516
 
404
517
  ```dotenv
405
518
  DAILY_FOCUS_PROFILE=personal
@@ -408,7 +521,7 @@ DAILY_FOCUS_PROFILE=personal
408
521
  The dashboard then links the personal prompt, `prompts/morning-brief-personal.md`,
409
522
  into the store as `prompt.md`, and the source list starts from a template with
410
523
  sections for those sources. The profile also switches off
411
- the Jira board and away detection, and gives the tab a green house icon instead of the blue briefcase. The pull request
524
+ the Jira board, and gives the tab a green house icon instead of the blue briefcase. The pull request
412
525
  board stays on for side projects; point it at your personal account with
413
526
  `DAILY_FOCUS_GITHUB_ACCOUNTS`, or set `DAILY_FOCUS_GITHUB=off`.
414
527
 
@@ -469,9 +582,7 @@ matters when `DAILY_FOCUS_FREE_WINDOWS` is off.
469
582
  | `DAILY_FOCUS_MIN_FREE_WINDOW` | `45` | Minutes before a gap counts as a focus window |
470
583
  | `DAILY_FOCUS_STALE_AFTER_HOURS` | `24` | When to expect a refresh. Shows an informational message for 45 minutes before warning that the agent may not have run. Counted only in hours a run was due, so days off never trip it |
471
584
  | `DAILY_FOCUS_AGENT_DAYS` | `1-5` | Weekdays the dashboard runs the agent on, cron-style and cron-numbered: `1-5` for Monday to Friday, `0-4` for Sunday to Thursday, `0,6` for a weekend-only run |
472
- | `DAILY_FOCUS_SESSION_MINUTES` | `25` | Default focus session length |
473
- | `DAILY_FOCUS_AWAY_AFTER` | `10`; `0` for personal | Minutes of an untouched machine before a session is closed at the last sign of life. `0` turns it off |
474
- | `DAILY_FOCUS_GITHUB` | `on` | `off` disables the pull request board; nothing is polled |
585
+ | `DAILY_FOCUS_GITHUB` | `on` | `off` disables the pull request board, and the ticket board stops checking GitHub; nothing is polled |
475
586
  | `DAILY_FOCUS_GITHUB_ACCOUNTS` | *gh's active account* | Logins to poll as, comma-separated, each resolved with `gh auth token --user` |
476
587
  | `DAILY_FOCUS_GITHUB_SCOPE` | *everything* | Organisations or `owner/repo` entries to limit the board to, comma-separated |
477
588
  | `DAILY_FOCUS_GITHUB_MERGE_GATE_CHECKS` | *none* | Check names that stand for a repository's whole merge policy, comma-separated and matched exactly. Their rows get the *Waiting on merge gate* bucket |
@@ -493,13 +604,16 @@ matters when `DAILY_FOCUS_FREE_WINDOWS` is off.
493
604
  | `DAILY_FOCUS_ASSISTANT_BIN` | *the CLI's name* | Path to the assistant's CLI, for when the server's PATH lacks it. `~` is expanded |
494
605
  | `DAILY_FOCUS_ASSISTANT_MODEL` | *the CLI's own* | Model passed to the CLI untouched: an alias like `opus`, or a full id. Unset passes no flag |
495
606
  | `DAILY_FOCUS_ASSISTANT_EFFORT` | *the CLI's own* | Effort passed to the CLI untouched: `low`, `medium`, `high`, `xhigh` or `max`. Unset passes no flag |
496
- | `DAILY_FOCUS_ASSISTANT_TOOLS` | `Bash(gh *),Bash(acli *),WebFetch,mcp__claude_ai_Gmail` | What Claude Code may use without asking, in its permission syntax, comma-separated. Editing tools are denied regardless. Ignored by Codex |
607
+ | `DAILY_FOCUS_ASSISTANT_TOOLS` | `Bash(gh *),Bash(acli *),WebFetch,mcp__claude_ai_Gmail` | What Claude Code may use without asking, in its permission syntax, comma-separated. Editing tools are denied regardless. The default allows every Gmail tool, sending included; see [What the assistant can do](#what-the-assistant-can-do) to narrow it. Ignored by Codex |
608
+ | `DAILY_FOCUS_ASSISTANT_COMPUTER_USE` | `off` | `on` lets the assistant use Codex's computer-use and browser plugins, which act in your apps and browser with your sign-ins. `off` switches them off for its runs. Ignored by Claude Code, which uses only the tools in its list |
609
+ | `DAILY_FOCUS_ASSISTANT_AUTO` | `off` | `on` asks the assistant ahead about pull requests waiting on you, after a review or a failing check, and puts the answer's first line on the row. See [Answer ahead](#answer-ahead) |
610
+ | `DAILY_FOCUS_ASSISTANT_AUTO_LIMIT` | `10` | How many times a day the assistant may start on its own, from 1 to 100 |
497
611
  | `DAILY_FOCUS_AGENT` | `off` | `codex` or `claude` lets the dashboard run the morning agent through that CLI: each scheduled morning, and from the refresh icon beside the brief's age. `off` hides it |
498
612
  | `DAILY_FOCUS_AGENT_AT` | `07:00` | Local time, `HH:MM`, at which the dashboard starts the agent on each scheduled day, or as soon as it is running after that. `off` means it never starts one on its own; the refresh icon still does. Needs `DAILY_FOCUS_AGENT` |
499
613
  | `DAILY_FOCUS_AGENT_BIN` | *the CLI's name* | Path to that CLI, for when the server's PATH lacks it. `~` is expanded |
500
614
  | `DAILY_FOCUS_AGENT_MODEL` | *the CLI's own* | Model passed to the CLI untouched. Unset passes no flag |
501
615
  | `DAILY_FOCUS_AGENT_EFFORT` | *the CLI's own* | Effort passed to the CLI untouched. Unset passes no flag |
502
- | `DAILY_FOCUS_AGENT_TOOLS` | `Bash(gh *),Bash(acli *),WebFetch,mcp__claude_ai_Gmail` | What Claude Code may use to reach your sources, in its permission syntax, comma-separated. Writing `items.json`, and nothing else in the store, is allowed regardless. Ignored by Codex |
616
+ | `DAILY_FOCUS_AGENT_TOOLS` | `Bash(gh *),Bash(acli *),WebFetch,mcp__claude_ai_Gmail` | What Claude Code may use to reach your sources, in its permission syntax, comma-separated. Writing `items.json`, and nothing else in the store, is allowed regardless. The default allows every Gmail tool, sending included. Ignored by Codex |
503
617
 
504
618
  ## If something looks wrong
505
619
 
@@ -507,9 +621,10 @@ matters when `DAILY_FOCUS_FREE_WINDOWS` is off.
507
621
  which it ends with. Run `daily-focus service` to keep it running. If the
508
622
  service is installed and the page still doesn't load, read
509
623
  `~/Library/Logs/local.daily-focus.log`.
510
- - Before the first brief, the Today tab shows the setup steps. Once a brief has
511
- existed, an empty Today tab means the agent hasn't written a new `items.json`:
512
- start a run from the refresh icon beside the brief's age.
624
+ - After setup and before the first brief, the Today tab says where the first brief
625
+ is, and offers to run it again if it didn't finish. Once a brief has existed, an
626
+ empty Today tab means the agent hasn't written a new `items.json`: start a run
627
+ from the refresh icon beside the brief's age.
513
628
  - A stale brief needs an agent run. Refreshing a board doesn't regenerate the brief;
514
629
  the icon beside the brief's age does. Click "updated … ago" to see what the last
515
630
  run said, or whether there was one: the dashboard has to be running at
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  readSystemZone,
3
3
  startingZone
4
- } from "./chunk-AUBJ2IDQ.js";
4
+ } from "./chunk-GVLNDQVQ.js";
5
5
  import {
6
6
  linkState
7
7
  } from "./chunk-QKT2FAB5.js";
@@ -11,8 +11,9 @@ import {
11
11
  parseBrief,
12
12
  readArchiveIndex,
13
13
  resolveItems,
14
- runContractChecks
15
- } from "./chunk-C6FXWHGT.js";
14
+ runContractChecks,
15
+ setsStatus
16
+ } from "./chunk-CPJ6LOVC.js";
16
17
  import {
17
18
  BRIEF_REFRESH_GRACE_HOURS,
18
19
  describeSchedule,
@@ -22,7 +23,7 @@ import {
22
23
  resolveSchedule,
23
24
  runsOn,
24
25
  workingMsBetween
25
- } from "./chunk-NWYOCDUU.js";
26
+ } from "./chunk-4DZEBUPU.js";
26
27
  import {
27
28
  command
28
29
  } from "./chunk-BC2W7NND.js";
@@ -180,7 +181,7 @@ if (!previous) {
180
181
  const reproduced = [...previousIds].filter((id) => currentIds.has(id));
181
182
  const dropped = [...previousIds].filter((id) => !currentIds.has(id));
182
183
  const added = [...currentIds].filter((id) => !previousIds.has(id));
183
- const actedOn = new Set(actions.filter((a) => a.action !== "note").map((a) => a.id));
184
+ const actedOn = new Set(actions.filter(setsStatus).map((a) => a.id));
184
185
  const addedFingerprints = new Map(added.map((id) => [fingerprintId(id), id]));
185
186
  const handled = dropped.filter((id) => actedOn.has(id));
186
187
  const drifted = dropped.filter((id) => !actedOn.has(id) && addedFingerprints.has(fingerprintId(id)));
@@ -353,7 +353,10 @@ function envAssistant(env) {
353
353
  binPath: expandHome((env.DAILY_FOCUS_ASSISTANT_BIN ?? "").trim() || (agent ?? "claude")),
354
354
  model: envString("DAILY_FOCUS_ASSISTANT_MODEL", "", env) || null,
355
355
  effort: envString("DAILY_FOCUS_ASSISTANT_EFFORT", "", env) || null,
356
- tools: tools.length > 0 ? tools : DEFAULT_ASSISTANT_TOOLS
356
+ tools: tools.length > 0 ? tools : DEFAULT_ASSISTANT_TOOLS,
357
+ computerUse: envFlag("DAILY_FOCUS_ASSISTANT_COMPUTER_USE", false, env),
358
+ auto: envFlag("DAILY_FOCUS_ASSISTANT_AUTO", false, env),
359
+ autoLimit: envBounded("DAILY_FOCUS_ASSISTANT_AUTO_LIMIT", 10, 1, 100, env)
357
360
  };
358
361
  }
359
362
  var DEFAULT_ASSISTANT_TOOLS = ["Bash(gh *)", "Bash(acli *)", "WebFetch", "mcp__claude_ai_Gmail"];
@@ -439,15 +442,10 @@ function loadConfig(env = loadEnv()) {
439
442
  schemaFile: resolve2(dataDir, "items.schema.json"),
440
443
  schemaSource: resolve2(import.meta.dirname, "..", "schema", "items.schema.json"),
441
444
  archiveDir: resolve2(dataDir, "archive"),
442
- sessionFile: resolve2(dataDir, "session.json"),
443
- sessionsLogFile: resolve2(dataDir, "sessions.jsonl"),
444
445
  pullsFile: resolve2(dataDir, "prs.json"),
445
446
  calendarFile: resolve2(dataDir, "calendar.json"),
446
447
  ticketsFile: resolve2(dataDir, "tickets.json"),
447
448
  timeZoneFile: resolve2(dataDir, "timezone.json"),
448
- // The same 1 to 120 the session endpoint holds a start to.
449
- sessionMinutes: envBounded("DAILY_FOCUS_SESSION_MINUTES", 25, 1, 120, env),
450
- awayAfterMinutes: envBounded("DAILY_FOCUS_AWAY_AFTER", profile === "personal" ? 0 : 10, 0, 24 * 60, env),
451
449
  port: envBounded("DAILY_FOCUS_PORT", 4321, 0, 65535, env),
452
450
  host: envString("DAILY_FOCUS_HOST", "127.0.0.1", env),
453
451
  freeWindows: envFlag("DAILY_FOCUS_FREE_WINDOWS", profile !== "personal", env),
@@ -464,12 +462,16 @@ function loadConfig(env = loadEnv()) {
464
462
  assistantPromptFile: resolve2(dataDir, "assistant.md"),
465
463
  assistantPromptSource: resolve2(import.meta.dirname, "..", "prompts", "assistant.md"),
466
464
  agent: envAgent(env),
467
- agentLogFile: resolve2(dataDir, "agent.jsonl")
465
+ agentLogFile: resolve2(dataDir, "agent.jsonl"),
466
+ onboardingFile: resolve2(dataDir, "onboarding.json"),
467
+ onboardingDir: resolve2(dataDir, "onboarding"),
468
+ onboardingPromptSource: resolve2(import.meta.dirname, "..", "prompts", "onboarding.md")
468
469
  };
469
470
  }
470
471
 
471
472
  export {
472
473
  LAUNCH_SETTINGS,
474
+ expandHome,
473
475
  readDotEnv,
474
476
  envSources,
475
477
  layerEnv,