@wirecat/cli-memo 0.131.69 → 0.131.70

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.
Files changed (35) hide show
  1. package/dist/bin/memo.js +2 -2
  2. package/dist/bundle/{auto-IKZIROGF.js → auto-CVILDIC6.js} +3 -3
  3. package/dist/bundle/{chunk-EKSOPEFQ.js → chunk-3OEV7GNU.js} +1 -1
  4. package/dist/bundle/{chunk-3YVLNOPE.js → chunk-52F4LHCH.js} +1 -1
  5. package/dist/bundle/{chunk-TVZXLAID.js → chunk-57SQU2YO.js} +1 -1
  6. package/dist/bundle/{chunk-5MUR6D2G.js → chunk-7OXLZZ27.js} +31 -1
  7. package/dist/bundle/{chunk-W2FFA7T5.js → chunk-EQKS6M52.js} +1 -1
  8. package/dist/bundle/{chunk-BJJULUUC.js → chunk-YBTUFOQG.js} +1 -1
  9. package/dist/bundle/{failure-NRZUB77S.js → failure-HM55W3NH.js} +2 -2
  10. package/dist/bundle/memo.js +5 -5
  11. package/dist/bundle/{program-BXL5ZOVQ.js → program-RSUVU6HA.js} +209 -89
  12. package/dist/bundle/{server-JLPZUC42.js → server-BVRPQPGY.js} +4 -4
  13. package/dist/bundle/{update-M54Z3SEU.js → update-ZE53ASCW.js} +2 -2
  14. package/dist/contract-overrides/skill.d.ts.map +1 -1
  15. package/dist/contract-overrides/skill.js +5 -10
  16. package/dist/contract-overrides/skill.js.map +1 -1
  17. package/dist/digest/backfill.d.ts.map +1 -1
  18. package/dist/digest/backfill.js +4 -2
  19. package/dist/digest/backfill.js.map +1 -1
  20. package/dist/digest/brief.d.ts +14 -0
  21. package/dist/digest/brief.d.ts.map +1 -0
  22. package/dist/digest/brief.js +143 -0
  23. package/dist/digest/brief.js.map +1 -0
  24. package/dist/examples.d.ts.map +1 -1
  25. package/dist/examples.js +7 -0
  26. package/dist/examples.js.map +1 -1
  27. package/dist/program.d.ts.map +1 -1
  28. package/dist/program.js +16 -8
  29. package/dist/program.js.map +1 -1
  30. package/dist/reasons.d.ts.map +1 -1
  31. package/dist/reasons.js +30 -0
  32. package/dist/reasons.js.map +1 -1
  33. package/dist/version.d.ts +1 -1
  34. package/dist/version.js +1 -1
  35. package/package.json +2 -2
@@ -6,17 +6,17 @@ import {
6
6
  autoState,
7
7
  lastAutoRun,
8
8
  recordAutoRun
9
- } from "./chunk-EKSOPEFQ.js";
9
+ } from "./chunk-3OEV7GNU.js";
10
10
  import {
11
11
  installer,
12
12
  latest,
13
13
  upgradeCommand
14
- } from "./chunk-BJJULUUC.js";
14
+ } from "./chunk-YBTUFOQG.js";
15
15
  import {
16
16
  mcpOwnerAllowed,
17
17
  readOnlyAvailability,
18
18
  refuseWritesUnderLock
19
- } from "./chunk-W2FFA7T5.js";
19
+ } from "./chunk-EQKS6M52.js";
20
20
  import {
21
21
  answers,
22
22
  atDetail,
@@ -27,7 +27,7 @@ import {
27
27
  trackAnswers,
28
28
  wholeList,
29
29
  withStore
30
- } from "./chunk-TVZXLAID.js";
30
+ } from "./chunk-57SQU2YO.js";
31
31
  import {
32
32
  ATTACHMENT_CHARS,
33
33
  DIALECTS,
@@ -67,7 +67,7 @@ import "./chunk-MWQI6FSU.js";
67
67
  import {
68
68
  errorObject,
69
69
  recognisable
70
- } from "./chunk-3YVLNOPE.js";
70
+ } from "./chunk-52F4LHCH.js";
71
71
  import {
72
72
  AGENT_INPUT_MAX_CHARS,
73
73
  DISCOVERY_DESCRIPTIONS,
@@ -378,7 +378,7 @@ import {
378
378
  REASONS,
379
379
  STORE_CLIENT,
380
380
  VERSION
381
- } from "./chunk-5MUR6D2G.js";
381
+ } from "./chunk-7OXLZZ27.js";
382
382
  import "./chunk-DSU6UR2X.js";
383
383
  import "./chunk-SYWHHQMC.js";
384
384
  import "./chunk-D72URWJE.js";
@@ -4348,7 +4348,8 @@ var search = [
4348
4348
  ];
4349
4349
 
4350
4350
  // dist/contract-overrides/skill.js
4351
- var REASON2 = "Memo installs its own stored-data instructions through its environment, prints the packaged primary skill without filesystem effects, and takes --json on each skill command because it has no global one.";
4351
+ var REASON2 = "Memo installs its own stored-data instructions through its environment, prints the packaged skills (morning-digest with the owner's brief from the store after it), and takes --json on each skill command because it has no global one.";
4352
+ var SHOW_DESCRIPTION = "print SKILL.md \u2014 `memo skill install` puts it where Claude Code, Codex, Gemini CLI and OpenClaw look for it, and where Hermes does on request; --for prints the copy already there";
4352
4353
  var JSON_OPTION2 = { flags: "--json", description: "print JSON", takes_value: false, mandatory: false };
