daily-focus 1.2.0-dev.8 → 2.0.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.
@@ -1,15 +1,21 @@
1
1
  import {
2
- QUICK_ACTIONS
3
- } from "./chunk-SX5FPS3A.js";
2
+ QUICK_ACTIONS,
3
+ actionOf,
4
+ autoKeys,
5
+ judge
6
+ } from "./chunk-JTMBBUMD.js";
4
7
  import {
5
8
  dateFromNow,
6
9
  sampleBrief,
7
10
  sampleGeneratedAt
8
- } from "./chunk-P3E2B2SD.js";
11
+ } from "./chunk-WPXIQPYX.js";
12
+ import "./chunk-ITUK7XKS.js";
13
+ import "./chunk-QG4XXKBP.js";
9
14
  import {
10
15
  PROFILES,
16
+ SETTINGS_FILE,
11
17
  localDateKey
12
- } from "./chunk-KZNY45XW.js";
18
+ } from "./chunk-72NUDSOV.js";
13
19
  import "./chunk-BC2W7NND.js";
14
20
 
15
21
  // src/demo.ts
@@ -48,36 +54,23 @@ function demoProfile(raw) {
48
54
  }
49
55
  return chosen;
50
56
  }
51
- function demoEnv(base, store, profile) {
52
- const work = profile === "work";
57
+ function demoEnv(base, store) {
58
+ return { ...base, DAILY_FOCUS_DATA: store, DAILY_FOCUS_PORT: base.DAILY_FOCUS_PORT ?? "0" };
59
+ }
60
+ var DEMO_FIXED = {
61
+ DAILY_FOCUS_AGENT: "off",
62
+ DAILY_FOCUS_ASSISTANT: "off",
63
+ DAILY_FOCUS_CALENDAR: "off"
64
+ };
65
+ function demoSettings(profile) {
66
+ if (profile === "personal") return { DAILY_FOCUS_PROFILE: "personal" };
53
67
  return {
54
- ...base,
55
- DAILY_FOCUS_DATA: store,
56
- // Any free port unless one was asked for, so the demo never collides with a
57
- // dashboard already running on 4321.
58
- DAILY_FOCUS_PORT: base.DAILY_FOCUS_PORT ?? "0",
59
- DAILY_FOCUS_PROFILE: profile,
60
- DAILY_FOCUS_AGENT: "off",
61
- DAILY_FOCUS_AGENT_AT: "",
62
- DAILY_FOCUS_AGENT_DAYS: "",
63
- DAILY_FOCUS_ASSISTANT: "off",
64
- DAILY_FOCUS_CALENDAR: "off",
65
- DAILY_FOCUS_GITHUB: "on",
66
- DAILY_FOCUS_GITHUB_ACCOUNTS: "",
67
- DAILY_FOCUS_GITHUB_SCOPE: work ? "acme" : "",
68
- DAILY_FOCUS_GITHUB_MERGE_GATE_CHECKS: work ? "merge-policy" : "",
69
- DAILY_FOCUS_GITHUB_POLL_MINUTES: "",
70
- DAILY_FOCUS_JIRA: work ? "on" : "off",
71
- DAILY_FOCUS_JIRA_PROJECTS: work ? "PROJ, PLAT" : "",
72
- DAILY_FOCUS_JIRA_HOLD_STATUSES: work ? "Blocked" : "",
73
- DAILY_FOCUS_JIRA_IN_PROGRESS_STATUSES: work ? "In Progress, In Review" : "",
74
- DAILY_FOCUS_JIRA_SITE: "",
75
- DAILY_FOCUS_JIRA_POLL_MINUTES: "",
76
- DAILY_FOCUS_FREE_WINDOWS: "",
77
- DAILY_FOCUS_WORK_START: "",
78
- DAILY_FOCUS_WORK_END: "",
79
- DAILY_FOCUS_MIN_FREE_WINDOW: "",
80
- DAILY_FOCUS_STALE_AFTER_HOURS: ""
68
+ DAILY_FOCUS_PROFILE: "work",
69
+ DAILY_FOCUS_GITHUB_SCOPE: "acme",
70
+ DAILY_FOCUS_GITHUB_MERGE_GATE_CHECKS: "merge-policy",
71
+ DAILY_FOCUS_JIRA_PROJECTS: "PROJ, PLAT",
72
+ DAILY_FOCUS_JIRA_HOLD_STATUSES: "Blocked",
73
+ DAILY_FOCUS_JIRA_IN_PROGRESS_STATUSES: "In Progress, In Review"
81
74
  };
82
75
  }
83
76
  function pull(seed) {
@@ -118,6 +111,7 @@ function demoPulls(profile, now = /* @__PURE__ */ new Date()) {
118
111
  reviewDecision: "REVIEW_REQUIRED",
119
112
  checks: "failure",
120
113
  failingChecks: ["unit-tests (node-20)"],
114
+ headSha: "9c41e07d2b5f3a8e6d1c0b4a7f2e9d8c5b3a1f60",
121
115
  mergeStateStatus: "UNSTABLE",
122
116
  lastActivityByYou: hoursAgo(now, 3),
123
117
  requestedReviewers: ["eli"]
@@ -258,6 +252,7 @@ function personalPulls(now) {
258
252
  createdAt: daysAgo(now, 2),
259
253
  checks: "failure",
260
254
  failingChecks: ["build (macos)"],
255
+ headSha: "3e8a1c5f9b2d7e4a6c0f1b8d3e5a7c9f2b4d6e81",
261
256
  mergeStateStatus: "UNSTABLE",
262
257
  lastActivityByYou: hoursAgo(now, 15)
263
258
  }),
@@ -367,7 +362,7 @@ function demoTickets(now = /* @__PURE__ */ new Date()) {
367
362
  statuses: Object.fromEntries(Object.entries(TICKET_STATUSES).map(([project, names]) => [project, [...names]]))
368
363
  };
369
364
  }
370
- function demoIntegrations(profile) {
365
+ function demoIntegrations(profile, now = /* @__PURE__ */ new Date()) {
371
366
  const world = demoTickets();
372
367
  return {
373
368
  github: {
@@ -378,7 +373,7 @@ function demoIntegrations(profile) {
378
373
  return "demo";
379
374
  },
380
375
  async fetch() {
381
- return { login: LOGIN, pulls: demoPulls(profile, /* @__PURE__ */ new Date()), warnings: [], orgs: {}, rateLimitRemaining: null };
376
+ return { login: LOGIN, pulls: demoPulls(profile, now), warnings: [], orgs: {}, rateLimitRemaining: null };
382
377
  }
383
378
  },
384
379
  jira: {
@@ -613,7 +608,7 @@ function runLines(seed) {
613
608
  return lines2;
614
609
  }
615
610
  const report = seed.messages.at(-1) ?? "";
616
- lines2.push({ event: "finished", run: seed.id, sessionId: `sample-${seed.id}`, report, messages: seed.messages, at: endedAt });
611
+ lines2.push({ event: "finished", run: seed.id, sessionId: `sample-${seed.id}`, report, messages: seed.messages, steps: seed.steps ?? [], at: endedAt });
617
612
  if (seed.question) {
618
613
  const turn = `${seed.id}-q1`;
619
614
  const replied = new Date(new Date(seed.question.at).getTime() + 48e3).toISOString();
@@ -735,8 +730,77 @@ function demoAgentLog(profile, now) {
735
730
  }
736
731
  }
737
732
  ];
733
+ const newest = runs.find((run) => run.id === "run-0");
734
+ newest.steps = demoRunSteps(profile, newest.messages);
738
735
  return runs.flatMap(runLines);
739
736
  }
737
+ function demoRunSteps(profile, messages) {
738
+ const said2 = (text, by = null) => ({ kind: "message", text, detail: null, state: "done", by });
739
+ const call2 = (text, detail, by = null) => ({ kind: "tool", text, detail, state: "done", by });
740
+ const handoff = (name) => ({ ...call2("Hand part of it to a subagent", name), subagent: name });
741
+ const wait = call2("Wait for its subagents", null);
742
+ const start = [
743
+ said2(messages[0]),
744
+ call2("Run a command", "cat prompt.md focus.md sources.md items.json"),
745
+ call2("Run a command", "tail -n 400 actions.jsonl")
746
+ ];
747
+ const finish = [call2("Run a command", "mv items.json.tmp items.json"), said2(messages.at(-1))];
748
+ if (profile === "work") {
749
+ return [
750
+ ...start,
751
+ handoff("calendar"),
752
+ handoff("gmail"),
753
+ handoff("github"),
754
+ call2("Google calendar list events", '{"calendar_id":"primary","time_min":"today 00:00"}', "calendar"),
755
+ said2("5 events. The 1:1 with Alice and the design review both sit at 11:00; the lunch & learn is marked free.", "calendar"),
756
+ call2("Gmail search emails", '{"query":"newer_than:3d -category:promotions"}', "gmail"),
757
+ call2("Gmail batch read email", '{"message_ids":["19a2f\u2026","19a31\u2026","19a33\u2026","19a35\u2026"]}', "gmail"),
758
+ said2("31 threads in the window. 4 ask something of you; Bob followed up on Q4 headcount yesterday.", "gmail"),
759
+ call2("Run a command", "gh search prs --review-requested=@me --state=open --json url,title,updatedAt", "github"),
760
+ call2("Run a command", "gh pr checks 3402 -R acme/webapp", "github"),
761
+ said2("A review request from Alice on acme/webapp#3421, and a red check on #3402. The rest is already on the board.", "github"),
762
+ wait,
763
+ said2(messages[1]),
764
+ said2(messages[2]),
765
+ handoff("jira"),
766
+ handoff("slack"),
767
+ handoff("workday"),
768
+ call2("Run a command", 'acli jira workitem search --jql "assignee = currentUser() AND statusCategory != Done"', "jira"),
769
+ said2("PROJ-8842 is still open, with both of its pull requests merged.", "jira"),
770
+ call2("Slack search messages", '{"query":"to:me after:yesterday"}', "slack"),
771
+ said2("One direct question, from Chris in #webapp-dev.", "slack"),
772
+ call2("Workday list inbox tasks", null, "workday"),
773
+ said2("The compliance training is due tonight. The Berlin expense report is still a draft.", "workday"),
774
+ { ...wait },
775
+ said2(messages[3]),
776
+ ...finish
777
+ ];
778
+ }
779
+ return [
780
+ ...start,
781
+ handoff("calendar"),
782
+ handoff("eboks"),
783
+ handoff("email"),
784
+ call2("Google calendar list events", '{"calendar_id":"personal","time_min":"today 00:00"}', "calendar"),
785
+ call2("Google calendar list events", '{"calendar_id":"family","time_min":"today 00:00"}', "calendar"),
786
+ said2("6 events across Personal and Family. The insurance call at 16:30 overlaps the daycare pickup.", "calendar"),
787
+ call2("Run a command", "eboks list --since 3d --json", "eboks"),
788
+ call2("Run a command", "eboks text --json 4417911204", "eboks"),
789
+ said2("5 letters. The daycare invoice and the tax assessment ask for something; three are confirmations.", "eboks"),
790
+ call2("Gmail search emails", '{"query":"newer_than:3d -category:promotions"}', "email"),
791
+ said2("3 threads need you, the insulation quote among them, quiet for nine days.", "email"),
792
+ wait,
793
+ said2(messages[1]),
794
+ handoff("messages"),
795
+ call2("Run a command", "messages recent --since 3d --json", "messages"),
796
+ said2("Jonas asked about Saturday on Tuesday, and Priya is still waiting for the photos.", "messages"),
797
+ { ...wait },
798
+ said2(messages[2]),
799
+ ...finish
800
+ ];
801
+ }
802
+ var call = (text, detail, state = "done") => ({ kind: "tool", text, detail, state });
803
+ var said = (text) => ({ kind: "message", text, detail: null, state: "done" });
740
804
  function turnLines(seed) {
741
805
  const quick = seed.action ? QUICK_ACTIONS.find((candidate) => candidate.id === seed.action) : void 0;
742
806
  const request = quick ? seed.text ? `${quick.request}
@@ -744,10 +808,27 @@ function turnLines(seed) {
744
808
  ${seed.text}` : quick.request : seed.text ?? "";
745
809
  const endedAt = new Date(new Date(seed.at).getTime() + seed.seconds * 1e3).toISOString();
746
810
  return [
747
- { event: "started", turn: seed.id, item: seed.item, agent: "claude", request, action: quick?.id ?? null, at: seed.at },
748
- { event: "finished", turn: seed.id, sessionId: `sample-${seed.item}`, reply: seed.reply, at: endedAt }
811
+ {
812
+ event: "started",
813
+ turn: seed.id,
814
+ item: seed.item,
815
+ agent: "claude",
816
+ request,
817
+ action: quick?.id ?? null,
818
+ ...seed.auto ? { auto: seed.auto } : {},
819
+ at: seed.at
820
+ },
821
+ { event: "finished", turn: seed.id, sessionId: `sample-${seed.item}`, reply: seed.reply, steps: seed.steps, at: endedAt }
749
822
  ];
750
823
  }
824
+ function aheadKey(profile, now, id, action) {
825
+ const pr = demoPulls(profile, now).find((candidate) => candidate.id === id);
826
+ if (!pr) throw new Error(`the demo has no pull request ${id}`);
827
+ const row = { ...pr, ...judge(pr, now, null), status: "open", notes: [] };
828
+ const key = autoKeys(row).find((candidate) => actionOf(candidate) === action);
829
+ if (!key) throw new Error(`the demo's ${id} calls for no ${action} ahead`);
830
+ return key;
831
+ }
751
832
  function demoAssistantLog(profile, now) {
752
833
  const fence = "```";
753
834
  const turns = profile === "work" ? [
@@ -757,6 +838,12 @@ function demoAssistantLog(profile, now) {
757
838
  action: "summarise-pr",
758
839
  at: minutesAgo(now, 46),
759
840
  seconds: 52,
841
+ steps: [
842
+ call("View the pull request", "gh pr view 3421 --repo acme/webapp --json title,body,files,reviews"),
843
+ call("Read the diff", "gh pr diff 3421 --repo acme/webapp"),
844
+ said("Four files. The recorder change is the substance; the rest is its tests and a type."),
845
+ call("Read the issue it closes", "gh issue view 3388 --repo acme/webapp --comments")
846
+ ],
760
847
  reply: [
761
848
  "**What it changes.** Session replay keeps every recorded mutation batch in an array on the recorder for the life of the tab, and only ever appends; on a tab left open for a day that is hundreds of megabytes. The change caps the buffer per tab, drops batches once the ingest endpoint has acknowledged them, and holds DOM node references through a `WeakRef` so a detached subtree can be collected.",
762
849
  "",
@@ -778,6 +865,11 @@ function demoAssistantLog(profile, now) {
778
865
  text: "Is the Safari fallback actually reachable?",
779
866
  at: minutesAgo(now, 44),
780
867
  seconds: 31,
868
+ steps: [
869
+ call("Find where the fallback is chosen", 'gh search code "WeakRef" --repo acme/webapp'),
870
+ call("Read the SDK docs on browser support", "gh api repos/acme/sdk-docs/contents/support.md", "failed"),
871
+ call("Read the webapp's copy of the support matrix", "gh api repos/acme/webapp/contents/docs/browser-support.md")
872
+ ],
781
873
  reply: "Only on Safari 14.0 and below, which the SDK\u2019s support matrix dropped in v5. Under the current matrix the branch is dead code. I would ask Alice to remove it rather than test it."
782
874
  },
783
875
  {
@@ -786,19 +878,55 @@ function demoAssistantLog(profile, now) {
786
878
  action: "draft-reply",
787
879
  at: minutesAgo(now, 38),
788
880
  seconds: 64,
881
+ steps: [
882
+ call("Gmail: get thread", '{"threadId":"18f2a9c4b7"}'),
883
+ call("Gmail: search threads", '{"query":"Q4 planning doc headcount"}'),
884
+ said("Bob wants numbers per team with a reason each. The planning doc has both."),
885
+ call("Gmail: create draft", '{"threadId":"18f2a9c4b7"}')
886
+ ],
789
887
  reply: [
790
888
  "I read the thread \u2014 four messages, Bob twice. He wants the Q4 team split: how many of the six open roles go to Platform and how many to Webapp, with a line of justification each, by the end of the week so it lands in the planning deck.",
791
889
  "",
792
- "I have created a Gmail draft on the thread, from you, proposing four Platform and two Webapp with the reasons from the planning doc, and asking whether the deck can carry a footnote that the SDK hire depends on the Q3 numbers. It is **not sent**; it is waiting on the thread when you open it."
890
+ "I have created a Gmail draft on the thread, from you, proposing four Platform and two Webapp with the reasons from the planning doc, and asking whether the deck can carry a footnote that the SDK hire depends on the Q3 numbers. It is **not sent**; it is waiting on the thread when you open it.",
891
+ "",
892
+ "Created: [Gmail draft](https://mail.google.com/mail/u/0/#drafts?compose=18f2a9c4b7)"
893
+ ].join("\n")
894
+ },
895
+ {
896
+ id: "turn-d1",
897
+ item: "github:pr:acme/webapp#3398",
898
+ action: "assess-review",
899
+ auto: aheadKey(profile, now, "github:pr:acme/webapp#3398", "assess-review"),
900
+ at: minutesAgo(now, 172),
901
+ seconds: 47,
902
+ steps: [
903
+ call("Read the review comments", "gh pr view 3398 --repo acme/webapp --comments"),
904
+ call("Read the diff", "gh pr diff 3398 --repo acme/webapp")
905
+ ],
906
+ reply: [
907
+ "Dana is right: the backoff never resets after a send succeeds.",
908
+ "",
909
+ "She commented on `beacon.ts:41` that `attempt` is only zeroed on page load. The diff bears her out: after one failed send, every later failure waits longer, for the life of the tab. Reset `attempt` in the success branch of `sendBeacon` and add a test where a success between two failures starts the delay over.",
910
+ "",
911
+ "Her second point, capping the delay at 30 seconds rather than 60, is a preference. Sixty is defensible for a beacon nobody waits on; say so and leave it."
793
912
  ].join("\n")
794
913
  },
795
914
  {
796
915
  id: "turn-c1",
797
916
  item: "github:pr:acme/webapp#3402",
798
917
  action: "explain-ci",
918
+ auto: aheadKey(profile, now, "github:pr:acme/webapp#3402", "explain-ci"),
799
919
  at: minutesAgo(now, 20),
800
920
  seconds: 58,
921
+ steps: [
922
+ call("List the checks", "gh pr checks 3402 --repo acme/webapp"),
923
+ call("Read the failing job\u2019s log", "gh run view 9182734 --repo acme/webapp --log-failed"),
924
+ said("One failure, in tracing/fetch.spec.ts. Reading the retry path it exercises."),
925
+ call("Read the retry code", "gh api repos/acme/webapp/contents/src/tracing/fetch.ts")
926
+ ],
801
927
  reply: [
928
+ "Yours, not flaky: the retry path drops the trace headers.",
929
+ "",
802
930
  "The failing check is `unit-tests (node-20)`, in `tracing/fetch.spec.ts`:",
803
931
  "",
804
932
  fence,
@@ -817,6 +945,10 @@ function demoAssistantLog(profile, now) {
817
945
  action: "summarise-pr",
818
946
  at: minutesAgo(now, 52),
819
947
  seconds: 47,
948
+ steps: [
949
+ call("View the pull request", "gh pr view 47 --repo mara-l/pedalboard --json title,body,files,commits"),
950
+ call("Read the diff", "gh pr diff 47 --repo mara-l/pedalboard")
951
+ ],
820
952
  reply: [
821
953
  "Tomas adds MIDI clock sync to the looper: the transport listens for MIDI clock at 24 pulses per quarter note and for start and stop, derives the tempo, and quantises the loop start to the next beat. +212/\u221218 across three files, with a test for the tempo derivation.",
822
954
  "",
@@ -829,13 +961,31 @@ function demoAssistantLog(profile, now) {
829
961
  "A kind review that asks for the first two and lets the third go is probably right for a first contribution."
830
962
  ].join("\n")
831
963
  },
964
+ {
965
+ id: "turn-p3",
966
+ item: "github:pr:mara-l/pedalboard#51",
967
+ action: "explain-ci",
968
+ auto: aheadKey(profile, now, "github:pr:mara-l/pedalboard#51", "explain-ci"),
969
+ at: minutesAgo(now, 64),
970
+ seconds: 39,
971
+ steps: [
972
+ call("List the checks", "gh pr checks 51 --repo mara-l/pedalboard"),
973
+ call("Read the failing job\u2019s log", "gh run view 4471920 --repo mara-l/pedalboard --log-failed")
974
+ ],
975
+ reply: [
976
+ "Not your change: the macOS runner could not download the JUCE cache.",
977
+ "",
978
+ "The `build (macos)` job stops in its setup step with a 503 from the cache server, before any of your code is compiled. The Linux and Windows builds of the same commit pass. Rerun the job; if it fails the same way, the cache key in `.github/workflows/build.yml` can fall back to a fresh download."
979
+ ].join("\n")
980
+ },
832
981
  {
833
982
  id: "turn-p2",
834
983
  item: "email:thread:19a0c4e2f1",
835
984
  action: "draft-reply",
836
985
  at: minutesAgo(now, 30),
837
986
  seconds: 41,
838
- reply: "The thread is three messages: your request on the 28th, their \u201Cwithin the week\u201D on the 29th, and nothing since. I have created a Gmail draft on it that asks, briefly and politely, whether the quote is still coming this week, and says the other quotes are in and you would like to decide by Friday. It is **not sent**; open the thread to read it."
987
+ steps: [call("Gmail: get thread", '{"threadId":"19a0c4e2f1"}'), call("Gmail: create draft", '{"threadId":"19a0c4e2f1"}')],
988
+ reply: "The thread is three messages: your request on the 28th, their \u201Cwithin the week\u201D on the 29th, and nothing since. I have created a Gmail draft on it that asks, briefly and politely, whether the quote is still coming this week, and says the other quotes are in and you would like to decide by Friday. It is **not sent**; open the thread to read it.\n\nCreated: [Gmail draft](https://mail.google.com/mail/u/0/#drafts?compose=19a0c4e2f1)"
839
989
  }
840
990
  ];
841
991
  return turns.flatMap(turnLines);
@@ -851,6 +1001,8 @@ async function writeDemoStore(store, profile, now = /* @__PURE__ */ new Date())
851
1001
  await writeFile(join(store, "archive", `items-${past.date}.json`), `${JSON.stringify(past, null, 2)}
852
1002
  `, "utf8");
853
1003
  }
1004
+ await writeFile(join(store, SETTINGS_FILE), `${JSON.stringify(demoSettings(profile), null, 2)}
1005
+ `, "utf8");
854
1006
  await writeFile(join(store, "focus.md"), FOCUS[profile], "utf8");
855
1007
  await writeFile(join(store, "sources.md"), SOURCES[profile], "utf8");
856
1008
  await writeFile(join(store, "actions.jsonl"), lines(demoActions(profile, now)), "utf8");
@@ -858,10 +1010,12 @@ async function writeDemoStore(store, profile, now = /* @__PURE__ */ new Date())
858
1010
  await writeFile(join(store, "assistant.jsonl"), lines(demoAssistantLog(profile, now)), "utf8");
859
1011
  }
860
1012
  export {
1013
+ DEMO_FIXED,
861
1014
  demoEnv,
862
1015
  demoIntegrations,
863
1016
  demoProfile,
864
1017
  demoPulls,
1018
+ demoSettings,
865
1019
  demoTickets,
866
1020
  workingDayBack,
867
1021
  writeDemoStore
@@ -1,14 +1,20 @@
1
1
  import {
2
2
  FOCUS_TEMPLATE,
3
+ applySettingsChange,
4
+ saveSettings,
3
5
  sourcesTemplate
4
- } from "./chunk-V2UN3JYL.js";
6
+ } from "./chunk-U6EPOXEW.js";
5
7
  import {
6
8
  describeLink,
7
9
  linkStore
8
10
  } from "./chunk-QKT2FAB5.js";
11
+ import "./chunk-QG4XXKBP.js";
9
12
  import {
10
- loadConfig
11
- } from "./chunk-KZNY45XW.js";
13
+ PROFILES,
14
+ layerSettings,
15
+ loadConfig,
16
+ settingSources
17
+ } from "./chunk-72NUDSOV.js";
12
18
  import {
13
19
  PACKAGED,
14
20
  command
@@ -17,8 +23,32 @@ import {
17
23
  // scripts/init.ts
18
24
  import { mkdir, writeFile } from "node:fs/promises";
19
25
  import { platform } from "node:os";
20
- import { relative } from "node:path";
21
- var config = loadConfig();
26
+ import { dirname, relative } from "node:path";
27
+ import { parseArgs } from "node:util";
28
+ var { values: flags } = parseArgs({ args: process.argv.slice(2), options: { profile: { type: "string" } }, strict: false, allowPositionals: true });
29
+ var asked = typeof flags.profile === "string" ? flags.profile.trim().toLowerCase() : null;
30
+ if (asked !== null && !PROFILES.includes(asked)) {
31
+ console.error(`--profile must be one of ${PROFILES.join(", ")}, got ${JSON.stringify(flags.profile)}`);
32
+ process.exit(1);
33
+ }
34
+ var sources = settingSources();
35
+ var savedProfile = sources.settings.DAILY_FOCUS_PROFILE?.trim().toLowerCase() || null;
36
+ if (asked !== null && savedProfile !== null && savedProfile !== asked) {
37
+ console.error(`${sources.settingsPath} already says this store briefs the ${savedProfile} profile. Change it in the dashboard's settings.`);
38
+ process.exit(1);
39
+ }
40
+ var savesProfile = asked !== null && savedProfile === null;
41
+ if (savesProfile) {
42
+ const applied = applySettingsChange(sources, { DAILY_FOCUS_PROFILE: asked });
43
+ if ("error" in applied) {
44
+ console.error(applied.error);
45
+ process.exit(1);
46
+ }
47
+ await mkdir(dirname(sources.settingsPath), { recursive: true });
48
+ await saveSettings(sources.settingsPath, applied.settings);
49
+ sources = settingSources();
50
+ }
51
+ var config = loadConfig(layerSettings(sources));
22
52
  var created = 0;
23
53
  var linked = 0;
24
54
  var failed = 0;
@@ -54,6 +84,7 @@ async function writeIfAbsent(path, contents, what) {
54
84
  console.log(`
55
85
  \x1B[1mDaily Focus \u2014 store setup\x1B[0m`);
56
86
  console.log(`\x1B[2m${config.dataDir} (${config.profile} profile)\x1B[0m`);
87
+ if (savesProfile) ok(`saved the ${asked} profile`, relative(config.dataDir, sources.settingsPath));
57
88
  section("Directories");
58
89
  try {
59
90
  await mkdir(config.dataDir, { recursive: true });
@@ -86,8 +117,12 @@ var start = platform() === "darwin" ? `\`${command("service")}\` to run the boar
86
117
  var demo = PACKAGED ? "daily-focus --demo" : "npm run demo";
87
118
  section(next.length > 0 ? "Next" : "Nothing to do");
88
119
  if (next.length === 0) {
120
+ const changed = [
121
+ savesProfile ? `Saved the ${asked} profile` : null,
122
+ linked > 0 ? `${savesProfile ? "linked" : "Linked"} ${linked} ${linked === 1 ? "file" : "files"} to this checkout` : null
123
+ ].filter((part) => part !== null);
89
124
  console.log(
90
- linked > 0 ? ` The store was already set up. Linked ${linked} ${linked === 1 ? "file" : "files"} to this checkout; nothing else changed.` : " The store was already set up. Nothing was changed."
125
+ changed.length > 0 ? ` The store was already set up. ${changed.join(" and ")}; nothing else changed.` : " The store was already set up. Nothing was changed."
91
126
  );
92
127
  console.log(` ${start}, \`${command("audit")}\` to check the current brief.`);
93
128
  } else {
@@ -1,12 +1,13 @@
1
1
  import {
2
2
  sampleBrief
3
- } from "./chunk-P3E2B2SD.js";
3
+ } from "./chunk-WPXIQPYX.js";
4
4
  import {
5
5
  Store
6
- } from "./chunk-GQ3NCWRT.js";
6
+ } from "./chunk-ITUK7XKS.js";
7
+ import "./chunk-QG4XXKBP.js";
7
8
  import {
8
9
  loadConfig
9
- } from "./chunk-KZNY45XW.js";
10
+ } from "./chunk-72NUDSOV.js";
10
11
  import {
11
12
  command
12
13
  } from "./chunk-BC2W7NND.js";