daily-focus 0.2.0-dev.13 → 0.2.0-dev.14

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.
@@ -8,7 +8,7 @@ import {
8
8
  readArchiveIndex,
9
9
  resolveItems,
10
10
  runContractChecks
11
- } from "./chunk-ISUDD7OB.js";
11
+ } from "./chunk-NAD6PRZT.js";
12
12
  import {
13
13
  BRIEF_REFRESH_GRACE_HOURS,
14
14
  describeSchedule,
@@ -17,13 +17,13 @@ import {
17
17
  nextRunDate,
18
18
  resolveSchedule,
19
19
  runsOn
20
- } from "./chunk-Z57EHQZV.js";
20
+ } from "./chunk-IFAGJFOT.js";
21
21
  import {
22
22
  command
23
23
  } from "./chunk-BC2W7NND.js";
24
24
  import {
25
25
  workingMsBetween
26
- } from "./chunk-EXGTFXNV.js";
26
+ } from "./chunk-K2VT4JBR.js";
27
27
 
28
28
  // scripts/audit.ts
29
29
  import { readFile, readdir } from "node:fs/promises";
@@ -7,7 +7,7 @@ import {
7
7
  localDateKey,
8
8
  parseISO,
9
9
  startOfLocalDay
10
- } from "./chunk-EXGTFXNV.js";
10
+ } from "./chunk-K2VT4JBR.js";
11
11
 
12
12
  // src/env.ts
13
13
  import { readFileSync } from "node:fs";
@@ -1,5 +1,8 @@
1
1
  // src/time.ts
2
2
  var MS_PER_DAY = 864e5;
3
+ function localTimeZone() {
4
+ return Intl.DateTimeFormat().resolvedOptions().timeZone;
5
+ }
3
6
  function localDateKey(d) {
4
7
  const y = d.getFullYear();
5
8
  const m = String(d.getMonth() + 1).padStart(2, "0");
@@ -64,6 +67,7 @@ function laterISO(a, b) {
64
67
  }
65
68
 
66
69
  export {
70
+ localTimeZone,
67
71
  localDateKey,
68
72
  isDateOnly,
69
73
  parseISO,
@@ -4,18 +4,19 @@ import {
4
4
  nextRunDate,
5
5
  resolveSchedule,
6
6
  runsOn
7
- } from "./chunk-Z57EHQZV.js";
7
+ } from "./chunk-IFAGJFOT.js";
8
8
  import {
9
9
  calendarDaysBetween,
10
10
  isDateOnly,
11
11
  isSameLocalDay,
12
12
  isWorkingDay,
13
13
  localDateKey,
14
+ localTimeZone,
14
15
  parseISO,
15
16
  startOfLocalDay,
16
17
  workingDaysSince,
17
18
  workingMsBetween
18
- } from "./chunk-EXGTFXNV.js";
19
+ } from "./chunk-K2VT4JBR.js";
19
20
 
20
21
  // src/fs.ts
21
22
  import { mkdir, rename, writeFile } from "node:fs/promises";
@@ -913,7 +914,8 @@ var Store = class {
913
914
  // Parser complaints and contract failures render the same way: both are
914
915
  // things the agent got wrong that you would not otherwise see.
915
916
  warnings: [...warnings, ...contractIssues],
916
- now: now.toISOString()
917
+ now: now.toISOString(),
918
+ timeZone: localTimeZone()
917
919
  };
918
920
  }
919
921
  };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  localDateKey
3
- } from "./chunk-EXGTFXNV.js";
3
+ } from "./chunk-K2VT4JBR.js";
4
4
 
5
5
  // src/sample.ts
6
6
  function sampleBrief(now = /* @__PURE__ */ new Date()) {
package/dist/cli.js CHANGED
@@ -62,7 +62,7 @@ async function demo(open) {
62
62
  DAILY_FOCUS_JIRA: "off",
63
63
  DAILY_FOCUS_CALENDAR: "off"
64
64
  });
65
- const { sampleBrief } = await import("./sample-M7WNKQOV.js");
65
+ const { sampleBrief } = await import("./sample-QDEXFFRY.js");
66
66
  await writeFile(join(store, "items.json"), `${JSON.stringify(sampleBrief(), null, 2)}
67
67
  `);
68
68
  await start(open, (url) => {
@@ -72,7 +72,7 @@ async function demo(open) {
72
72
  });
73
73
  }