4353
4354
  var SHOW_FOR = {
4354
4355
  flags: "--for <agents>",
@@ -4368,15 +4369,9 @@ var INSTALL_FOR = {
4368
4369
  var skill = [
4369
4370
  {
4370
4371
  command: ["skill", "show"],
4371
- field: "effects",
4372
- before: {
4373
- remote: "none",
4374
- local: "read"
4375
- },
4376
- after: {
4377
- remote: "none",
4378
- local: "none"
4379
- },
4372
+ field: "description",
4373
+ before: SHOW_DESCRIPTION,
4374
+ after: `${SHOW_DESCRIPTION}; morning-digest ends with your brief from \`memo digest brief\` when you wrote one`,
4380
4375
  reason: REASON2
4381
4376
  },
4382
4377
  {
@@ -4434,12 +4429,122 @@ var skill = [
4434
4429
  var SHELL_OVERRIDES = { search, doctor, skill, mcp, commands, notes, meetings };
4435
4430
 
4436
4431
  // dist/digest/backfill.js
4437
- import { existsSync as existsSync6, readdirSync as readdirSync4 } from "node:fs";
4438
- import { join as join6 } from "node:path";
4432
+ import { existsSync as existsSync7, readdirSync as readdirSync4 } from "node:fs";
4433
+ import { join as join7 } from "node:path";
4434
+
4435
+ // dist/digest/brief.js
4436
+ import { spawnSync } from "node:child_process";
4437
+ import { existsSync as existsSync3, mkdtempSync, readFileSync as readFileSync4, rmSync as rmSync2, writeFileSync as writeFileSync3 } from "node:fs";
4438
+ import { tmpdir } from "node:os";
4439
+ import { join as join3 } from "node:path";
4440
+ var BRIEF = { key: "digest/brief", channel: "text", language: "any" };
4441
+ var BRIEF_LIMIT = 4e3;
4442
+ var readBrief = /* @__PURE__ */ __name(async (env) => {
4443
+ if (!existsSync3(storePath(env)))
4444
+ return void 0;
4445
+ return withStore(env, async (store) => store.templates.get(BRIEF)?.body);
4446
+ }, "readBrief");
4447
+ var withBrief = /* @__PURE__ */ __name((skill2, brief) => brief === void 0 ? skill2 : `${skill2}
4448
+
4449
+ ## The owner's brief
4450
+
4451
+ The owner wrote this himself: it adds to everything above, and where it contradicts a rule of this skill, the brief wins.
4452
+
4453
+ ${brief.trim()}`, "withBrief");
4454
+ var systemEditor = /* @__PURE__ */ __name((path, env) => {
4455
+ const editor = env.VISUAL?.trim() || env.EDITOR?.trim();
4456
+ if (!editor)
4457
+ throw new CliError("validation_error", "set VISUAL or EDITOR, or pass the brief with --file", {
4458
+ reason: "brief.no-editor"
4459
+ });
4460
+ const [program = editor, ...args] = editor.split(/\s+/);
4461
+ const ran = spawnSync(program, [...args, path], { stdio: "inherit", env });
4462
+ if (ran.status !== 0)
4463
+ throw new CliError("validation_error", `the editor exited with ${ran.status ?? ran.signal}; nothing was saved`);
4464
+ }, "systemEditor");
4465
+ var refuseAgent = /* @__PURE__ */ __name((env) => {
4466
+ if (authorOf(env) !== "owner")
4467
+ throw new CliError("permission_error", "only the owner changes the digest brief, not an agent", {
4468
+ reason: "brief.owner-only"
4469
+ });
4470
+ }, "refuseAgent");
4471
+ var historyOf = /* @__PURE__ */ __name((store) => store.templates.history(BRIEF).map((entry) => ({
4472
+ saved_at: new Date(entry.savedAt).toISOString(),
4473
+ saved_by: entry.savedBy,
4474
+ replaced_at: new Date(entry.replacedAt).toISOString(),
4475
+ chars: entry.body.length
4476
+ })), "historyOf");
4477
+ var briefCommand = /* @__PURE__ */ __name((digest, print, env, editor = systemEditor) => {
4478
+ const brief = annotate(new Command("brief"), { effects: LOCAL_READ }).summary("your own instructions on what the morning digest collects").description(`your own instructions on what the morning digest collects: projects, people, topics, what to skip, how many items. The morning-digest skill ends with them, and where they contradict its rules they win; the run stays read only, with memo as its only tool and the schedule's cost cap. At most ${BRIEF_LIMIT} characters`);
4479
+ digest.addCommand(brief);
4480
+ annotate(brief.command("show"), { effects: LOCAL_READ }).summary("the brief the morning digest follows, and the bodies your changes replaced").option("--json", "print JSON").action(async (given2) => {
4481
+ const item = existsSync3(storePath(env)) ? await withStore(env, async (store) => {
4482
+ const row = store.templates.get(BRIEF);
4483
+ return {
4484
+ body: row?.body ?? null,
4485
+ chars: row?.body.length ?? 0,
4486
+ limit: BRIEF_LIMIT,
4487
+ updated_at: row ? new Date(row.updatedAt).toISOString() : null,
4488
+ updated_by: row?.updatedBy ?? null,
4489
+ history: historyOf(store)
4490
+ };
4491
+ }) : { body: null, chars: 0, limit: BRIEF_LIMIT, updated_at: null, updated_by: null, history: [] };
4492
+ print(given2.json, itemAnswer(item), item.body ?? "No brief: the morning digest follows its skill alone. `memo digest brief edit` writes one.");
4493
+ });
4494
+ grantsAuthority(annotate(brief.command("edit"), { effects: LOCAL_WRITE })).summary("write the brief in $EDITOR or from --file; only you, never an agent").description(`write the brief in $EDITOR, or from --file; at most ${BRIEF_LIMIT} characters. The body it replaces is kept, and --undo puts it back. Only you change it, never an agent or a read-only run`).option("--file <file>", "take the brief from this file instead of opening an editor; - reads stdin").addOption(new Option("--undo", "put back the body your last change replaced").conflicts("file")).option("--json", "print JSON").action(async (given2) => {
4495
+ refuseAgent(env);
4496
+ const { current, previous } = await withStore(env, async (store) => ({
4497
+ current: store.templates.get(BRIEF)?.body,
4498
+ previous: store.templates.history(BRIEF, 1)[0]?.body
4499
+ }));
4500
+ let draft;
4501
+ let body;
4502
+ if (given2.undo) {
4503
+ if (previous === void 0)
4504
+ throw new CliError("validation_error", "the brief has no earlier body to put back", {
4505
+ reason: "brief.no-history"
4506
+ });
4507
+ body = previous;
4508
+ } else if (given2.file !== void 0) {
4509
+ body = readFileSync4(given2.file === "-" ? 0 : given2.file, "utf8");
4510
+ } else {
4511
+ draft = join3(mkdtempSync(join3(tmpdir(), "memo-brief-")), "brief.md");
4512
+ writeFileSync3(draft, current ?? "", { mode: 384 });
4513
+ editor(draft, env);
4514
+ body = readFileSync4(draft, "utf8");
4515
+ }
4516
+ const kept = draft ? `. Your text is in ${draft}; fix it and run again with --file ${draft}` : "";
4517
+ body = body.trim();
4518
+ if (!body)
4519
+ throw new CliError("validation_error", `the brief is empty; memo digest brief reset removes it${kept}`, {
4520
+ reason: "brief.empty"
4521
+ });
4522
+ if (body.length > BRIEF_LIMIT)
4523
+ throw new CliError("validation_error", `the brief is ${body.length} characters; the limit is ${BRIEF_LIMIT}, because every morning run reads it and pays for it. Nothing was saved${kept}`, { reason: "brief.too-long", chars: body.length, limit: BRIEF_LIMIT });
4524
+ if (draft)
4525
+ rmSync2(join3(draft, ".."), { recursive: true, force: true });
4526
+ if (body === current) {
4527
+ print(given2.json, itemAnswer({ changed: false, chars: body.length }), "The brief is unchanged; nothing saved.");
4528
+ return;
4529
+ }
4530
+ const saved = await withStore(env, async (store) => store.templates.save(BRIEF, body, "memo"));
4531
+ print(given2.json, itemAnswer({
4532
+ changed: true,
4533
+ chars: body.length,
4534
+ limit: BRIEF_LIMIT,
4535
+ updated_at: new Date(saved.updatedAt).toISOString()
4536
+ }), `Saved the brief (${body.length} of ${BRIEF_LIMIT} characters); the next morning digest follows it.`);
4537
+ });
4538
+ grantsAuthority(annotate(brief.command("reset"), { effects: LOCAL_WRITE })).summary("remove the brief; edit --undo brings it back").description("remove the brief, so the morning digest follows its skill alone; edit --undo brings it back").option("--json", "print JSON").action(async (given2) => {
4539
+ refuseAgent(env);
4540
+ const changed = await withStore(env, async (store) => store.templates.reset(BRIEF));
4541
+ print(given2.json, itemAnswer({ changed }), changed ? "Removed the brief; memo digest brief edit --undo brings it back." : "There was no brief.");
4542
+ });
4543
+ }, "briefCommand");
4439
4544
 
4440
4545
  // dist/digest/tasks.js
4441
- import { existsSync as existsSync5, readdirSync as readdirSync3 } from "node:fs";
4442
- import { join as join5 } from "node:path";
4546
+ import { existsSync as existsSync6, readdirSync as readdirSync3 } from "node:fs";
4547
+ import { join as join6 } from "node:path";
4443
4548
 
4444
4549
  // dist/tasks/list.js
4445
4550
  import { createHash as createHash2 } from "node:crypto";
@@ -4609,13 +4714,13 @@ var countTasks = /* @__PURE__ */ __name(async (store, words) => {
4609
4714
  }, "countTasks");
4610
4715
 
4611
4716
  // dist/digest/sync-health.js
4612
- import { existsSync as existsSync4, readdirSync as readdirSync2, readFileSync as readFileSync5 } from "node:fs";
4613
- import { join as join4 } from "node:path";
4717
+ import { existsSync as existsSync5, readdirSync as readdirSync2, readFileSync as readFileSync6 } from "node:fs";
4718
+ import { join as join5 } from "node:path";
4614
4719
 
4615
4720
  // dist/knowledge/messenger-sync.js
4616
4721
  import { spawn } from "node:child_process";
4617
- import { existsSync as existsSync3, readdirSync, readFileSync as readFileSync4, realpathSync, statSync as statSync2 } from "node:fs";
4618
- import { delimiter, join as join3 } from "node:path";
4722
+ import { existsSync as existsSync4, readdirSync, readFileSync as readFileSync5, realpathSync, statSync as statSync2 } from "node:fs";
4723
+ import { delimiter, join as join4 } from "node:path";
4619
4724
  var STATE = {
4620
4725
  tg: { appName: "tg-cli", envPrefix: "TG" },
4621
4726
  max: { appName: "max-cli", envPrefix: "MAX" },
@@ -4635,10 +4740,10 @@ var syncProfileOf = /* @__PURE__ */ __name((value, previous = {}) => {
4635
4740
  throw new InvalidArgumentError(`one profile per tool; ${tool} is already ${previous[tool]}`);
4636
4741
  return { ...previous, [tool]: profile };
4637
4742
  }, "syncProfileOf");
4638
- var accountsDir = /* @__PURE__ */ __name((tool, env) => join3(resolvePaths({ appName: tool.appName, prefix: tool.envPrefix, env }).state, "accounts"), "accountsDir");
4743
+ var accountsDir = /* @__PURE__ */ __name((tool, env) => join4(resolvePaths({ appName: tool.appName, prefix: tool.envPrefix, env }).state, "accounts"), "accountsDir");
4639
4744
  var signedInAccount = /* @__PURE__ */ __name((tool, profile, env) => {
4640
4745
  try {
4641
- return JSON.parse(readFileSync4(join3(accountsDir(tool, env), `${profile}.json`), "utf8"))?.account;
4746
+ return JSON.parse(readFileSync5(join4(accountsDir(tool, env), `${profile}.json`), "utf8"))?.account;
4642
4747
  } catch {
4643
4748
  return void 0;
4644
4749
  }
@@ -4648,7 +4753,7 @@ var profileFor = /* @__PURE__ */ __name((provider, account2, env, chosen = {}) =
4648
4753
  if (!tool)
4649
4754
  return void 0;
4650
4755
  const dir = accountsDir(tool, env);
4651
- const profiles = existsSync3(dir) ? readdirSync(dir).filter((name2) => name2.endsWith(".json")).map((name2) => name2.slice(0, -".json".length)).sort() : [];
4756
+ const profiles = existsSync4(dir) ? readdirSync(dir).filter((name2) => name2.endsWith(".json")).map((name2) => name2.slice(0, -".json".length)).sort() : [];
4652
4757
  const accountOf = /* @__PURE__ */ __name((profile) => signedInAccount(tool, profile, env), "accountOf");
4653
4758
  const all = profiles.join(", ") || "none";
4654
4759
  const pick = chosen[tool.tool];
@@ -4668,7 +4773,7 @@ var profileFor = /* @__PURE__ */ __name((provider, account2, env, chosen = {}) =
4668
4773
  };
4669
4774
  return { why: `no ${tool.tool} profile here is signed in to account ${account2}; profiles: ${all}`, profiles: [] };
4670
4775
  }, "profileFor");
4671
- var onPath = /* @__PURE__ */ __name((name2, env) => (env.PATH ?? "").split(delimiter).filter(Boolean).map((dir) => join3(dir, name2)).find((path) => {
4776
+ var onPath = /* @__PURE__ */ __name((name2, env) => (env.PATH ?? "").split(delimiter).filter(Boolean).map((dir) => join4(dir, name2)).find((path) => {
4672
4777
  try {
4673
4778
  return statSync2(path).isFile();
4674
4779
  } catch {
@@ -4724,7 +4829,7 @@ var binaryOf = /* @__PURE__ */ __name(async (provider, env, run) => {
4724
4829
  const real = realpathSync(short);
4725
4830
  if (real.includes(`/${mark}/`))
4726
4831
  return short;
4727
- return statSync2(real).size < 65536 && readFileSync4(real, "utf8").includes(mark) ? short : void 0;
4832
+ return statSync2(real).size < 65536 && readFileSync5(real, "utf8").includes(mark) ? short : void 0;
4728
4833
  }, "binaryOf");
4729
4834
  var answerOf = /* @__PURE__ */ __name((stdout) => {
4730
4835
  try {
@@ -4832,13 +4937,13 @@ var SOURCE_WORDS = {
4832
4937
  var toolOf = /* @__PURE__ */ __name((provider) => provider === "email" ? MAIL2 : messengerToolOf(provider), "toolOf");
4833
4938
  var stateDirs = /* @__PURE__ */ __name((tool, env) => resolvePaths({ appName: tool.appName, prefix: tool.envPrefix, env }), "stateDirs");
4834
4939
  var schedulesOf = /* @__PURE__ */ __name((state) => {
4835
- const dir = join4(state, "schedules");
4836
- if (!existsSync4(dir))
4940
+ const dir = join5(state, "schedules");
4941
+ if (!existsSync5(dir))
4837
4942
  return [];
4838
4943
  const last = new Map(scheduledRuns(state).map((one2) => [one2.job, one2.last]));
4839
4944
  return readdirSync2(dir).flatMap((name2) => {
4840
4945
  try {
4841
- const schedule = JSON.parse(readFileSync5(join4(dir, name2, "schedule.json"), "utf8"));
4946
+ const schedule = JSON.parse(readFileSync6(join5(dir, name2, "schedule.json"), "utf8"));
4842
4947
  return [
4843
4948
  {
4844
4949
  name: String(schedule.name),
@@ -4853,15 +4958,15 @@ var schedulesOf = /* @__PURE__ */ __name((state) => {
4853
4958
  }
4854
4959
  });
4855
4960
  }, "schedulesOf");
4856
- var signedIn = /* @__PURE__ */ __name((dir) => existsSync4(dir) ? readdirSync2(dir).filter((name2) => name2.endsWith(".json")).map((name2) => name2.slice(0, -".json".length)) : [], "signedIn");
4961
+ var signedIn = /* @__PURE__ */ __name((dir) => existsSync5(dir) ? readdirSync2(dir).filter((name2) => name2.endsWith(".json")).map((name2) => name2.slice(0, -".json".length)) : [], "signedIn");
4857
4962
  var profilesOf = /* @__PURE__ */ __name((provider, tool, env) => {
4858
4963
  if (provider !== "email")
4859
- return new Map(signedIn(join4(stateDirs(tool, env).state, "accounts")).map((profile) => [
4964
+ return new Map(signedIn(join5(stateDirs(tool, env).state, "accounts")).map((profile) => [
4860
4965
  profile,
4861
4966
  signedInAccount(tool, profile, env)
4862
4967
  ]));
4863
4968
  try {
4864
- const config = JSON.parse(readFileSync5(configFilePath(stateDirs(MAIL2, env).config), "utf8"));
4969
+ const config = JSON.parse(readFileSync6(configFilePath(stateDirs(MAIL2, env).config), "utf8"));
4865
4970
  return new Map(Object.entries(config?.profiles ?? {}).map(([profile, one2]) => [
4866
4971
  profile,
4867
4972
  one2?.address
@@ -4951,8 +5056,8 @@ var runTime = /* @__PURE__ */ __name((file) => {
4951
5056
  }, "runTime");
4952
5057
  var digestReportTimes = /* @__PURE__ */ __name((env) => {
4953
5058
  const { state, schedule } = digestSchedule(env);
4954
- const runs = schedule ? join5(state, "schedules", schedule.name, "runs") : void 0;
4955
- if (!runs || !existsSync5(runs))
5059
+ const runs = schedule ? join6(state, "schedules", schedule.name, "runs") : void 0;
5060
+ if (!runs || !existsSync6(runs))
4956
5061
  return [];
4957
5062
  return readdirSync3(runs).filter((file) => file.endsWith(".report.json")).map(runTime).filter((at) => !Number.isNaN(at)).sort((a, b) => a - b);
4958
5063
  }, "digestReportTimes");
@@ -5081,7 +5186,8 @@ var usd = /* @__PURE__ */ __name((value) => `$${value.toFixed(2)}`, "usd");
5081
5186
  var cents = /* @__PURE__ */ __name((value) => Math.round(value * 100) / 100, "cents");
5082
5187
  var digestCommand = /* @__PURE__ */ __name((program, streams, env) => {
5083
5188
  const { print } = answers(program, streams, env);
5084
- const digest = program.command("digest").description("the morning digest's history: build the digests of past days").summary("the morning digest's history");
5189
+ const digest = program.command("digest").description("the morning digest: your brief on what it collects, and the digests of past days").summary("the morning digest: your brief, past days");
5190
+ briefCommand(digest, print, env);
5085
5191
  fromAppOption(annotate(digest.command("backfill"), { effects: LOCAL_WRITE })).summary("build the morning digests of past days, without sending them").description("build the morning digest each past day would have had: the morning-digest schedule's agent runs as its timer does (the same skill, flags and cost caps), reading the agenda as of that day's run time, and the result is kept as that day's run, marked backfill, for WireCat Desktop's digests screen. It is never sent to Telegram or mail. A day that already has a digest is skipped. Without --yes it only prints what it would build and the estimate: the days times the last digest run's cost. Each day is a paid model call: it stops once today's runs cost the schedule's daily cap or a day fails, and only you run it, never an agent. The store keeps what holds now, so a chat answered since reads as answered").requiredOption("--from <date>", "the first day, YYYY-MM-DD").requiredOption("--to <date>", "the last day, YYYY-MM-DD; not a day whose run time is still ahead").option("--yes", "build them; without it, only the estimate is printed").option("--json", "print JSON").action(async (given2, command) => {
5086
5192
  const from = dateOf(given2.from, "--from");
5087
5193
  const to = dateOf(given2.to, "--to");
@@ -5102,8 +5208,8 @@ var digestCommand = /* @__PURE__ */ __name((program, streams, env) => {
5102
5208
  throw new CliError("validation_error", `the ${given2.to} digest's time has not come yet; --to an earlier day`, {
5103
5209
  param: "--to"
5104
5210
  });
5105
- const runs = join6(file, "..", "runs");
5106
- const done = new Set((existsSync6(runs) ? readdirSync4(runs) : []).filter((name2) => name2.endsWith(".report.json")).map((name2) => localDate(runTime(name2))));
5211
+ const runs = join7(file, "..", "runs");
5212
+ const done = new Set((existsSync7(runs) ? readdirSync4(runs) : []).filter((name2) => name2.endsWith(".report.json")).map((name2) => localDate(runTime(name2))));
5107
5213
  const days2 = all.filter((day2) => !done.has(day2.date));
5108
5214
  const skipped = all.filter((day2) => done.has(day2.date)).map((day2) => day2.date);
5109
5215
  const lastCost = schedule.last?.costUsd;
@@ -5248,9 +5354,9 @@ var commandsCommand = /* @__PURE__ */ __name((program, streams) => {
5248
5354
  }, "commandsCommand");
5249
5355
 
5250
5356
  // dist/doctor/command.js
5251
- import { existsSync as existsSync7, readdirSync as readdirSync5, readFileSync as readFileSync6 } from "node:fs";
5357
+ import { existsSync as existsSync8, readdirSync as readdirSync5, readFileSync as readFileSync7 } from "node:fs";
5252
5358
  import { homedir } from "node:os";
5253
- import { dirname, join as join7 } from "node:path";
5359
+ import { dirname, join as join8 } from "node:path";
5254
5360
  var retiredMailAddresses = /* @__PURE__ */ __name((mail) => {
5255
5361
  const accounts = mail?.accounts;
5256
5362
  if (!Array.isArray(accounts))
@@ -5276,7 +5382,7 @@ var diagnose = /* @__PURE__ */ __name(async (env, program, { deep = false } = {}
5276
5382
  problems.push({ what: "the store is from a newer version than this memo", fix: "memo upgrade" });
5277
5383
  const folders = noteFolders(config.notes).map(({ path, id }) => ({
5278
5384
  path,
5279
- exists: existsSync7(path),
5385
+ exists: existsSync8(path),
5280
5386
  bound: id !== null
5281
5387
  }));
5282
5388
  for (const folder of folders) {
@@ -5307,13 +5413,13 @@ var diagnose = /* @__PURE__ */ __name(async (env, program, { deep = false } = {}
5307
5413
  fix: `fix text_models in ${textModelsFile(env)}, or remove it to go back to ${DEFAULT_TEXT_MODEL}`
5308
5414
  });
5309
5415
  }
5310
- const modelDir = join7(sharedModelsDirectory("text", env), textModel);
5311
- const model = existsSync7(modelDir) && readdirSync5(modelDir).length > 0;
5416
+ const modelDir = join8(sharedModelsDirectory("text", env), textModel);
5417
+ const model = existsSync8(modelDir) && readdirSync5(modelDir).length > 0;
5312
5418
  const state = autoState(config);
5313
- const unitFile = join7(env.XDG_CONFIG_HOME ?? join7(env.HOME ?? homedir(), ".config"), "systemd", "user", "memo-import.service");
5314
- const unit = existsSync7(unitFile) ? readFileSync6(unitFile, "utf8") : void 0;
5419
+ const unitFile = join8(env.XDG_CONFIG_HOME ?? join8(env.HOME ?? homedir(), ".config"), "systemd", "user", "memo-import.service");
5420
+ const unit = existsSync8(unitFile) ? readFileSync7(unitFile, "utf8") : void 0;
5315
5421
  const runs = unit ? unitPaths(unit) : [];
5316
- const missing = runs.filter((path) => !existsSync7(path));
5422
+ const missing = runs.filter((path) => !existsSync8(path));
5317
5423
  const last = lastAutoRun(env);
5318
5424
  const failing = last && last.exitCode !== 0 ? { since: last.failingSince ?? last.at, runs: last.failures ?? 1, reason: last.reason ?? null } : null;
5319
5425
  if (state.enabled && !unit)
@@ -5324,7 +5430,7 @@ var diagnose = /* @__PURE__ */ __name(async (env, program, { deep = false } = {}
5324
5430
  problems.push({ what: `the timer has failed ${failing.runs} runs since ${failing.since}`, fix: "memo jobs status" });
5325
5431
  const skills = SKILL_TARGETS.map((target) => {
5326
5432
  const path = skillPath(target, APP.appName, env);
5327
- const version = existsSync7(path) ? skillVersion(readFileSync6(path, "utf8")) ?? "unknown" : null;
5433
+ const version = existsSync8(path) ? skillVersion(readFileSync7(path, "utf8")) ?? "unknown" : null;
5328
5434
  return { target, path, version };
5329
5435
  });
5330
5436
  if (skills.some(({ version }) => version !== null && version !== VERSION))
@@ -6194,6 +6300,13 @@ var EXAMPLES = {
6194
6300
  "memo digest backfill --from 2026-11-01 --to 2026-11-07",
6195
6301
  "memo digest backfill --from 2026-11-01 --to 2026-11-07 --yes --json"
6196
6302
  ],
6303
+ "digest brief show": ["memo digest brief show", "memo digest brief show --json"],
6304
+ "digest brief edit": [
6305
+ "memo digest brief edit",
6306
+ "memo digest brief edit --file brief.md",
6307
+ "memo digest brief edit --undo"
6308
+ ],
6309
+ "digest brief reset": ["memo digest brief reset"],
6197
6310
  "schedule remove": ["memo schedule remove digest"],
6198
6311
  "schedule exec": ["memo schedule exec ~/.local/state/cli-memo/schedules/digest/schedule.json"],
6199
6312
  "templates list": ["memo templates list", "memo templates list channel:telegram source:stored --json"],
@@ -9506,9 +9619,9 @@ var messagesCommand = /* @__PURE__ */ __name((program, streams, env) => {
9506
9619
  }, "messagesCommand");
9507
9620
 
9508
9621
  // dist/mcp/command.js
9509
- import { join as join8 } from "node:path";
9622
+ import { join as join9 } from "node:path";
9510
9623
  var DEFAULT_PORT = 8767;
9511
- var httpTokenFile = /* @__PURE__ */ __name((env) => join8(resolvePaths({ appName: APP.appName, prefix: APP.envPrefix, env }).state, "mcp-http", "memo.json"), "httpTokenFile");
9624
+ var httpTokenFile = /* @__PURE__ */ __name((env) => join9(resolvePaths({ appName: APP.appName, prefix: APP.envPrefix, env }).state, "mcp-http", "memo.json"), "httpTokenFile");
9512
9625
  var mcpCommandDefinition = /* @__PURE__ */ __name((program, streams, env, createProgram2) => {
9513
9626
  const out = answers(program, streams, env);
9514
9627
  const mcp2 = annotate(program.command("mcp"), { effects: LOCAL_READ, mcp: false }).summary("serve this profile's commands to an AI agent, and set that up").description("serve memo commands over MCP on stdio or authenticated HTTP, limited by saved permissions \u2014 `claude mcp add memo -- memo mcp serve`");
@@ -9520,7 +9633,7 @@ var mcpCommandDefinition = /* @__PURE__ */ __name((program, streams, env, create
9520
9633
  }).summary("serve this profile's commands to an AI agent").description("serve memo commands over MCP on stdio or authenticated HTTP, limited by saved permissions").option("--permission <key=level>", "tighten one saved permission for this server; repeat for more keys", (value, previous = []) => [...previous, value]).option("--http", "serve on 127.0.0.1 behind an HTTPS tunnel with an owner access-code login").option("--port <port>", `local HTTP port (default ${DEFAULT_PORT}); requires --http`).option("--public-url <url>", "tunnel's HTTPS address without /mcp, or a path of it such as https://<name>.ts.net/memo; requires --http").action(async (options) => {
9521
9634
  if (!options.http && (options.port !== void 0 || options.publicUrl !== void 0))
9522
9635
  throw new CliError("validation_error", "--port and --public-url require --http");
9523
- const { createMemoServer } = await import("./server-JLPZUC42.js");
9636
+ const { createMemoServer } = await import("./server-BVRPQPGY.js");
9524
9637
  const build = /* @__PURE__ */ __name(() => createMemoServer(env, createProgram2, options.permission), "build");
9525
9638
  if (options.http) {
9526
9639
  const { httpLockFile, mcpUrlOf, portOf, publicUrlOf, serveOverHttp } = await import("./mcp-CFIL7WZU.js");
@@ -9866,7 +9979,7 @@ var modelsCommand = /* @__PURE__ */ __name((program, streams, env, keyring) => {
9866
9979
  }, "modelsCommand");
9867
9980
 
9868
9981
  // dist/notes/command.js
9869
- import { readFileSync as readFileSync8 } from "node:fs";
9982
+ import { readFileSync as readFileSync9 } from "node:fs";
9870
9983
 
9871
9984
  // dist/people/identity.js
9872
9985
  var identityOf = /* @__PURE__ */ __name(async (store, reference2) => {
@@ -9904,8 +10017,8 @@ import { resolve as resolve3 } from "node:path";
9904
10017
 
9905
10018
  // dist/notes/export.js
9906
10019
  import { createHash as createHash3 } from "node:crypto";
9907
- import { existsSync as existsSync8, mkdirSync as mkdirSync3, readdirSync as readdirSync6, readFileSync as readFileSync7, renameSync as renameSync2, writeFileSync as writeFileSync3 } from "node:fs";
9908
- import { join as join9 } from "node:path";
10020
+ import { existsSync as existsSync9, mkdirSync as mkdirSync3, readdirSync as readdirSync6, readFileSync as readFileSync8, renameSync as renameSync2, writeFileSync as writeFileSync4 } from "node:fs";
10021
+ import { join as join10 } from "node:path";
9909
10022
  var HASH_LINE = /^memo-hash: .*\r?\n/m;
9910
10023
  var PLACEHOLDER = "f".repeat(64);
9911
10024
  var UNSAFE = /[\\/:*?"<>|#^[\]\p{Cc}]/gu;
@@ -9929,7 +10042,7 @@ var exportedIn = /* @__PURE__ */ __name((dir) => {
9929
10042
  for (const entry of readdirSync6(dir, { withFileTypes: true })) {
9930
10043
  if (!entry.isFile() || !/\.(md|markdown)$/i.test(entry.name))
9931
10044
  continue;
9932
- const id = readMemoId(join9(dir, entry.name));
10045
+ const id = readMemoId(join10(dir, entry.name));
9933
10046
  if (id !== null)
9934
10047
  found.set(id, entry.name);
9935
10048
  }
@@ -9946,11 +10059,11 @@ var exportNotes = /* @__PURE__ */ __name(({ dir, dialect, notes: notes2 }) => {
9946
10059
  frontMatter["memo-hash"] = PLACEHOLDER;
9947
10060
  const content = withHash(dialect.render({ ...note, frontMatter }));
9948
10061
  const known2 = existing.get(id);
9949
- const name2 = known2 ?? fileName(note.title, id, (candidate) => claimed.has(candidate) || existsSync8(join9(dir, candidate)));
10062
+ const name2 = known2 ?? fileName(note.title, id, (candidate) => claimed.has(candidate) || existsSync9(join10(dir, candidate)));
9950
10063
  claimed.add(name2);
9951
- const path = join9(dir, name2);
10064
+ const path = join10(dir, name2);
9952
10065
  if (known2 !== void 0) {
9953
- const current = readFileSync7(path, "utf8");
10066
+ const current = readFileSync8(path, "utf8");
9954
10067
  if (editedSinceExport(current)) {
9955
10068
  result.edited.push({ path, id });
9956
10069
  continue;
@@ -9960,8 +10073,8 @@ var exportNotes = /* @__PURE__ */ __name(({ dir, dialect, notes: notes2 }) => {
9960
10073
  continue;
9961
10074
  }
9962
10075
  }
9963
- const partial = join9(dir, `.${name2}.memo-tmp`);
9964
- writeFileSync3(partial, content);
10076
+ const partial = join10(dir, `.${name2}.memo-tmp`);
10077
+ writeFileSync4(partial, content);
9965
10078
  renameSync2(partial, path);
9966
10079
  result.written.push(path);
9967
10080
  }
@@ -10061,7 +10174,7 @@ var textOf = /* @__PURE__ */ __name((options, given2) => {
10061
10174
  if (sources.length !== 1)
10062
10175
  throw new CliError("validation_error", "give the text once: as an argument, --text or --text-file");
10063
10176
  if (options.textFile !== void 0)
10064
- return readFileSync8(options.textFile === "-" ? 0 : options.textFile, "utf8");
10177
+ return readFileSync9(options.textFile === "-" ? 0 : options.textFile, "utf8");
10065
10178
  return sources[0];
10066
10179
  }, "textOf");
10067
10180
  var noteOf = /* @__PURE__ */ __name(async (store, env, reference2) => {
@@ -10217,9 +10330,9 @@ import { statSync as statSync4 } from "node:fs";
10217
10330
  import { basename as basename2, resolve as resolve4 } from "node:path";
10218
10331
 
10219
10332
  // dist/run/lock.js
10220
- import { join as join10 } from "node:path";
10333
+ import { join as join11 } from "node:path";
10221
10334
  var withImportLock = /* @__PURE__ */ __name(async (env, work) => {
10222
- const lock = join10(resolvePaths({ appName: "cli-memo", prefix: "MEMO", env }).state, "import.lock");
10335
+ const lock = join11(resolvePaths({ appName: "cli-memo", prefix: "MEMO", env }).state, "import.lock");
10223
10336
  const holder = takeLock(lock, { pid: process.pid, startedAt: (/* @__PURE__ */ new Date()).toISOString() });
10224
10337
  if (holder !== void 0)
10225
10338
  throw new CliError("rate_limited", `another memo sync is running (process ${holder.pid}); try again when it ends`, {
@@ -10350,7 +10463,7 @@ var foldersCommand = /* @__PURE__ */ __name((program, streams, env) => {
10350
10463
  }, "foldersCommand");
10351
10464
 
10352
10465
  // dist/people/command.js
10353
- import { join as join11 } from "node:path";
10466
+ import { join as join12 } from "node:path";
10354
10467
  var noteCommand = /* @__PURE__ */ __name((program, streams, env) => {
10355
10468
  const notes2 = program.commands.find((command) => command.name() === "notes") ?? program.command("notes");
10356
10469
  const links = notes2.command("links").description("imported note files linked to the person behind an identity");
@@ -10403,7 +10516,7 @@ var noteCommand = /* @__PURE__ */ __name((program, streams, env) => {
10403
10516
  }
10404
10517
  const paths = (await files()).map(({ note }) => {
10405
10518
  const folder = folders.find((candidate) => candidate.id === note.folderId);
10406
- return folder ? join11(folder.path, note.path) : note.ref;
10519
+ return folder ? join12(folder.path, note.path) : note.ref;
10407
10520
  });
10408
10521
  return { person: to, name: person.name ?? person.uid, files: paths };
10409
10522
  });
@@ -10846,8 +10959,8 @@ ${SOURCE_REVIEW_HELP}`);
10846
10959
  }, "reviewCommand");
10847
10960
 
10848
10961
  // dist/notes/embed.js
10849
- import { existsSync as existsSync9, readdirSync as readdirSync7 } from "node:fs";
10850
- import { join as join12 } from "node:path";
10962
+ import { existsSync as existsSync10, readdirSync as readdirSync7 } from "node:fs";
10963
+ import { join as join13 } from "node:path";
10851
10964
  var EMBED_PER_RUN = 600;
10852
10965
  var SLOWEST_KNOWN = 2;
10853
10966
  var embedPerRun = /* @__PURE__ */ __name((env = process.env) => {
@@ -10864,8 +10977,8 @@ var missingModel = /* @__PURE__ */ __name((error, env) => {
10864
10977
  }, "missingModel");
10865
10978
  var searchModelPresent = /* @__PURE__ */ __name((env) => {
10866
10979
  try {
10867
- const path = join12(sharedModelsDirectory("text", env), chosenTextModel(env).id);
10868
- return existsSync9(path) && readdirSync7(path).length > 0;
10980
+ const path = join13(sharedModelsDirectory("text", env), chosenTextModel(env).id);
10981
+ return existsSync10(path) && readdirSync7(path).length > 0;
10869
10982
  } catch {
10870
10983
  return false;
10871
10984
  }
@@ -11346,8 +11459,8 @@ var searchText = /* @__PURE__ */ __name((result, offset = 0) => [
11346
11459
  ].join("\n"), "searchText");
11347
11460
 
11348
11461
  // dist/search/hits.js
11349
- var BRIEF = ["ref", "chat_title", "timestamp", "sender_name", "excerpt", "score"];
11350
- var briefHit = /* @__PURE__ */ __name((hit) => Object.fromEntries(BRIEF.flatMap((key) => hit[key] === void 0 || hit[key] === null ? [] : [[key, hit[key]]])), "briefHit");
11462
+ var BRIEF2 = ["ref", "chat_title", "timestamp", "sender_name", "excerpt", "score"];
11463
+ var briefHit = /* @__PURE__ */ __name((hit) => Object.fromEntries(BRIEF2.flatMap((key) => hit[key] === void 0 || hit[key] === null ? [] : [[key, hit[key]]])), "briefHit");
11351
11464
 
11352
11465
  // dist/search/answers.js
11353
11466
  var named4 = /* @__PURE__ */ __name((accounts) => [
@@ -11768,29 +11881,29 @@ var showCommand = /* @__PURE__ */ __name((program, streams, env) => {
11768
11881
  }, "showCommand");
11769
11882
 
11770
11883
  // dist/sources/command.js
11771
- import { existsSync as existsSync11 } from "node:fs";
11884
+ import { existsSync as existsSync12 } from "node:fs";
11772
11885
 
11773
11886
  // dist/sources/copy.js
11774
11887
  import { randomUUID } from "node:crypto";
11775
- import { existsSync as existsSync10, mkdirSync as mkdirSync4, renameSync as renameSync3, rmSync as rmSync2, writeFileSync as writeFileSync4 } from "node:fs";
11776
- import { isAbsolute, join as join13, relative as relative2, resolve as resolve5, sep as sep2 } from "node:path";
11777
- var copiesDir = /* @__PURE__ */ __name((env) => join13(resolvePaths({ appName: APP.appName, prefix: APP.envPrefix, env }).state, "sources"), "copiesDir");
11778
- var copyPath = /* @__PURE__ */ __name((env, hash) => join13(copiesDir(env), hash), "copyPath");
11888
+ import { existsSync as existsSync11, mkdirSync as mkdirSync4, renameSync as renameSync3, rmSync as rmSync3, writeFileSync as writeFileSync5 } from "node:fs";
11889
+ import { isAbsolute, join as join14, relative as relative2, resolve as resolve5, sep as sep2 } from "node:path";
11890
+ var copiesDir = /* @__PURE__ */ __name((env) => join14(resolvePaths({ appName: APP.appName, prefix: APP.envPrefix, env }).state, "sources"), "copiesDir");
11891
+ var copyPath = /* @__PURE__ */ __name((env, hash) => join14(copiesDir(env), hash), "copyPath");
11779
11892
  var keepCopy = /* @__PURE__ */ __name((env, hash, bytes) => {
11780
11893
  const path = copyPath(env, hash);
11781
- if (existsSync10(path))
11894
+ if (existsSync11(path))
11782
11895
  return { path, wrote: false };
11783
11896
  mkdirSync4(copiesDir(env), { recursive: true, mode: 448 });
11784
11897
  const partial = `${path}.${randomUUID()}.part`;
11785
- writeFileSync4(partial, bytes, { mode: 384 });
11898
+ writeFileSync5(partial, bytes, { mode: 384 });
11786
11899
  renameSync3(partial, path);
11787
11900
  return { path, wrote: true };
11788
11901
  }, "keepCopy");
11789
11902
  var dropCopy = /* @__PURE__ */ __name((env, path) => {
11790
11903
  const inside2 = relative2(resolve5(copiesDir(env)), resolve5(path));
11791
- if (!inside2 || isAbsolute(inside2) || inside2.startsWith("..") || inside2.includes(sep2) || !existsSync10(path))
11904
+ if (!inside2 || isAbsolute(inside2) || inside2.startsWith("..") || inside2.includes(sep2) || !existsSync11(path))
11792
11905
  return false;
11793
- rmSync2(path);
11906
+ rmSync3(path);
11794
11907
  return true;
11795
11908
  }, "dropCopy");
11796
11909
 
@@ -11864,7 +11977,7 @@ ${note.text}`);
11864
11977
  }, "namedIn");
11865
11978
 
11866
11979
  // dist/sources/read.js
11867
- import { readFileSync as readFileSync9, statSync as statSync5 } from "node:fs";
11980
+ import { readFileSync as readFileSync10, statSync as statSync5 } from "node:fs";
11868
11981
  import { basename as basename3, extname as extname2 } from "node:path";
11869
11982
  var SOURCE_TEXT_CHARS = 2e5;
11870
11983
  var URL_LIKE = /^[a-z][a-z0-9+.-]*:\/\//i;
@@ -11982,7 +12095,7 @@ var readFile = /* @__PURE__ */ __name(async (path, { maxChars, load = importEngi
11982
12095
  throw new CliError("validation_error", `${path} is not a file`, { path });
11983
12096
  if (stat.size > MAX_FILE_BYTES)
11984
12097
  throw tooLarge2(name2);
11985
- const bytes = new Uint8Array(readFileSync9(path));
12098
+ const bytes = new Uint8Array(readFileSync10(path));
11986
12099
  const extension = extname2(name2).toLowerCase();
11987
12100
  const mime = MIMES[extension] ?? null;
11988
12101
  const found = await extractText(bytes, { kind: "file", name: name2, mime, path }, load);
@@ -12184,7 +12297,7 @@ var sourcesCommand = /* @__PURE__ */ __name((program, streams, env, { fetch: fet
12184
12297
  mime: source?.mime ?? null,
12185
12298
  bytes: source?.size ?? null,
12186
12299
  // The row says a copy was kept; only the file itself says it still is.
12187
- kept: source === void 0 ? null : source.copy !== null && existsSync11(source.copy) ? "copy" : "text",
12300
+ kept: source === void 0 ? null : source.copy !== null && existsSync12(source.copy) ? "copy" : "text",
12188
12301
  chars: note.text.length,
12189
12302
  text: text3,
12190
12303
  textTruncated: truncated,
@@ -13310,14 +13423,19 @@ var createProgram = /* @__PURE__ */ __name(({ streams: raw = processStreams, env
13310
13423
  program.addCommand(scheduleCommand(env));
13311
13424
  digestCommand(program, streams, env);
13312
13425
  commandsCommand(program, streams);
13313
- const skill2 = customizeSharedCommand(skillCommand2(APP, new URL("../skills/cli-memo/SKILL.md", new URL("../program.js", import.meta.url).href)), "Memo installs its own stored-data instructions through its environment, prints the packaged primary skill without filesystem effects, and takes --json on each skill command because it has no global one.", () => {
13426
+ const skill2 = customizeSharedCommand(skillCommand2(APP, new URL("../skills/cli-memo/SKILL.md", new URL("../program.js", import.meta.url).href)), "Memo installs its own stored-data instructions through its environment, prints the packaged skills (morning-digest with the owner's brief from the store after it), and takes --json on each skill command because it has no global one.", () => {
13314
13427
  const out = answers(program, streams, env);
13428
+ let brief;
13315
13429
  const skill3 = skillCommand(APP, new URL("../skills/cli-memo/SKILL.md", new URL("../program.js", import.meta.url).href), (command) => {
13316
13430
  const json5 = command.opts().json === true;
13317
13431
  const renderer = createRenderer({ format: json5 ? "json" : "pretty", color: false, streams });
13432
+ const result = /* @__PURE__ */ __name((value) => {
13433
+ const shown3 = value;
13434
+ out.print(true, itemAnswer(shown3.content === void 0 ? value : { ...shown3, content: withBrief(shown3.content, brief) }));
13435
+ }, "result");
13318
13436
  return {
13319
- renderer: json5 ? { ...renderer, result: /* @__PURE__ */ __name((value) => out.print(true, itemAnswer(value)), "result") } : renderer,
13320
- streams,
13437
+ renderer: json5 ? { ...renderer, result } : renderer,
13438
+ streams: { ...streams, data: /* @__PURE__ */ __name((text3) => streams.data(withBrief(text3, brief)), "data") },
13321
13439
  env
13322
13440
  };
13323
13441
  }, {
@@ -13328,8 +13446,10 @@ var createProgram = /* @__PURE__ */ __name(({ streams: raw = processStreams, env
13328
13446
  for (const command of skill3.commands)
13329
13447
  command.option("--json", "print JSON");
13330
13448
  const show = skill3.commands.find((command) => command.name() === "show");
13331
- if (show)
13332
- annotate(show, { effects: NO_EFFECTS });
13449
+ show?.description(`${show.description()}; morning-digest ends with your brief from \`memo digest brief\` when you wrote one`);
13450
+ show?.hook("preAction", async (command) => {
13451
+ brief = command.args[0] === "morning-digest" ? await readBrief(env) : void 0;
13452
+ });
13333
13453
  return skill3;
13334
13454
  }, SHELL_OVERRIDES.skill);
13335
13455
  program.addCommand(skill2);