daily-focus 1.2.0-dev.11 → 1.2.0-dev.12

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/SETUP.md CHANGED
@@ -613,6 +613,7 @@ matters when `DAILY_FOCUS_FREE_WINDOWS` is off.
613
613
  | `DAILY_FOCUS_AGENT_BIN` | *the CLI's name* | Path to that CLI, for when the server's PATH lacks it. `~` is expanded |
614
614
  | `DAILY_FOCUS_AGENT_MODEL` | *the CLI's own* | Model passed to the CLI untouched. Unset passes no flag |
615
615
  | `DAILY_FOCUS_AGENT_EFFORT` | *the CLI's own* | Effort passed to the CLI untouched. Unset passes no flag |
616
+ | `DAILY_FOCUS_AGENT_SEARCH_TRASH` | `off` | Whether the agent searches the mail account's Trash as well as the inbox and archive. The dashboard writes it to `agent-settings.json` in the store before each run, where the agent reads it |
616
617
  | `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 |
617
618
 
618
619
  ## If something looks wrong
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  readSystemZone,
3
3
  startingZone
4
- } from "./chunk-GVLNDQVQ.js";
4
+ } from "./chunk-HEP46XRX.js";
5
5
  import {
6
6
  linkState
7
7
  } from "./chunk-QKT2FAB5.js";
@@ -13,7 +13,7 @@ import {
13
13
  resolveItems,
14
14
  runContractChecks,
15
15
  setsStatus
16
- } from "./chunk-CPJ6LOVC.js";
16
+ } from "./chunk-D3JAWEF7.js";
17
17
  import {
18
18
  BRIEF_REFRESH_GRACE_HOURS,
19
19
  describeSchedule,
@@ -23,7 +23,7 @@ import {
23
23
  resolveSchedule,
24
24
  runsOn,
25
25
  workingMsBetween
26
- } from "./chunk-4DZEBUPU.js";
26
+ } from "./chunk-DPMHC72S.js";
27
27
  import {
28
28
  command
29
29
  } from "./chunk-BC2W7NND.js";
@@ -14,7 +14,7 @@ import {
14
14
  startOfLocalDay,
15
15
  workingDaysSince,
16
16
  workingMsBetween
17
- } from "./chunk-4DZEBUPU.js";
17
+ } from "./chunk-DPMHC72S.js";
18
18
 
19
19
  // src/ids.ts
20
20
  function canonicalId(id) {
@@ -387,7 +387,8 @@ function envAgent(env) {
387
387
  binPath: expandHome((env.DAILY_FOCUS_AGENT_BIN ?? "").trim() || (cli ?? "codex")),
388
388
  model: envString("DAILY_FOCUS_AGENT_MODEL", "", env) || null,
389
389
  effort: envString("DAILY_FOCUS_AGENT_EFFORT", "", env) || null,
390
- tools: tools.length > 0 ? tools : DEFAULT_AGENT_TOOLS
390
+ tools: tools.length > 0 ? tools : DEFAULT_AGENT_TOOLS,
391
+ searchTrash: envFlag("DAILY_FOCUS_AGENT_SEARCH_TRASH", false, env)
391
392
  };
392
393
  }
393
394
  function envTimeOfDay(name, env) {
@@ -463,6 +464,7 @@ function loadConfig(env = loadEnv()) {
463
464
  assistantPromptSource: resolve2(import.meta.dirname, "..", "prompts", "assistant.md"),
464
465
  agent: envAgent(env),
465
466
  agentLogFile: resolve2(dataDir, "agent.jsonl"),
467
+ agentSettingsFile: resolve2(dataDir, "agent-settings.json"),
466
468
  onboardingFile: resolve2(dataDir, "onboarding.json"),
467
469
  onboardingDir: resolve2(dataDir, "onboarding"),
468
470
  onboardingPromptSource: resolve2(import.meta.dirname, "..", "prompts", "onboarding.md")
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  canonicalId,
3
3
  foldActionLog
4
- } from "./chunk-CPJ6LOVC.js";
4
+ } from "./chunk-D3JAWEF7.js";
5
5
  import {
6
6
  laterISO,
7
7
  localDateKey,
8
8
  parseISO
9
- } from "./chunk-4DZEBUPU.js";
9
+ } from "./chunk-DPMHC72S.js";
10
10
 
11
11
  // src/codex.ts
12
12
  import { execFile } from "node:child_process";
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  writeJsonAtomic
3
- } from "./chunk-CPJ6LOVC.js";
3
+ } from "./chunk-D3JAWEF7.js";
4
4
  import {
5
5
  localTimeZone
6
- } from "./chunk-4DZEBUPU.js";
6
+ } from "./chunk-DPMHC72S.js";
7
7
 
8
8
  // src/zone.ts
9
9
  import { readFile, readlink } from "node:fs/promises";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  localDateKey
3
- } from "./chunk-4DZEBUPU.js";
3
+ } from "./chunk-DPMHC72S.js";
4
4
 
5
5
  // src/sample.ts
6
6
  function timeOn(now, hour, minute = 0) {
package/dist/cli.js CHANGED
@@ -49,7 +49,7 @@ function shouldOpen(flag) {
49
49
  return flag && process.stdout.isTTY === true && !process.env.CI;
50
50
  }
51
51
  async function demo(open, profile) {
52
- const { demoEnv, demoIntegrations, demoProfile, writeDemoStore } = await import("./demo-UMGG3VKY.js");
52
+ const { demoEnv, demoIntegrations, demoProfile, writeDemoStore } = await import("./demo-UKILSZYF.js");
53
53
  const chosen = demoProfile(profile);
54
54
  const store = await mkdtemp(join(tmpdir(), "daily-focus-demo-"));
55
55
  process.on("exit", () => rmSync(store, { recursive: true, force: true }));
@@ -66,7 +66,7 @@ async function demo(open, profile) {
66
66
  );
67
67
  }
68
68
  async function start(open, onStarted, options = {}) {
69
- const { runServer } = await import("./server-EDPYEZCP.js");
69
+ const { runServer } = await import("./server-RKEB6FDK.js");
70
70
  await runServer({
71
71
  ...options,
72
72
  onStarted: (url) => {
@@ -163,20 +163,20 @@ async function main(argv) {
163
163
  }
164
164
  return start(open);
165
165
  case "service": {
166
- const { main: service } = await import("./service-XPFMYIHR.js");
166
+ const { main: service } = await import("./service-RRHZ7BJN.js");
167
167
  process.exitCode = await service(values.remove ? ["--remove"] : []);
168
168
  return;
169
169
  }
170
170
  // These three are scripts that do their work as they load, and read their
171
171
  // own flags from the command line.
172
172
  case "init":
173
- await import("./init-MFPXASX3.js");
173
+ await import("./init-BZSCAS3L.js");
174
174
  return;
175
175
  case "audit":
176
- await import("./audit-F26VGPOO.js");
176
+ await import("./audit-JVDLHD3B.js");
177
177
  return;
178
178
  case "seed":
179
- await import("./seed-S32JX5MW.js");
179
+ await import("./seed-WQEXDK2L.js");
180
180
  return;
181
181
  case "build-calendar":
182
182
  return buildCalendar();
@@ -3,17 +3,17 @@ import {
3
3
  actionOf,
4
4
  autoKeys,
5
5
  judge
6
- } from "./chunk-EV44BC2F.js";
6
+ } from "./chunk-FPBY3TAW.js";
7
7
  import {
8
8
  dateFromNow,
9
9
  sampleBrief,
10
10
  sampleGeneratedAt
11
- } from "./chunk-HVCCIZGA.js";
12
- import "./chunk-CPJ6LOVC.js";
11
+ } from "./chunk-TUZHZ3NP.js";
12
+ import "./chunk-D3JAWEF7.js";
13
13
  import {
14
14
  PROFILES,
15
15
  localDateKey
16
- } from "./chunk-4DZEBUPU.js";
16
+ } from "./chunk-DPMHC72S.js";
17
17
  import "./chunk-BC2W7NND.js";
18
18
 
19
19
  // src/demo.ts
@@ -8,7 +8,7 @@ import {
8
8
  } from "./chunk-QKT2FAB5.js";
9
9
  import {
10
10
  loadConfig
11
- } from "./chunk-4DZEBUPU.js";
11
+ } from "./chunk-DPMHC72S.js";
12
12
  import {
13
13
  PACKAGED,
14
14
  command
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  sampleBrief
3
- } from "./chunk-HVCCIZGA.js";
3
+ } from "./chunk-TUZHZ3NP.js";
4
4
  import {
5
5
  Store
6
- } from "./chunk-CPJ6LOVC.js";
6
+ } from "./chunk-D3JAWEF7.js";
7
7
  import {
8
8
  loadConfig
9
- } from "./chunk-4DZEBUPU.js";
9
+ } from "./chunk-DPMHC72S.js";
10
10
  import {
11
11
  command
12
12
  } from "./chunk-BC2W7NND.js";
@@ -9,7 +9,7 @@ import {
9
9
  countBoard,
10
10
  refusalFor,
11
11
  resolveBoard
12
- } from "./chunk-EV44BC2F.js";
12
+ } from "./chunk-FPBY3TAW.js";
13
13
  import {
14
14
  FOCUS_TEMPLATE,
15
15
  sourcesTemplate
@@ -17,7 +17,7 @@ import {
17
17
  import {
18
18
  TimeZoneKeeper,
19
19
  validZone
20
- } from "./chunk-GVLNDQVQ.js";
20
+ } from "./chunk-HEP46XRX.js";
21
21
  import {
22
22
  describeLink,
23
23
  linkStore,
@@ -30,7 +30,7 @@ import {
30
30
  foldActionLog,
31
31
  tempPathFor,
32
32
  writeJsonAtomic
33
- } from "./chunk-CPJ6LOVC.js";
33
+ } from "./chunk-D3JAWEF7.js";
34
34
  import {
35
35
  CLI_NAMES,
36
36
  LAUNCH_SETTINGS,
@@ -46,7 +46,7 @@ import {
46
46
  readDotEnv,
47
47
  resolveSchedule,
48
48
  scheduledRunDue
49
- } from "./chunk-4DZEBUPU.js";
49
+ } from "./chunk-DPMHC72S.js";
50
50
  import {
51
51
  PACKAGED,
52
52
  command,
@@ -2749,6 +2749,11 @@ function agentPrompt(promptPath) {
2749
2749
  "Finish by reporting back as that file asks you to."
2750
2750
  ].join("\n");
2751
2751
  }
2752
+ function agentSettings(config) {
2753
+ return {
2754
+ searchTrash: config.agent.searchTrash
2755
+ };
2756
+ }
2752
2757
  function followUpPrompt(question) {
2753
2758
  return [
2754
2759
  "A follow-up question about the brief you wrote in this session. Answer it here.",
@@ -2968,6 +2973,12 @@ var AgentRunner = class {
2968
2973
  };
2969
2974
  this.runs.push(run5);
2970
2975
  await this.append({ event: "started", run: run5.id, cli: cli2, trigger, at: run5.startedAt });
2976
+ try {
2977
+ await writeJsonAtomic(this.config.agentSettingsFile, agentSettings(this.config));
2978
+ } catch (err) {
2979
+ await this.finish(run5, null, { ok: false, error: `could not write ${displayPath(this.config.agentSettingsFile)}: ${err.message}` });
2980
+ return run5;
2981
+ }
2971
2982
  const adapter = ADAPTERS[cli2];
2972
2983
  const args = adapter.args({
2973
2984
  prompt: agentPrompt(displayPath(this.config.promptFile)),
@@ -3871,6 +3882,14 @@ var SETTINGS = [
3871
3882
  choices: EFFORTS,
3872
3883
  fallback: always("The CLI's own")
3873
3884
  },
3885
+ {
3886
+ key: "DAILY_FOCUS_AGENT_SEARCH_TRASH",
3887
+ group: "agent",
3888
+ label: "Search deleted mail",
3889
+ help: "Lets the agent look in your mail\u2019s Trash as well as the inbox and archive. Off, it leaves out what you deleted.",
3890
+ kind: "flag",
3891
+ fallback: always("Off")
3892
+ },
3874
3893
  {
3875
3894
  key: "DAILY_FOCUS_AGENT_TOOLS",
3876
3895
  group: "agent",
@@ -5373,6 +5392,9 @@ data: ${payload}
5373
5392
  // Appended by this process, which broadcasts on its own.
5374
5393
  basename(config.assistantLogFile),
5375
5394
  basename(config.agentLogFile),
5395
+ // Rewritten by the runner before every run; nothing on the page shows it.
5396
+ basename(config.agentSettingsFile),
5397
+ basename(tempPathFor(config.agentSettingsFile)),
5376
5398
  // Rewritten by the setup screen, which broadcasts on its own.
5377
5399
  basename(config.onboardingFile),
5378
5400
  basename(tempPathFor(config.onboardingFile))
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  loadConfig
3
- } from "./chunk-4DZEBUPU.js";
3
+ } from "./chunk-DPMHC72S.js";
4
4
  import {
5
5
  IN_NPX_CACHE,
6
6
  PACKAGED,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "daily-focus",
3
- "version": "1.2.0-dev.11",
3
+ "version": "1.2.0-dev.12",
4
4
  "description": "An interactive dashboard of what you should focus on today at work",
5
5
  "keywords": [
6
6
  "dashboard",
package/prompts/README.md CHANGED
@@ -36,6 +36,7 @@ alongside `items.schema.json`, so a run only ever names a path inside the store:
36
36
  focus.md you write it, on the setup screen, in the dashboard or by hand
37
37
  sources.md you write it, on the setup screen, in the dashboard or by hand
38
38
  settings.json the dashboard writes: what you set on its settings page
39
+ agent-settings.json the dashboard writes before every run: the settings the agent reads
39
40
  items.json the agent writes it
40
41
  actions.jsonl the dashboard appends
41
42
  agent.jsonl the dashboard appends: every run, its report, and the questions asked of it
@@ -71,6 +72,12 @@ it. Nothing else is handed over: no extra instructions, no checkout, no copy of
71
72
  prompt. Everything that evolves lives in the prompt, in git, where a change to it is
72
73
  reviewable, and the wrapper should never need editing.
73
74
 
75
+ A setting that changes how the agent gathers, such as searching deleted mail, reaches
76
+ it the same way everything else does: through the store. Before each run the dashboard
77
+ writes `agent-settings.json` with the values it is running with, whether they were
78
+ saved on the settings page or set in `.env`, and both prompts say what each key means.
79
+ The wrapper stays the same whatever the settings are.
80
+
74
81
  Which days it runs is `DAILY_FOCUS_AGENT_DAYS` — cron-numbered, so `1-5` is Mon–Fri
75
82
  and `0-4` is the Sun–Thu week — and Mon–Fri when unset. The same schedule drives the
76
83
  staleness banner, which turns red once the brief is more than 24 *working* hours old,
@@ -24,6 +24,10 @@ not for you.
24
24
  gather and how to judge it; that file says *who* and *where*.
25
25
  - `items.schema.json` — **you only ever read this.** The machine-readable shape of
26
26
  `items.json`. Validate against it in step 5 if you can.
27
+ - `agent-settings.json` — **you only ever read this.** The choices the user made on
28
+ the dashboard's settings page about how you gather, rewritten by the dashboard
29
+ before every run. Each key is explained where it applies below; a missing file or
30
+ key means that key's default.
27
31
  - `prs.json` — **you only ever read this.** The dashboard's own cache of the pull
28
32
  requests the user has open, refreshed while the dashboard is in use. Facts only —
29
33
  reviews, checks, who last acted — with no judgement attached; use it if it helps,
@@ -148,6 +152,12 @@ and anything filters moved out of the inbox, included. Mail the user filed is no
148
152
  mail they finished with. **Do not limit the search to unread mail**: the things that
149
153
  rot are the ones the user opened, meant to deal with, and didn't.
150
154
 
155
+ Mail the user deleted is mail they finished with, so leave Trash out unless
156
+ `searchTrash` in `agent-settings.json` is `true` (default `false`). A search with no
157
+ `in:` operator already covers archived mail and skips Trash and Spam; when the
158
+ setting is off, don't widen it with `in:anywhere` or a trash option. When it is on,
159
+ search Trash as well, and still never Spam.
160
+
151
161
  **On a first run, search the last 90 days.** The point of that run is to find what
152
162
  fell through the cracks: a reply the user owes, a bill, a form, a booking to confirm,
153
163
  a promise they made in a thread. Afterwards, use the normal window from step 1.
@@ -22,6 +22,10 @@ not for you.
22
22
  how to judge it; that file says *who* and *where*.
23
23
  - `items.schema.json` — **you only ever read this.** The machine-readable shape of
24
24
  `items.json`. Validate against it in step 5 if you can.
25
+ - `agent-settings.json` — **you only ever read this.** The choices the user made on
26
+ the dashboard's settings page about how you gather, rewritten by the dashboard
27
+ before every run. Each key is explained where it applies below; a missing file or
28
+ key means that key's default.
25
29
 
26
30
  There is also an `archive/` directory of dated past briefs. The dashboard maintains
27
31
  it; you never write to it. Read it if you want history — it is how the dashboard
@@ -167,6 +171,12 @@ the user's filters moved out of the inbox, included. Mail they filed is not mail
167
171
  finished with, and a label records how they sorted something, not whether they dealt
168
172
  with it.
169
173
 
174
+ Mail the user deleted is mail they finished with, so leave Trash out unless
175
+ `searchTrash` in `agent-settings.json` is `true` (default `false`). A search with no
176
+ `in:` operator already covers archived mail and skips Trash and Spam; when the
177
+ setting is off, don't widen it with `in:anywhere` or a trash option. When it is on,
178
+ search Trash as well, and still never Spam.
179
+
170
180
  Prioritise direct requests, deadlines, decisions, travel and logistics,
171
181
  finance/legal/security, and anyone plausibly waiting on a reply. **Do not limit
172
182
  continuity-sensitive searches to unread mail** — the things that rot are usually the