74
74
  async function start(open, onStarted) {
75
- const { runServer } = await import("./server-UIZFO5EF.js");
75
+ const { runServer } = await import("./server-ANIS2MXU.js");
76
76
  await runServer({
77
77
  onStarted: (url) => {
78
78
  onStarted?.(url);
@@ -168,20 +168,20 @@ async function main(argv) {
168
168
  }
169
169
  return start(open);
170
170
  case "service": {
171
- const { main: service } = await import("./service-YVGOLKYX.js");
171
+ const { main: service } = await import("./service-NEQVCWI5.js");
172
172
  process.exitCode = await service(values.remove ? ["--remove"] : []);
173
173
  return;
174
174
  }
175
175
  // These three are scripts that do their work as they load, and read their
176
176
  // own flags from the command line.
177
177
  case "init":
178
- await import("./init-YTIXVWOB.js");
178
+ await import("./init-BMFPWMXL.js");
179
179
  return;
180
180
  case "audit":
181
- await import("./audit-JEJRPW7R.js");
181
+ await import("./audit-DTXVAT5Z.js");
182
182
  return;
183
183
  case "seed":
184
- await import("./seed-C2BLE6P2.js");
184
+ await import("./seed-GCT7Z3IV.js");
185
185
  return;
186
186
  case "build-calendar":
187
187
  return buildCalendar();
@@ -8,12 +8,12 @@ import {
8
8
  } from "./chunk-QKT2FAB5.js";
9
9
  import {
10
10
  loadConfig
11
- } from "./chunk-Z57EHQZV.js";
11
+ } from "./chunk-IFAGJFOT.js";
12
12
  import {
13
13
  PACKAGED,
14
14
  command
15
15
  } from "./chunk-BC2W7NND.js";
16
- import "./chunk-EXGTFXNV.js";
16
+ import "./chunk-K2VT4JBR.js";
17
17
 
18
18
  // scripts/init.ts
19
19
  import { mkdir, writeFile } from "node:fs/promises";
@@ -0,0 +1,7 @@
1
+ import {
2
+ sampleBrief
3
+ } from "./chunk-UAR65OCG.js";
4
+ import "./chunk-K2VT4JBR.js";
5
+ export {
6
+ sampleBrief
7
+ };
@@ -1,16 +1,16 @@
1
1
  import {
2
2
  sampleBrief
3
- } from "./chunk-NDWZUZJE.js";
3
+ } from "./chunk-UAR65OCG.js";
4
4
  import {
5
5
  Store
6
- } from "./chunk-ISUDD7OB.js";
6
+ } from "./chunk-NAD6PRZT.js";
7
7
  import {
8
8
  loadConfig
9
- } from "./chunk-Z57EHQZV.js";
9
+ } from "./chunk-IFAGJFOT.js";
10
10
  import {
11
11
  command
12
12
  } from "./chunk-BC2W7NND.js";
13
- import "./chunk-EXGTFXNV.js";
13
+ import "./chunk-K2VT4JBR.js";
14
14
 
15
15
  // scripts/seed.ts
16
16
  import { writeFile } from "node:fs/promises";
@@ -16,7 +16,7 @@ import {
16
16
  stopSession,
17
17
  tempPathFor,
18
18
  writeJsonAtomic
19
- } from "./chunk-ISUDD7OB.js";
19
+ } from "./chunk-NAD6PRZT.js";
20
20
  import {
21
21
  CLI_NAMES,
22
22
  LAUNCH_SETTINGS,
@@ -30,7 +30,7 @@ import {
30
30
  readDotEnv,
31
31
  resolveSchedule,
32
32
  scheduledRunDue
33
- } from "./chunk-Z57EHQZV.js";
33
+ } from "./chunk-IFAGJFOT.js";
34
34
  import {
35
35
  PACKAGED,
36
36
  command,
@@ -40,7 +40,7 @@ import {
40
40
  import {
41
41
  laterISO,
42
42
  parseISO
43
- } from "./chunk-EXGTFXNV.js";
43
+ } from "./chunk-K2VT4JBR.js";
44
44
 
45
45
  // src/server.ts
46
46
  import { createServer } from "node:http";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  loadConfig
3
- } from "./chunk-Z57EHQZV.js";
3
+ } from "./chunk-IFAGJFOT.js";
4
4
  import {
5
5
  IN_NPX_CACHE,
6
6
  PACKAGED,
@@ -8,7 +8,7 @@ import {
8
8
  command,
9
9
  ranDirectly
10
10
  } from "./chunk-BC2W7NND.js";
11
- import "./chunk-EXGTFXNV.js";
11
+ import "./chunk-K2VT4JBR.js";
12
12
 
13
13
  // scripts/service.ts
14
14
  import { execFile } from "node:child_process";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "daily-focus",
3
- "version": "0.2.0-dev.13",
3
+ "version": "0.2.0-dev.14",
4
4
  "description": "An interactive dashboard of what you should focus on today at work",
5
5
  "keywords": [
6
6
  "dashboard",
package/public/app.js CHANGED
@@ -1321,12 +1321,49 @@ function formatWeekday(value) {
1321
1321
  const d4 = parseDate(value);
1322
1322
  return d4 ? weekdayFmt.format(d4) : "";
1323
1323
  }
1324
- function localDateKey(d4) {
1324
+ var dayKeyFmt = null;
1325
+ var calendarZone;
1326
+ function setCalendarZone(timeZone) {
1327
+ if (timeZone === calendarZone) return;
1328
+ calendarZone = timeZone;
1329
+ try {
1330
+ dayKeyFmt = timeZone ? new Intl.DateTimeFormat("en-US", { timeZone, year: "numeric", month: "2-digit", day: "2-digit" }) : null;
1331
+ } catch {
1332
+ dayKeyFmt = null;
1333
+ }
1334
+ }
1335
+ function dayKey(d4) {
1336
+ if (dayKeyFmt) {
1337
+ const parts = dayKeyFmt.formatToParts(d4);
1338
+ const part = (type) => parts.find((p5) => p5.type === type)?.value ?? "";
1339
+ return `${part("year")}-${part("month")}-${part("day")}`;
1340
+ }
1325
1341
  const m4 = String(d4.getMonth() + 1).padStart(2, "0");
1326
1342
  const day = String(d4.getDate()).padStart(2, "0");
1327
1343
  return `${d4.getFullYear()}-${m4}-${day}`;
1328
1344
  }
1345
+ function splitKey(key) {
1346
+ const [y4, m4, d4] = key.split("-").map(Number);
1347
+ return [y4, m4 - 1, d4];
1348
+ }
1349
+ function keyAt(ms) {
1350
+ return new Date(ms).toISOString().slice(0, 10);
1351
+ }
1352
+ function addDays(key, days) {
1353
+ const [y4, m4, d4] = splitKey(key);
1354
+ return keyAt(Date.UTC(y4, m4, d4 + days));
1355
+ }
1356
+ function addMonths(key, months) {
1357
+ const [y4, m4, d4] = splitKey(key);
1358
+ const lastDay = new Date(Date.UTC(y4, m4 + months + 1, 0)).getUTCDate();
1359
+ return keyAt(Date.UTC(y4, m4 + months, Math.min(d4, lastDay)));
1360
+ }
1329
1361
  function daysFromToday(value, now = /* @__PURE__ */ new Date()) {
1362
+ if (typeof value === "string" && /^\d{4}-\d{2}-\d{2}$/.test(value)) {
1363
+ const [y4, m4, d4] = splitKey(value);
1364
+ const [ty, tm, td] = splitKey(dayKey(now));
1365
+ return Math.round((Date.UTC(y4, m4, d4) - Date.UTC(ty, tm, td)) / 864e5);
1366
+ }
1330
1367
  const target = parseDate(value);
1331
1368
  if (!target) return null;
1332
1369
  const a4 = new Date(now.getFullYear(), now.getMonth(), now.getDate()).getTime();
@@ -2343,7 +2380,7 @@ function renderBanners(state2, ui2, handlers2) {
2343
2380
  )
2344
2381
  );
2345
2382
  }
2346
- if (!running && agent?.last && agent.last.status !== "done" && agent.last.id !== ui2.agentReportSeen.value && localDateKey(parseDate(agent.last.startedAt) ?? /* @__PURE__ */ new Date(0)) === localDateKey(new Date(state2.now))) {
2383
+ if (!running && agent?.last && agent.last.status !== "done" && agent.last.id !== ui2.agentReportSeen.value && dayKey(parseDate(agent.last.startedAt) ?? /* @__PURE__ */ new Date(0)) === dayKey(new Date(state2.now))) {
2347
2384
  banners.push(agentRunBanner(agent.last, state2, handlers2));
2348
2385
  }
2349
2386
  for (const warning of state2.setupWarnings ?? []) {
@@ -2403,8 +2440,8 @@ function agentRunBanner(run, state2, handlers2) {
2403
2440
  }
2404
2441
  function isHeldOverDayOff(state2) {
2405
2442
  if (state2.brief.generatedAt === null || state2.schedule.runsToday) return false;
2406
- const today = localDateKey(new Date(state2.now));
2407
- const briefDate = state2.brief.date ?? localDateKey(parseDate(state2.brief.generatedAt) ?? new Date(state2.now));
2443
+ const today = dayKey(new Date(state2.now));
2444
+ const briefDate = state2.brief.date ?? dayKey(parseDate(state2.brief.generatedAt) ?? new Date(state2.now));
2408
2445
  return briefDate !== today;
2409
2446
  }
2410
2447
  function nextRunPhraseFor(agent) {
@@ -2669,13 +2706,14 @@ function renderActions(item, state2, ui2, handlers2) {
2669
2706
  return el("div", { class: "item__actions" }, buttons);
2670
2707
  }
2671
2708
  function renderSnoozeMenu(item, now, handlers2, { indefinite = true, longRange = false } = {}) {
2709
+ const today = dayKey(now);
2672
2710
  const presets = [
2673
- ["Tomorrow", addDays(now, 1), false],
2674
- ["In 3 days", addDays(now, 3), false],
2675
- ["Next week", addDays(now, 7), false]
2711
+ ["Tomorrow", addDays(today, 1), false],
2712
+ ["In 3 days", addDays(today, 3), false],
2713
+ ["Next week", addDays(today, 7), false]
2676
2714
  ];
2677
2715
  if (longRange) {
2678
- presets.push(["Next month", addMonths(now, 1), true], ["Next quarter", addMonths(now, 3), true]);
2716
+ presets.push(["Next month", addMonths(today, 1), true], ["Next quarter", addMonths(today, 3), true]);
2679
2717
  }
2680
2718
  let dateInput = null;
2681
2719
  return k(
@@ -2737,15 +2775,6 @@ function Menu({ class: className, children }) {
2737
2775
  });
2738
2776
  return el("div", { class: className, role: "menu", popover: "manual", ref }, children);
2739
2777
  }
2740
- function addDays(from, days) {
2741
- return localDateKey(new Date(from.getFullYear(), from.getMonth(), from.getDate() + days));
2742
- }
2743
- function addMonths(from, months) {
2744
- const target = new Date(from.getFullYear(), from.getMonth() + months, 1);
2745
- const lastDay = new Date(target.getFullYear(), target.getMonth() + 1, 0).getDate();
2746
- target.setDate(Math.min(from.getDate(), lastDay));
2747
- return localDateKey(target);
2748
- }
2749
2778
 
2750
2779
  // client/refresh.ts
2751
2780
  function refreshControl({ source, fetchedAt, status, fetching, stale, action, onRefresh }) {
@@ -3522,8 +3551,8 @@ function Header({ state: state2, ui: ui2, handlers: handlers2 }) {
3522
3551
  );
3523
3552
  }
3524
3553
  function headerDate(state2) {
3525
- const now = new Date(state2.now);
3526
- return formatDay(state2.brief.date ?? state2.now) || formatDay(now.toISOString());
3554
+ const today = dayKey(new Date(state2.now));
3555
+ return formatDay(state2.brief.date ?? today) || formatDay(today);
3527
3556
  }
3528
3557
  function freshness(state2, handlers2) {
3529
3558
  let text;
@@ -4944,9 +4973,7 @@ function selectedItem() {
4944
4973
  return list.find((entry) => entry.id === id) ?? null;
4945
4974
  }
4946
4975
  function tomorrow() {
4947
- const d4 = /* @__PURE__ */ new Date();
4948
- d4.setDate(d4.getDate() + 1);
4949
- return localDateKey(d4);
4976
+ return addDays(dayKey(/* @__PURE__ */ new Date()), 1);
4950
4977
  }
4951
4978
  function installKeyboard(handlers2) {
4952
4979
  document.addEventListener("keydown", (event) => {
@@ -5070,6 +5097,7 @@ function installKeyboard(handlers2) {
5070
5097
 
5071
5098
  // client/main.ts
5072
5099
  ui.theme.value = stampedTheme();
5100
+ j3(() => setCalendarZone(state.value?.timeZone));
5073
5101
  var root = document.getElementById("app");
5074
5102
  if (!root) throw new Error("index.html has no #app to render into");
5075
5103
  R(k(App, { ui, handlers }), root);
@@ -1,7 +0,0 @@
1
- import {
2
- sampleBrief
3
- } from "./chunk-NDWZUZJE.js";
4
- import "./chunk-EXGTFXNV.js";
5
- export {
6
- sampleBrief
7
- };