@wirecat/cli-memo 0.131.68 → 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.
- package/dist/bin/memo.js +2 -2
- package/dist/bundle/{app-server-PGZD3JUW.js → app-server-UP3AL2XQ.js} +10 -10
- package/dist/bundle/{auto-OVLXIZRU.js → auto-CVILDIC6.js} +17 -17
- package/dist/bundle/{chunk-JQREFZWM.js → chunk-2NFI7SDW.js} +5 -0
- package/dist/bundle/{chunk-EEBQN7TK.js → chunk-3OEV7GNU.js} +4 -4
- package/dist/bundle/{chunk-V6QYWGO4.js → chunk-3TFK7RBA.js} +3 -3
- package/dist/bundle/{chunk-5JPVRS7W.js → chunk-52F4LHCH.js} +3 -3
- package/dist/bundle/{chunk-KX7CVSAY.js → chunk-57SQU2YO.js} +4 -4
- package/dist/bundle/{chunk-FOF7KGG3.js → chunk-5EHUHZU5.js} +5 -5
- package/dist/bundle/{chunk-YVVRV3PQ.js → chunk-7OXLZZ27.js} +31 -1
- package/dist/bundle/{chunk-FSDAEZFS.js → chunk-EQKS6M52.js} +3 -3
- package/dist/bundle/{chunk-5EB34LNI.js → chunk-FQ54GW57.js} +8 -8
- package/dist/bundle/{chunk-FYWGFRR2.js → chunk-GGFL64HF.js} +1 -1
- package/dist/bundle/{chunk-5RYMHX2O.js → chunk-GVEY6743.js} +2 -2
- package/dist/bundle/{chunk-6A6HR2CS.js → chunk-GVP6CAPH.js} +3 -3
- package/dist/bundle/{chunk-4AH6FONF.js → chunk-IJAILIZR.js} +4 -4
- package/dist/bundle/{chunk-PUACXS7G.js → chunk-JMGQATR6.js} +1 -1
- package/dist/bundle/{chunk-BQYAMBKB.js → chunk-LYAJUZM4.js} +6 -6
- package/dist/bundle/{chunk-37H7TTWN.js → chunk-MYLNRBDF.js} +2 -2
- package/dist/bundle/{chunk-A3WUEOEV.js → chunk-OAO5UCPJ.js} +1 -1
- package/dist/bundle/{chunk-EOJPZ3LX.js → chunk-OHA7HDPX.js} +15 -15
- package/dist/bundle/{chunk-RG4GW7EY.js → chunk-QAXIZHK7.js} +9 -9
- package/dist/bundle/{chunk-WLD5XU3T.js → chunk-UEMI6FXR.js} +2 -2
- package/dist/bundle/{chunk-QHUPSOQT.js → chunk-XTEJXJJ3.js} +3 -3
- package/dist/bundle/{chunk-5EZOMIPL.js → chunk-YBTUFOQG.js} +4 -4
- package/dist/bundle/{chunk-AJMAR5DC.js → chunk-YXXAPVAZ.js} +4 -4
- package/dist/bundle/{command-contract-RX6RWHCT.js → command-contract-OGW2DX4C.js} +3 -3
- package/dist/bundle/{entry-XHWG43NW.js → entry-7S2ONYSF.js} +1 -1
- package/dist/bundle/{failure-Z7WOYPMA.js → failure-HM55W3NH.js} +15 -15
- package/dist/bundle/{first-run-FQ2BAEYK.js → first-run-MLIFZSVH.js} +1 -1
- package/dist/bundle/{first-screen-GP2QGKUA.js → first-screen-DGTTK6VK.js} +4 -4
- package/dist/bundle/{mcp-USR3ZFQU.js → mcp-CFIL7WZU.js} +7 -7
- package/dist/bundle/memo.js +6 -6
- package/dist/bundle/{program-FVSSLRBJ.js → program-RSUVU6HA.js} +250 -114
- package/dist/bundle/{server-YRZDZ2PZ.js → server-AASCSGCI.js} +10 -10
- package/dist/bundle/{server-3FW2MQRQ.js → server-BVRPQPGY.js} +20 -20
- package/dist/bundle/{server-SWSWXNDP.js → server-YQLPZK4Z.js} +7 -7
- package/dist/bundle/{store-PIQ4TF4O.js → store-VQQVUA4W.js} +2 -2
- package/dist/bundle/{store-maintenance-command-EWEXJ253.js → store-maintenance-command-GCBABKEZ.js} +6 -6
- package/dist/bundle/{update-6QYRXRVJ.js → update-ZE53ASCW.js} +16 -16
- package/dist/contract-overrides/skill.d.ts.map +1 -1
- package/dist/contract-overrides/skill.js +5 -10
- package/dist/contract-overrides/skill.js.map +1 -1
- package/dist/digest/backfill.d.ts.map +1 -1
- package/dist/digest/backfill.js +4 -2
- package/dist/digest/backfill.js.map +1 -1
- package/dist/digest/brief.d.ts +14 -0
- package/dist/digest/brief.d.ts.map +1 -0
- package/dist/digest/brief.js +143 -0
- package/dist/digest/brief.js.map +1 -0
- package/dist/examples.d.ts.map +1 -1
- package/dist/examples.js +10 -1
- package/dist/examples.js.map +1 -1
- package/dist/knowledge/command.d.ts.map +1 -1
- package/dist/knowledge/command.js +17 -6
- package/dist/knowledge/command.js.map +1 -1
- package/dist/knowledge/project-context.d.ts.map +1 -1
- package/dist/knowledge/project-context.js +3 -2
- package/dist/knowledge/project-context.js.map +1 -1
- package/dist/knowledge/relationships.d.ts.map +1 -1
- package/dist/knowledge/relationships.js +11 -2
- package/dist/knowledge/relationships.js.map +1 -1
- package/dist/program.d.ts.map +1 -1
- package/dist/program.js +16 -8
- package/dist/program.js.map +1 -1
- package/dist/reasons.d.ts.map +1 -1
- package/dist/reasons.js +30 -0
- package/dist/reasons.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -2
- package/skills/cli-memo/topics/projects.md +7 -0
|
@@ -6,17 +6,17 @@ import {
|
|
|
6
6
|
autoState,
|
|
7
7
|
lastAutoRun,
|
|
8
8
|
recordAutoRun
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-3OEV7GNU.js";
|
|
10
10
|
import {
|
|
11
11
|
installer,
|
|
12
12
|
latest,
|
|
13
13
|
upgradeCommand
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-YBTUFOQG.js";
|
|
15
15
|
import {
|
|
16
16
|
mcpOwnerAllowed,
|
|
17
17
|
readOnlyAvailability,
|
|
18
18
|
refuseWritesUnderLock
|
|
19
|
-
} from "./chunk-
|
|
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-
|
|
30
|
+
} from "./chunk-57SQU2YO.js";
|
|
31
31
|
import {
|
|
32
32
|
ATTACHMENT_CHARS,
|
|
33
33
|
DIALECTS,
|
|
@@ -59,7 +59,7 @@ import {
|
|
|
59
59
|
showMail,
|
|
60
60
|
unsetConfigKey,
|
|
61
61
|
updateConfig
|
|
62
|
-
} from "./chunk-
|
|
62
|
+
} from "./chunk-FQ54GW57.js";
|
|
63
63
|
import "./chunk-QP3KNC5D.js";
|
|
64
64
|
import "./chunk-TXOXPQN2.js";
|
|
65
65
|
import "./chunk-EO4JMJFZ.js";
|
|
@@ -67,7 +67,7 @@ import "./chunk-MWQI6FSU.js";
|
|
|
67
67
|
import {
|
|
68
68
|
errorObject,
|
|
69
69
|
recognisable
|
|
70
|
-
} from "./chunk-
|
|
70
|
+
} from "./chunk-52F4LHCH.js";
|
|
71
71
|
import {
|
|
72
72
|
AGENT_INPUT_MAX_CHARS,
|
|
73
73
|
DISCOVERY_DESCRIPTIONS,
|
|
@@ -112,7 +112,7 @@ import {
|
|
|
112
112
|
tasksStatsCommand,
|
|
113
113
|
templatesCommand,
|
|
114
114
|
withSqliteSidecars
|
|
115
|
-
} from "./chunk-
|
|
115
|
+
} from "./chunk-OHA7HDPX.js";
|
|
116
116
|
import "./chunk-7JFLHRQL.js";
|
|
117
117
|
import "./chunk-RHW3DDWI.js";
|
|
118
118
|
import {
|
|
@@ -121,7 +121,7 @@ import {
|
|
|
121
121
|
messageHitItem,
|
|
122
122
|
noteHitItem,
|
|
123
123
|
shownOf
|
|
124
|
-
} from "./chunk-
|
|
124
|
+
} from "./chunk-LYAJUZM4.js";
|
|
125
125
|
import "./chunk-OBQ7TSUB.js";
|
|
126
126
|
import {
|
|
127
127
|
REASONS as REASONS2,
|
|
@@ -129,15 +129,15 @@ import {
|
|
|
129
129
|
skillCommand,
|
|
130
130
|
skillPath,
|
|
131
131
|
skillVersion
|
|
132
|
-
} from "./chunk-
|
|
132
|
+
} from "./chunk-MYLNRBDF.js";
|
|
133
133
|
import {
|
|
134
134
|
recoveryNotes,
|
|
135
135
|
storeInfo,
|
|
136
136
|
storeRecoveryCheck,
|
|
137
137
|
storeRecoveryRun,
|
|
138
138
|
storeSummary
|
|
139
|
-
} from "./chunk-
|
|
140
|
-
import "./chunk-
|
|
139
|
+
} from "./chunk-5EHUHZU5.js";
|
|
140
|
+
import "./chunk-GVP6CAPH.js";
|
|
141
141
|
import {
|
|
142
142
|
LIST_QUERY_GUIDE,
|
|
143
143
|
STATUS_SIGNALS,
|
|
@@ -197,7 +197,7 @@ import {
|
|
|
197
197
|
timeLimit,
|
|
198
198
|
typedQuery,
|
|
199
199
|
withQuery
|
|
200
|
-
} from "./chunk-
|
|
200
|
+
} from "./chunk-3TFK7RBA.js";
|
|
201
201
|
import {
|
|
202
202
|
readBoundedUtf8File,
|
|
203
203
|
writeFileAtomic
|
|
@@ -206,9 +206,9 @@ import {
|
|
|
206
206
|
commandsText,
|
|
207
207
|
inSection,
|
|
208
208
|
installHelp
|
|
209
|
-
} from "./chunk-
|
|
209
|
+
} from "./chunk-UEMI6FXR.js";
|
|
210
210
|
import "./chunk-HTQTIKWP.js";
|
|
211
|
-
import "./chunk-
|
|
211
|
+
import "./chunk-JMGQATR6.js";
|
|
212
212
|
import {
|
|
213
213
|
Command,
|
|
214
214
|
DEFAULT_TEXT_MODEL,
|
|
@@ -245,15 +245,15 @@ import {
|
|
|
245
245
|
snakeKeys,
|
|
246
246
|
textModels,
|
|
247
247
|
textModelsFile
|
|
248
|
-
} from "./chunk-
|
|
248
|
+
} from "./chunk-OAO5UCPJ.js";
|
|
249
249
|
import "./chunk-N73YBQ42.js";
|
|
250
|
-
import "./chunk-
|
|
250
|
+
import "./chunk-XTEJXJJ3.js";
|
|
251
251
|
import {
|
|
252
252
|
isNewer
|
|
253
253
|
} from "./chunk-LJCT7YG6.js";
|
|
254
254
|
import "./chunk-L62FWN3Y.js";
|
|
255
255
|
import "./chunk-EDPA54WQ.js";
|
|
256
|
-
import "./chunk-
|
|
256
|
+
import "./chunk-GVEY6743.js";
|
|
257
257
|
import "./chunk-2DQYP2K3.js";
|
|
258
258
|
import "./chunk-22CDLXSR.js";
|
|
259
259
|
import {
|
|
@@ -303,7 +303,7 @@ import {
|
|
|
303
303
|
plainQuery,
|
|
304
304
|
providerNamed,
|
|
305
305
|
refLabel
|
|
306
|
-
} from "./chunk-
|
|
306
|
+
} from "./chunk-GGFL64HF.js";
|
|
307
307
|
import {
|
|
308
308
|
CATALOG_KINDS,
|
|
309
309
|
CONTRACT_KINDS,
|
|
@@ -311,6 +311,7 @@ import {
|
|
|
311
311
|
DEAL_KINDS,
|
|
312
312
|
DEAL_ROLES,
|
|
313
313
|
DEAL_STATUSES,
|
|
314
|
+
ENGAGEMENT_LEVELS,
|
|
314
315
|
FACT_STATUSES,
|
|
315
316
|
FACT_TYPES,
|
|
316
317
|
FINANCE_REVIEWS,
|
|
@@ -331,6 +332,7 @@ import {
|
|
|
331
332
|
TRANSACTION_STATUSES,
|
|
332
333
|
WALLET_KINDS,
|
|
333
334
|
WORK_TASK_TYPES,
|
|
335
|
+
byEngagement,
|
|
334
336
|
createUpcomingMeetingReader,
|
|
335
337
|
dateRange,
|
|
336
338
|
dayBoundary,
|
|
@@ -352,7 +354,7 @@ import {
|
|
|
352
354
|
timezoneOf,
|
|
353
355
|
validateQuery,
|
|
354
356
|
walkQuery
|
|
355
|
-
} from "./chunk-
|
|
357
|
+
} from "./chunk-2NFI7SDW.js";
|
|
356
358
|
import "./chunk-3LGLKLBA.js";
|
|
357
359
|
import "./chunk-TV75OHKJ.js";
|
|
358
360
|
import "./chunk-BGWPKEKK.js";
|
|
@@ -376,7 +378,7 @@ import {
|
|
|
376
378
|
REASONS,
|
|
377
379
|
STORE_CLIENT,
|
|
378
380
|
VERSION
|
|
379
|
-
} from "./chunk-
|
|
381
|
+
} from "./chunk-7OXLZZ27.js";
|
|
380
382
|
import "./chunk-DSU6UR2X.js";
|
|
381
383
|
import "./chunk-SYWHHQMC.js";
|
|
382
384
|
import "./chunk-D72URWJE.js";
|
|
@@ -4346,7 +4348,8 @@ var search = [
|
|
|
4346
4348
|
];
|
|
4347
4349
|
|
|
4348
4350
|
// dist/contract-overrides/skill.js
|
|
4349
|
-
var REASON2 = "Memo installs its own stored-data instructions through its environment, prints the packaged
|
|
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";
|
|
4350
4353
|
var JSON_OPTION2 = { flags: "--json", description: "print JSON", takes_value: false, mandatory: false };
|
|
4351
4354
|
var SHOW_FOR = {
|
|
4352
4355
|
flags: "--for <agents>",
|
|
@@ -4366,15 +4369,9 @@ var INSTALL_FOR = {
|
|
|
4366
4369
|
var skill = [
|
|
4367
4370
|
{
|
|
4368
4371
|
command: ["skill", "show"],
|
|
4369
|
-
field: "
|
|
4370
|
-
before:
|
|
4371
|
-
|
|
4372
|
-
local: "read"
|
|
4373
|
-
},
|
|
4374
|
-
after: {
|
|
4375
|
-
remote: "none",
|
|
4376
|
-
local: "none"
|
|
4377
|
-
},
|
|
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`,
|
|
4378
4375
|
reason: REASON2
|
|
4379
4376
|
},
|
|
4380
4377
|
{
|
|
@@ -4432,12 +4429,122 @@ var skill = [
|
|
|
4432
4429
|
var SHELL_OVERRIDES = { search, doctor, skill, mcp, commands, notes, meetings };
|
|
4433
4430
|
|
|
4434
4431
|
// dist/digest/backfill.js
|
|
4435
|
-
import { existsSync as
|
|
4436
|
-
import { join as
|
|
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");
|
|
4437
4544
|
|
|
4438
4545
|
// dist/digest/tasks.js
|
|
4439
|
-
import { existsSync as
|
|
4440
|
-
import { join as
|
|
4546
|
+
import { existsSync as existsSync6, readdirSync as readdirSync3 } from "node:fs";
|
|
4547
|
+
import { join as join6 } from "node:path";
|
|
4441
4548
|
|
|
4442
4549
|
// dist/tasks/list.js
|
|
4443
4550
|
import { createHash as createHash2 } from "node:crypto";
|
|
@@ -4607,13 +4714,13 @@ var countTasks = /* @__PURE__ */ __name(async (store, words) => {
|
|
|
4607
4714
|
}, "countTasks");
|
|
4608
4715
|
|
|
4609
4716
|
// dist/digest/sync-health.js
|
|
4610
|
-
import { existsSync as
|
|
4611
|
-
import { join as
|
|
4717
|
+
import { existsSync as existsSync5, readdirSync as readdirSync2, readFileSync as readFileSync6 } from "node:fs";
|
|
4718
|
+
import { join as join5 } from "node:path";
|
|
4612
4719
|
|
|
4613
4720
|
// dist/knowledge/messenger-sync.js
|
|
4614
4721
|
import { spawn } from "node:child_process";
|
|
4615
|
-
import { existsSync as
|
|
4616
|
-
import { delimiter, join as
|
|
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";
|
|
4617
4724
|
var STATE = {
|
|
4618
4725
|
tg: { appName: "tg-cli", envPrefix: "TG" },
|
|
4619
4726
|
max: { appName: "max-cli", envPrefix: "MAX" },
|
|
@@ -4633,10 +4740,10 @@ var syncProfileOf = /* @__PURE__ */ __name((value, previous = {}) => {
|
|
|
4633
4740
|
throw new InvalidArgumentError(`one profile per tool; ${tool} is already ${previous[tool]}`);
|
|
4634
4741
|
return { ...previous, [tool]: profile };
|
|
4635
4742
|
}, "syncProfileOf");
|
|
4636
|
-
var accountsDir = /* @__PURE__ */ __name((tool, env) =>
|
|
4743
|
+
var accountsDir = /* @__PURE__ */ __name((tool, env) => join4(resolvePaths({ appName: tool.appName, prefix: tool.envPrefix, env }).state, "accounts"), "accountsDir");
|
|
4637
4744
|
var signedInAccount = /* @__PURE__ */ __name((tool, profile, env) => {
|
|
4638
4745
|
try {
|
|
4639
|
-
return JSON.parse(
|
|
4746
|
+
return JSON.parse(readFileSync5(join4(accountsDir(tool, env), `${profile}.json`), "utf8"))?.account;
|
|
4640
4747
|
} catch {
|
|
4641
4748
|
return void 0;
|
|
4642
4749
|
}
|
|
@@ -4646,7 +4753,7 @@ var profileFor = /* @__PURE__ */ __name((provider, account2, env, chosen = {}) =
|
|
|
4646
4753
|
if (!tool)
|
|
4647
4754
|
return void 0;
|
|
4648
4755
|
const dir = accountsDir(tool, env);
|
|
4649
|
-
const profiles =
|
|
4756
|
+
const profiles = existsSync4(dir) ? readdirSync(dir).filter((name2) => name2.endsWith(".json")).map((name2) => name2.slice(0, -".json".length)).sort() : [];
|
|
4650
4757
|
const accountOf = /* @__PURE__ */ __name((profile) => signedInAccount(tool, profile, env), "accountOf");
|
|
4651
4758
|
const all = profiles.join(", ") || "none";
|
|
4652
4759
|
const pick = chosen[tool.tool];
|
|
@@ -4666,7 +4773,7 @@ var profileFor = /* @__PURE__ */ __name((provider, account2, env, chosen = {}) =
|
|
|
4666
4773
|
};
|
|
4667
4774
|
return { why: `no ${tool.tool} profile here is signed in to account ${account2}; profiles: ${all}`, profiles: [] };
|
|
4668
4775
|
}, "profileFor");
|
|
4669
|
-
var onPath = /* @__PURE__ */ __name((name2, env) => (env.PATH ?? "").split(delimiter).filter(Boolean).map((dir) =>
|
|
4776
|
+
var onPath = /* @__PURE__ */ __name((name2, env) => (env.PATH ?? "").split(delimiter).filter(Boolean).map((dir) => join4(dir, name2)).find((path) => {
|
|
4670
4777
|
try {
|
|
4671
4778
|
return statSync2(path).isFile();
|
|
4672
4779
|
} catch {
|
|
@@ -4722,7 +4829,7 @@ var binaryOf = /* @__PURE__ */ __name(async (provider, env, run) => {
|
|
|
4722
4829
|
const real = realpathSync(short);
|
|
4723
4830
|
if (real.includes(`/${mark}/`))
|
|
4724
4831
|
return short;
|
|
4725
|
-
return statSync2(real).size < 65536 &&
|
|
4832
|
+
return statSync2(real).size < 65536 && readFileSync5(real, "utf8").includes(mark) ? short : void 0;
|
|
4726
4833
|
}, "binaryOf");
|
|
4727
4834
|
var answerOf = /* @__PURE__ */ __name((stdout) => {
|
|
4728
4835
|
try {
|
|
@@ -4830,13 +4937,13 @@ var SOURCE_WORDS = {
|
|
|
4830
4937
|
var toolOf = /* @__PURE__ */ __name((provider) => provider === "email" ? MAIL2 : messengerToolOf(provider), "toolOf");
|
|
4831
4938
|
var stateDirs = /* @__PURE__ */ __name((tool, env) => resolvePaths({ appName: tool.appName, prefix: tool.envPrefix, env }), "stateDirs");
|
|
4832
4939
|
var schedulesOf = /* @__PURE__ */ __name((state) => {
|
|
4833
|
-
const dir =
|
|
4834
|
-
if (!
|
|
4940
|
+
const dir = join5(state, "schedules");
|
|
4941
|
+
if (!existsSync5(dir))
|
|
4835
4942
|
return [];
|
|
4836
4943
|
const last = new Map(scheduledRuns(state).map((one2) => [one2.job, one2.last]));
|
|
4837
4944
|
return readdirSync2(dir).flatMap((name2) => {
|
|
4838
4945
|
try {
|
|
4839
|
-
const schedule = JSON.parse(
|
|
4946
|
+
const schedule = JSON.parse(readFileSync6(join5(dir, name2, "schedule.json"), "utf8"));
|
|
4840
4947
|
return [
|
|
4841
4948
|
{
|
|
4842
4949
|
name: String(schedule.name),
|
|
@@ -4851,15 +4958,15 @@ var schedulesOf = /* @__PURE__ */ __name((state) => {
|
|
|
4851
4958
|
}
|
|
4852
4959
|
});
|
|
4853
4960
|
}, "schedulesOf");
|
|
4854
|
-
var signedIn = /* @__PURE__ */ __name((dir) =>
|
|
4961
|
+
var signedIn = /* @__PURE__ */ __name((dir) => existsSync5(dir) ? readdirSync2(dir).filter((name2) => name2.endsWith(".json")).map((name2) => name2.slice(0, -".json".length)) : [], "signedIn");
|
|
4855
4962
|
var profilesOf = /* @__PURE__ */ __name((provider, tool, env) => {
|
|
4856
4963
|
if (provider !== "email")
|
|
4857
|
-
return new Map(signedIn(
|
|
4964
|
+
return new Map(signedIn(join5(stateDirs(tool, env).state, "accounts")).map((profile) => [
|
|
4858
4965
|
profile,
|
|
4859
4966
|
signedInAccount(tool, profile, env)
|
|
4860
4967
|
]));
|
|
4861
4968
|
try {
|
|
4862
|
-
const config = JSON.parse(
|
|
4969
|
+
const config = JSON.parse(readFileSync6(configFilePath(stateDirs(MAIL2, env).config), "utf8"));
|
|
4863
4970
|
return new Map(Object.entries(config?.profiles ?? {}).map(([profile, one2]) => [
|
|
4864
4971
|
profile,
|
|
4865
4972
|
one2?.address
|
|
@@ -4949,8 +5056,8 @@ var runTime = /* @__PURE__ */ __name((file) => {
|
|
|
4949
5056
|
}, "runTime");
|
|
4950
5057
|
var digestReportTimes = /* @__PURE__ */ __name((env) => {
|
|
4951
5058
|
const { state, schedule } = digestSchedule(env);
|
|
4952
|
-
const runs = schedule ?
|
|
4953
|
-
if (!runs || !
|
|
5059
|
+
const runs = schedule ? join6(state, "schedules", schedule.name, "runs") : void 0;
|
|
5060
|
+
if (!runs || !existsSync6(runs))
|
|
4954
5061
|
return [];
|
|
4955
5062
|
return readdirSync3(runs).filter((file) => file.endsWith(".report.json")).map(runTime).filter((at) => !Number.isNaN(at)).sort((a, b) => a - b);
|
|
4956
5063
|
}, "digestReportTimes");
|
|
@@ -5079,7 +5186,8 @@ var usd = /* @__PURE__ */ __name((value) => `$${value.toFixed(2)}`, "usd");
|
|
|
5079
5186
|
var cents = /* @__PURE__ */ __name((value) => Math.round(value * 100) / 100, "cents");
|
|
5080
5187
|
var digestCommand = /* @__PURE__ */ __name((program, streams, env) => {
|
|
5081
5188
|
const { print } = answers(program, streams, env);
|
|
5082
|
-
const digest = program.command("digest").description("the morning digest
|
|
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);
|
|
5083
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) => {
|
|
5084
5192
|
const from = dateOf(given2.from, "--from");
|
|
5085
5193
|
const to = dateOf(given2.to, "--to");
|
|
@@ -5100,8 +5208,8 @@ var digestCommand = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
5100
5208
|
throw new CliError("validation_error", `the ${given2.to} digest's time has not come yet; --to an earlier day`, {
|
|
5101
5209
|
param: "--to"
|
|
5102
5210
|
});
|
|
5103
|
-
const runs =
|
|
5104
|
-
const done = new Set((
|
|
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))));
|
|
5105
5213
|
const days2 = all.filter((day2) => !done.has(day2.date));
|
|
5106
5214
|
const skipped = all.filter((day2) => done.has(day2.date)).map((day2) => day2.date);
|
|
5107
5215
|
const lastCost = schedule.last?.costUsd;
|
|
@@ -5246,9 +5354,9 @@ var commandsCommand = /* @__PURE__ */ __name((program, streams) => {
|
|
|
5246
5354
|
}, "commandsCommand");
|
|
5247
5355
|
|
|
5248
5356
|
// dist/doctor/command.js
|
|
5249
|
-
import { existsSync as
|
|
5357
|
+
import { existsSync as existsSync8, readdirSync as readdirSync5, readFileSync as readFileSync7 } from "node:fs";
|
|
5250
5358
|
import { homedir } from "node:os";
|
|
5251
|
-
import { dirname, join as
|
|
5359
|
+
import { dirname, join as join8 } from "node:path";
|
|
5252
5360
|
var retiredMailAddresses = /* @__PURE__ */ __name((mail) => {
|
|
5253
5361
|
const accounts = mail?.accounts;
|
|
5254
5362
|
if (!Array.isArray(accounts))
|
|
@@ -5274,7 +5382,7 @@ var diagnose = /* @__PURE__ */ __name(async (env, program, { deep = false } = {}
|
|
|
5274
5382
|
problems.push({ what: "the store is from a newer version than this memo", fix: "memo upgrade" });
|
|
5275
5383
|
const folders = noteFolders(config.notes).map(({ path, id }) => ({
|
|
5276
5384
|
path,
|
|
5277
|
-
exists:
|
|
5385
|
+
exists: existsSync8(path),
|
|
5278
5386
|
bound: id !== null
|
|
5279
5387
|
}));
|
|
5280
5388
|
for (const folder of folders) {
|
|
@@ -5305,13 +5413,13 @@ var diagnose = /* @__PURE__ */ __name(async (env, program, { deep = false } = {}
|
|
|
5305
5413
|
fix: `fix text_models in ${textModelsFile(env)}, or remove it to go back to ${DEFAULT_TEXT_MODEL}`
|
|
5306
5414
|
});
|
|
5307
5415
|
}
|
|
5308
|
-
const modelDir =
|
|
5309
|
-
const model =
|
|
5416
|
+
const modelDir = join8(sharedModelsDirectory("text", env), textModel);
|
|
5417
|
+
const model = existsSync8(modelDir) && readdirSync5(modelDir).length > 0;
|
|
5310
5418
|
const state = autoState(config);
|
|
5311
|
-
const unitFile =
|
|
5312
|
-
const unit =
|
|
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;
|
|
5313
5421
|
const runs = unit ? unitPaths(unit) : [];
|
|
5314
|
-
const missing = runs.filter((path) => !
|
|
5422
|
+
const missing = runs.filter((path) => !existsSync8(path));
|
|
5315
5423
|
const last = lastAutoRun(env);
|
|
5316
5424
|
const failing = last && last.exitCode !== 0 ? { since: last.failingSince ?? last.at, runs: last.failures ?? 1, reason: last.reason ?? null } : null;
|
|
5317
5425
|
if (state.enabled && !unit)
|
|
@@ -5322,7 +5430,7 @@ var diagnose = /* @__PURE__ */ __name(async (env, program, { deep = false } = {}
|
|
|
5322
5430
|
problems.push({ what: `the timer has failed ${failing.runs} runs since ${failing.since}`, fix: "memo jobs status" });
|
|
5323
5431
|
const skills = SKILL_TARGETS.map((target) => {
|
|
5324
5432
|
const path = skillPath(target, APP.appName, env);
|
|
5325
|
-
const version =
|
|
5433
|
+
const version = existsSync8(path) ? skillVersion(readFileSync7(path, "utf8")) ?? "unknown" : null;
|
|
5326
5434
|
return { target, path, version };
|
|
5327
5435
|
});
|
|
5328
5436
|
if (skills.some(({ version }) => version !== null && version !== VERSION))
|
|
@@ -5951,10 +6059,12 @@ var EXAMPLES = {
|
|
|
5951
6059
|
"projects key-documents list": ["memo projects key-documents list HRB"],
|
|
5952
6060
|
"relationships update": [
|
|
5953
6061
|
"memo relationships update 12 --purpose sales",
|
|
5954
|
-
"memo relationships update 12 --
|
|
6062
|
+
"memo relationships update 12 --engagement low",
|
|
6063
|
+
"memo relationships update 12 --role approver --role-note 'signs the acts'"
|
|
5955
6064
|
],
|
|
5956
6065
|
"relationships add": [
|
|
5957
6066
|
"memo relationships add person:3 organization:1 --role employee",
|
|
6067
|
+
"memo relationships add person:3 project:1 --role client-contact --engagement low",
|
|
5958
6068
|
"memo relationships add project:2 organization:1 --kind related-to --reason 'same client'"
|
|
5959
6069
|
],
|
|
5960
6070
|
"relationships list": ['memo relationships list about:"person:3"', "memo relationships list confirmed:false"],
|
|
@@ -6190,6 +6300,13 @@ var EXAMPLES = {
|
|
|
6190
6300
|
"memo digest backfill --from 2026-11-01 --to 2026-11-07",
|
|
6191
6301
|
"memo digest backfill --from 2026-11-01 --to 2026-11-07 --yes --json"
|
|
6192
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"],
|
|
6193
6310
|
"schedule remove": ["memo schedule remove digest"],
|
|
6194
6311
|
"schedule exec": ["memo schedule exec ~/.local/state/cli-memo/schedules/digest/schedule.json"],
|
|
6195
6312
|
"templates list": ["memo templates list", "memo templates list channel:telegram source:stored --json"],
|
|
@@ -8441,7 +8558,7 @@ var projectFindings = /* @__PURE__ */ __name(async (store, project, links) => {
|
|
|
8441
8558
|
// dist/knowledge/project-context.js
|
|
8442
8559
|
var projectContext = /* @__PURE__ */ __name(async (store, env, reference2) => {
|
|
8443
8560
|
const project = await projectOf(store, reference2);
|
|
8444
|
-
const relationships = (await store.notes.links({ to: project.ref })).concat(await store.notes.links({ from: project.ref })).filter((link2) => link2.kind !== "about" && link2.kind !== "links-to" && link2.role !== "key");
|
|
8561
|
+
const relationships = byEngagement((await store.notes.links({ to: project.ref })).concat(await store.notes.links({ from: project.ref })).filter((link2) => link2.kind !== "about" && link2.kind !== "links-to" && link2.role !== "key"));
|
|
8445
8562
|
const documents = await keyDocuments(store, project);
|
|
8446
8563
|
const pending2 = /* @__PURE__ */ __name((kind) => proposalRegistry(store).list({ project: project.ref, kinds: [kind], status: "proposed", limit: 50, offset: 0 }), "pending");
|
|
8447
8564
|
const [facts, tasks, findings, keys, links, waiting2] = await Promise.all([
|
|
@@ -8898,7 +9015,7 @@ var listRelationships = /* @__PURE__ */ __name(async (store, words) => {
|
|
|
8898
9015
|
const confirmed = terms2.get("confirmed");
|
|
8899
9016
|
const found = confirmed === "false" ? await pending(store, about) : {
|
|
8900
9017
|
hasMore: false,
|
|
8901
|
-
items: (await store.knowledge.relations(null, about)).filter((one2) => confirmed === void 0 || one2.confirmed).map((one2) => ({ ...one2, status: one2.confirmed ? "confirmed" : "proposed" }))
|
|
9018
|
+
items: byEngagement(await store.knowledge.relations(null, about)).filter((one2) => confirmed === void 0 || one2.confirmed).map((one2) => ({ ...one2, status: one2.confirmed ? "confirmed" : "proposed" }))
|
|
8902
9019
|
};
|
|
8903
9020
|
const label = await labelsFor(store, found.items.flatMap((one2) => [one2.from, one2.to]));
|
|
8904
9021
|
return {
|
|
@@ -8910,7 +9027,13 @@ var listRelationships = /* @__PURE__ */ __name(async (store, words) => {
|
|
|
8910
9027
|
var relationshipsText = /* @__PURE__ */ __name((items) => items.length ? items.map((one2) => [
|
|
8911
9028
|
one2.id,
|
|
8912
9029
|
`${one2.fromTitle} \u2192 ${one2.toTitle}`,
|
|
8913
|
-
[
|
|
9030
|
+
[
|
|
9031
|
+
one2.kind,
|
|
9032
|
+
one2.role && `as ${one2.role}`,
|
|
9033
|
+
"roleNote" in one2 && one2.roleNote && `(${one2.roleNote})`,
|
|
9034
|
+
one2.purpose && `for ${one2.purpose}`,
|
|
9035
|
+
"engagement" in one2 && one2.engagement && `engagement ${one2.engagement}`
|
|
9036
|
+
].filter(Boolean).join(" "),
|
|
8914
9037
|
"proposer" in one2 ? `proposed by ${one2.proposer}` : one2.confirmed ? "" : "suggested"
|
|
8915
9038
|
].filter(Boolean).join(" ")).join("\n") : "no relationships", "relationshipsText");
|
|
8916
9039
|
|
|
@@ -8924,6 +9047,7 @@ var pendingLink = /* @__PURE__ */ __name(async (store, id) => {
|
|
|
8924
9047
|
throw error;
|
|
8925
9048
|
}
|
|
8926
9049
|
}, "pendingLink");
|
|
9050
|
+
var ENGAGEMENT_HELP = "a person on a project: how much you deal with them yourself, not how active they are: none, low, medium or high";
|
|
8927
9051
|
var knowledgeCommands = /* @__PURE__ */ __name((program, streams, env) => {
|
|
8928
9052
|
const { run, print } = answers(program, streams, env);
|
|
8929
9053
|
const warn = /* @__PURE__ */ __name((text3) => streams.diagnostic(text3), "warn");
|
|
@@ -9001,7 +9125,7 @@ var knowledgeCommands = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
9001
9125
|
return ownedList("projects key-documents list", options, async (store) => keyDocuments(store, await projectOf(store, project), id === void 0 ? {} : { id }));
|
|
9002
9126
|
});
|
|
9003
9127
|
const relations = program.command("relationships").description("relations between people, organizations and projects; never between identities");
|
|
9004
|
-
byOption(annotate(relations.command("add"), { effects: LOCAL_WRITE }).description("state that a person, organization or project belongs to or relates to another, or that a chat is a project's (member-of only); an agent's waits for you to confirm it").summary("state that a person, organization, project or chat belongs or relates to another")).argument("<from>", "the person:, organization: or project: that belongs or relates, or chat:<provider>/<account>/<chat> of a project").argument("<to>", "the person:, organization: or project: it belongs or relates to").option("--json", "print JSON; --json=id,title keeps only those fields").option("--kind <kind>", "member-of or related-to", "member-of").option("--role <role>", "the role it has there; a person's role in an organization or a project is one from its list, such as employee or contributor").option("--reason <text>", "why you think so, in a sentence").action(async (from, to, options, command) => {
|
|
9128
|
+
byOption(annotate(relations.command("add"), { effects: LOCAL_WRITE }).description("state that a person, organization or project belongs to or relates to another, or that a chat is a project's (member-of only); an agent's waits for you to confirm it").summary("state that a person, organization, project or chat belongs or relates to another")).argument("<from>", "the person:, organization: or project: that belongs or relates, or chat:<provider>/<account>/<chat> of a project").argument("<to>", "the person:, organization: or project: it belongs or relates to").option("--json", "print JSON; --json=id,title keeps only those fields").option("--kind <kind>", "member-of or related-to", "member-of").option("--role <role>", "the role it has there; a person's role in an organization or a project is one from its list, such as employee or contributor").option("--role-note <text>", "what the role means here, in your words, beside a role from its list").option("--engagement <level>", ENGAGEMENT_HELP, oneOf(ENGAGEMENT_LEVELS)).option("--reason <text>", "why you think so, in a sentence").action(async (from, to, options, command) => {
|
|
9005
9129
|
const by = await whoRuns(command, env, { asOwner: options.asOwner, question: "state it as yours?" });
|
|
9006
9130
|
return owned(options, async (store) => {
|
|
9007
9131
|
const input = {
|
|
@@ -9009,6 +9133,8 @@ var knowledgeCommands = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
9009
9133
|
to: await withOwner(store, to),
|
|
9010
9134
|
kind: options.kind,
|
|
9011
9135
|
...options.role === void 0 ? {} : { role: options.role },
|
|
9136
|
+
...options.roleNote === void 0 ? {} : { roleNote: options.roleNote },
|
|
9137
|
+
...options.engagement === void 0 ? {} : { engagement: options.engagement },
|
|
9012
9138
|
...options.reason === void 0 ? {} : { evidence: options.reason }
|
|
9013
9139
|
};
|
|
9014
9140
|
return by === "owner" ? store.knowledge.relate(null, { ...input, by }) : store.knowledge.relate(null, { ...input, by });
|
|
@@ -9018,15 +9144,18 @@ var knowledgeCommands = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
9018
9144
|
const found = await withStore(env, (store) => listRelationships(store, words));
|
|
9019
9145
|
print(options.json, listAnswer("relationships list", { items: found.items, limit: found.limit, has_more: found.hasMore }), relationshipsText(found.items));
|
|
9020
9146
|
});
|
|
9021
|
-
byOption(annotate(relations.command("update"), { effects: LOCAL_WRITE }).description("set what a relationship is: its role, or what a chat is for in a project (work, sales, support, other); an agent's change waits for you in memo review").summary("set a relationship's role or a chat's purpose in a project").argument("<id>", "the relationship's id, as relationships list gives it").option("--role <role>", "the role it has there, from the same list as relationships add; an empty value clears it").option("--purpose <purpose>", "what the chat is for in the project: work, sales, support or other").option("--reason <text>", "why, in a sentence").option("--json", "print JSON; --json=id,title keeps only those fields")).action(async (id, options, command) => {
|
|
9147
|
+
byOption(annotate(relations.command("update"), { effects: LOCAL_WRITE }).description("set what a relationship is: its role and a note beside it, how much you deal with a person on a project, or what a chat is for in a project (work, sales, support, other); an agent's change waits for you in memo review").summary("set a relationship's role, engagement or a chat's purpose in a project").argument("<id>", "the relationship's id, as relationships list gives it").option("--role <role>", "the role it has there, from the same list as relationships add; an empty value clears it").option("--role-note <text>", "what the role means here, in your words; an empty value clears it").option("--engagement <level>", `${ENGAGEMENT_HELP}; an empty value clears it`, (value) => value === "" ? "" : oneOf(ENGAGEMENT_LEVELS)(value)).option("--purpose <purpose>", "what the chat is for in the project: work, sales, support or other").option("--reason <text>", "why, in a sentence").option("--json", "print JSON; --json=id,title keeps only those fields")).action(async (id, options, command) => {
|
|
9148
|
+
const cleared = /* @__PURE__ */ __name((value) => value === "" ? null : value, "cleared");
|
|
9022
9149
|
const change = {
|
|
9023
|
-
...options.role === void 0 ? {} : { role: options.role
|
|
9150
|
+
...options.role === void 0 ? {} : { role: cleared(options.role) },
|
|
9151
|
+
...options.roleNote === void 0 ? {} : { roleNote: cleared(options.roleNote) },
|
|
9152
|
+
...options.engagement === void 0 ? {} : { engagement: cleared(options.engagement) },
|
|
9024
9153
|
...options.purpose === void 0 ? {} : { purpose: options.purpose }
|
|
9025
9154
|
};
|
|
9026
9155
|
const by = await whoRuns(command, env, { asOwner: options.asOwner, question: `change relationship ${id}?` });
|
|
9027
9156
|
return owned(options, (store) => {
|
|
9028
|
-
if (
|
|
9029
|
-
throw new CliError("validation_error", "say what to change: --role, --
|
|
9157
|
+
if (!Object.keys(change).length)
|
|
9158
|
+
throw new CliError("validation_error", "say what to change: --role, --role-note, --engagement or --purpose", {
|
|
9030
9159
|
reason: "input.invalid",
|
|
9031
9160
|
param: "--purpose"
|
|
9032
9161
|
});
|
|
@@ -9490,9 +9619,9 @@ var messagesCommand = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
9490
9619
|
}, "messagesCommand");
|
|
9491
9620
|
|
|
9492
9621
|
// dist/mcp/command.js
|
|
9493
|
-
import { join as
|
|
9622
|
+
import { join as join9 } from "node:path";
|
|
9494
9623
|
var DEFAULT_PORT = 8767;
|
|
9495
|
-
var httpTokenFile = /* @__PURE__ */ __name((env) =>
|
|
9624
|
+
var httpTokenFile = /* @__PURE__ */ __name((env) => join9(resolvePaths({ appName: APP.appName, prefix: APP.envPrefix, env }).state, "mcp-http", "memo.json"), "httpTokenFile");
|
|
9496
9625
|
var mcpCommandDefinition = /* @__PURE__ */ __name((program, streams, env, createProgram2) => {
|
|
9497
9626
|
const out = answers(program, streams, env);
|
|
9498
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`");
|
|
@@ -9504,10 +9633,10 @@ var mcpCommandDefinition = /* @__PURE__ */ __name((program, streams, env, create
|
|
|
9504
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) => {
|
|
9505
9634
|
if (!options.http && (options.port !== void 0 || options.publicUrl !== void 0))
|
|
9506
9635
|
throw new CliError("validation_error", "--port and --public-url require --http");
|
|
9507
|
-
const { createMemoServer } = await import("./server-
|
|
9636
|
+
const { createMemoServer } = await import("./server-BVRPQPGY.js");
|
|
9508
9637
|
const build = /* @__PURE__ */ __name(() => createMemoServer(env, createProgram2, options.permission), "build");
|
|
9509
9638
|
if (options.http) {
|
|
9510
|
-
const { httpLockFile, mcpUrlOf, portOf, publicUrlOf, serveOverHttp } = await import("./mcp-
|
|
9639
|
+
const { httpLockFile, mcpUrlOf, portOf, publicUrlOf, serveOverHttp } = await import("./mcp-CFIL7WZU.js");
|
|
9511
9640
|
const publicUrl = publicUrlOf(options.publicUrl, {
|
|
9512
9641
|
missing: "--http",
|
|
9513
9642
|
reaches: "the browser apps reach memo",
|
|
@@ -9559,7 +9688,7 @@ var mcpCommandDefinition = /* @__PURE__ */ __name((program, streams, env, create
|
|
|
9559
9688
|
});
|
|
9560
9689
|
});
|
|
9561
9690
|
annotate(mcp2.command("revoke"), { effects: LOCAL_WRITE, mcp: false, examples: ["memo mcp revoke --json"] }).summary("forget every login given to a browser app").description("forget every login `memo mcp serve --http` gave a browser app; each app must log in again").option("--json", "print JSON").action(async function() {
|
|
9562
|
-
const { revokeAll } = await import("./mcp-
|
|
9691
|
+
const { revokeAll } = await import("./mcp-CFIL7WZU.js");
|
|
9563
9692
|
revokeAll(httpTokenFile(env));
|
|
9564
9693
|
out.print(this.opts().json, itemAnswer({ revoked: true }));
|
|
9565
9694
|
});
|
|
@@ -9850,7 +9979,7 @@ var modelsCommand = /* @__PURE__ */ __name((program, streams, env, keyring) => {
|
|
|
9850
9979
|
}, "modelsCommand");
|
|
9851
9980
|
|
|
9852
9981
|
// dist/notes/command.js
|
|
9853
|
-
import { readFileSync as
|
|
9982
|
+
import { readFileSync as readFileSync9 } from "node:fs";
|
|
9854
9983
|
|
|
9855
9984
|
// dist/people/identity.js
|
|
9856
9985
|
var identityOf = /* @__PURE__ */ __name(async (store, reference2) => {
|
|
@@ -9888,8 +10017,8 @@ import { resolve as resolve3 } from "node:path";
|
|
|
9888
10017
|
|
|
9889
10018
|
// dist/notes/export.js
|
|
9890
10019
|
import { createHash as createHash3 } from "node:crypto";
|
|
9891
|
-
import { existsSync as
|
|
9892
|
-
import { join as
|
|
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";
|
|
9893
10022
|
var HASH_LINE = /^memo-hash: .*\r?\n/m;
|
|
9894
10023
|
var PLACEHOLDER = "f".repeat(64);
|
|
9895
10024
|
var UNSAFE = /[\\/:*?"<>|#^[\]\p{Cc}]/gu;
|
|
@@ -9913,7 +10042,7 @@ var exportedIn = /* @__PURE__ */ __name((dir) => {
|
|
|
9913
10042
|
for (const entry of readdirSync6(dir, { withFileTypes: true })) {
|
|
9914
10043
|
if (!entry.isFile() || !/\.(md|markdown)$/i.test(entry.name))
|
|
9915
10044
|
continue;
|
|
9916
|
-
const id = readMemoId(
|
|
10045
|
+
const id = readMemoId(join10(dir, entry.name));
|
|
9917
10046
|
if (id !== null)
|
|
9918
10047
|
found.set(id, entry.name);
|
|
9919
10048
|
}
|
|
@@ -9930,11 +10059,11 @@ var exportNotes = /* @__PURE__ */ __name(({ dir, dialect, notes: notes2 }) => {
|
|
|
9930
10059
|
frontMatter["memo-hash"] = PLACEHOLDER;
|
|
9931
10060
|
const content = withHash(dialect.render({ ...note, frontMatter }));
|
|
9932
10061
|
const known2 = existing.get(id);
|
|
9933
|
-
const name2 = known2 ?? fileName(note.title, id, (candidate) => claimed.has(candidate) ||
|
|
10062
|
+
const name2 = known2 ?? fileName(note.title, id, (candidate) => claimed.has(candidate) || existsSync9(join10(dir, candidate)));
|
|
9934
10063
|
claimed.add(name2);
|
|
9935
|
-
const path =
|
|
10064
|
+
const path = join10(dir, name2);
|
|
9936
10065
|
if (known2 !== void 0) {
|
|
9937
|
-
const current =
|
|
10066
|
+
const current = readFileSync8(path, "utf8");
|
|
9938
10067
|
if (editedSinceExport(current)) {
|
|
9939
10068
|
result.edited.push({ path, id });
|
|
9940
10069
|
continue;
|
|
@@ -9944,8 +10073,8 @@ var exportNotes = /* @__PURE__ */ __name(({ dir, dialect, notes: notes2 }) => {
|
|
|
9944
10073
|
continue;
|
|
9945
10074
|
}
|
|
9946
10075
|
}
|
|
9947
|
-
const partial =
|
|
9948
|
-
|
|
10076
|
+
const partial = join10(dir, `.${name2}.memo-tmp`);
|
|
10077
|
+
writeFileSync4(partial, content);
|
|
9949
10078
|
renameSync2(partial, path);
|
|
9950
10079
|
result.written.push(path);
|
|
9951
10080
|
}
|
|
@@ -10045,7 +10174,7 @@ var textOf = /* @__PURE__ */ __name((options, given2) => {
|
|
|
10045
10174
|
if (sources.length !== 1)
|
|
10046
10175
|
throw new CliError("validation_error", "give the text once: as an argument, --text or --text-file");
|
|
10047
10176
|
if (options.textFile !== void 0)
|
|
10048
|
-
return
|
|
10177
|
+
return readFileSync9(options.textFile === "-" ? 0 : options.textFile, "utf8");
|
|
10049
10178
|
return sources[0];
|
|
10050
10179
|
}, "textOf");
|
|
10051
10180
|
var noteOf = /* @__PURE__ */ __name(async (store, env, reference2) => {
|
|
@@ -10201,9 +10330,9 @@ import { statSync as statSync4 } from "node:fs";
|
|
|
10201
10330
|
import { basename as basename2, resolve as resolve4 } from "node:path";
|
|
10202
10331
|
|
|
10203
10332
|
// dist/run/lock.js
|
|
10204
|
-
import { join as
|
|
10333
|
+
import { join as join11 } from "node:path";
|
|
10205
10334
|
var withImportLock = /* @__PURE__ */ __name(async (env, work) => {
|
|
10206
|
-
const lock =
|
|
10335
|
+
const lock = join11(resolvePaths({ appName: "cli-memo", prefix: "MEMO", env }).state, "import.lock");
|
|
10207
10336
|
const holder = takeLock(lock, { pid: process.pid, startedAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
10208
10337
|
if (holder !== void 0)
|
|
10209
10338
|
throw new CliError("rate_limited", `another memo sync is running (process ${holder.pid}); try again when it ends`, {
|
|
@@ -10334,7 +10463,7 @@ var foldersCommand = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
10334
10463
|
}, "foldersCommand");
|
|
10335
10464
|
|
|
10336
10465
|
// dist/people/command.js
|
|
10337
|
-
import { join as
|
|
10466
|
+
import { join as join12 } from "node:path";
|
|
10338
10467
|
var noteCommand = /* @__PURE__ */ __name((program, streams, env) => {
|
|
10339
10468
|
const notes2 = program.commands.find((command) => command.name() === "notes") ?? program.command("notes");
|
|
10340
10469
|
const links = notes2.command("links").description("imported note files linked to the person behind an identity");
|
|
@@ -10387,7 +10516,7 @@ var noteCommand = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
10387
10516
|
}
|
|
10388
10517
|
const paths = (await files()).map(({ note }) => {
|
|
10389
10518
|
const folder = folders.find((candidate) => candidate.id === note.folderId);
|
|
10390
|
-
return folder ?
|
|
10519
|
+
return folder ? join12(folder.path, note.path) : note.ref;
|
|
10391
10520
|
});
|
|
10392
10521
|
return { person: to, name: person.name ?? person.uid, files: paths };
|
|
10393
10522
|
});
|
|
@@ -10830,8 +10959,8 @@ ${SOURCE_REVIEW_HELP}`);
|
|
|
10830
10959
|
}, "reviewCommand");
|
|
10831
10960
|
|
|
10832
10961
|
// dist/notes/embed.js
|
|
10833
|
-
import { existsSync as
|
|
10834
|
-
import { join as
|
|
10962
|
+
import { existsSync as existsSync10, readdirSync as readdirSync7 } from "node:fs";
|
|
10963
|
+
import { join as join13 } from "node:path";
|
|
10835
10964
|
var EMBED_PER_RUN = 600;
|
|
10836
10965
|
var SLOWEST_KNOWN = 2;
|
|
10837
10966
|
var embedPerRun = /* @__PURE__ */ __name((env = process.env) => {
|
|
@@ -10848,8 +10977,8 @@ var missingModel = /* @__PURE__ */ __name((error, env) => {
|
|
|
10848
10977
|
}, "missingModel");
|
|
10849
10978
|
var searchModelPresent = /* @__PURE__ */ __name((env) => {
|
|
10850
10979
|
try {
|
|
10851
|
-
const path =
|
|
10852
|
-
return
|
|
10980
|
+
const path = join13(sharedModelsDirectory("text", env), chosenTextModel(env).id);
|
|
10981
|
+
return existsSync10(path) && readdirSync7(path).length > 0;
|
|
10853
10982
|
} catch {
|
|
10854
10983
|
return false;
|
|
10855
10984
|
}
|
|
@@ -11330,8 +11459,8 @@ var searchText = /* @__PURE__ */ __name((result, offset = 0) => [
|
|
|
11330
11459
|
].join("\n"), "searchText");
|
|
11331
11460
|
|
|
11332
11461
|
// dist/search/hits.js
|
|
11333
|
-
var
|
|
11334
|
-
var briefHit = /* @__PURE__ */ __name((hit) => Object.fromEntries(
|
|
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");
|
|
11335
11464
|
|
|
11336
11465
|
// dist/search/answers.js
|
|
11337
11466
|
var named4 = /* @__PURE__ */ __name((accounts) => [
|
|
@@ -11752,29 +11881,29 @@ var showCommand = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
11752
11881
|
}, "showCommand");
|
|
11753
11882
|
|
|
11754
11883
|
// dist/sources/command.js
|
|
11755
|
-
import { existsSync as
|
|
11884
|
+
import { existsSync as existsSync12 } from "node:fs";
|
|
11756
11885
|
|
|
11757
11886
|
// dist/sources/copy.js
|
|
11758
11887
|
import { randomUUID } from "node:crypto";
|
|
11759
|
-
import { existsSync as
|
|
11760
|
-
import { isAbsolute, join as
|
|
11761
|
-
var copiesDir = /* @__PURE__ */ __name((env) =>
|
|
11762
|
-
var copyPath = /* @__PURE__ */ __name((env, hash) =>
|
|
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");
|
|
11763
11892
|
var keepCopy = /* @__PURE__ */ __name((env, hash, bytes) => {
|
|
11764
11893
|
const path = copyPath(env, hash);
|
|
11765
|
-
if (
|
|
11894
|
+
if (existsSync11(path))
|
|
11766
11895
|
return { path, wrote: false };
|
|
11767
11896
|
mkdirSync4(copiesDir(env), { recursive: true, mode: 448 });
|
|
11768
11897
|
const partial = `${path}.${randomUUID()}.part`;
|
|
11769
|
-
|
|
11898
|
+
writeFileSync5(partial, bytes, { mode: 384 });
|
|
11770
11899
|
renameSync3(partial, path);
|
|
11771
11900
|
return { path, wrote: true };
|
|
11772
11901
|
}, "keepCopy");
|
|
11773
11902
|
var dropCopy = /* @__PURE__ */ __name((env, path) => {
|
|
11774
11903
|
const inside2 = relative2(resolve5(copiesDir(env)), resolve5(path));
|
|
11775
|
-
if (!inside2 || isAbsolute(inside2) || inside2.startsWith("..") || inside2.includes(sep2) || !
|
|
11904
|
+
if (!inside2 || isAbsolute(inside2) || inside2.startsWith("..") || inside2.includes(sep2) || !existsSync11(path))
|
|
11776
11905
|
return false;
|
|
11777
|
-
|
|
11906
|
+
rmSync3(path);
|
|
11778
11907
|
return true;
|
|
11779
11908
|
}, "dropCopy");
|
|
11780
11909
|
|
|
@@ -11848,7 +11977,7 @@ ${note.text}`);
|
|
|
11848
11977
|
}, "namedIn");
|
|
11849
11978
|
|
|
11850
11979
|
// dist/sources/read.js
|
|
11851
|
-
import { readFileSync as
|
|
11980
|
+
import { readFileSync as readFileSync10, statSync as statSync5 } from "node:fs";
|
|
11852
11981
|
import { basename as basename3, extname as extname2 } from "node:path";
|
|
11853
11982
|
var SOURCE_TEXT_CHARS = 2e5;
|
|
11854
11983
|
var URL_LIKE = /^[a-z][a-z0-9+.-]*:\/\//i;
|
|
@@ -11966,7 +12095,7 @@ var readFile = /* @__PURE__ */ __name(async (path, { maxChars, load = importEngi
|
|
|
11966
12095
|
throw new CliError("validation_error", `${path} is not a file`, { path });
|
|
11967
12096
|
if (stat.size > MAX_FILE_BYTES)
|
|
11968
12097
|
throw tooLarge2(name2);
|
|
11969
|
-
const bytes = new Uint8Array(
|
|
12098
|
+
const bytes = new Uint8Array(readFileSync10(path));
|
|
11970
12099
|
const extension = extname2(name2).toLowerCase();
|
|
11971
12100
|
const mime = MIMES[extension] ?? null;
|
|
11972
12101
|
const found = await extractText(bytes, { kind: "file", name: name2, mime, path }, load);
|
|
@@ -12168,7 +12297,7 @@ var sourcesCommand = /* @__PURE__ */ __name((program, streams, env, { fetch: fet
|
|
|
12168
12297
|
mime: source?.mime ?? null,
|
|
12169
12298
|
bytes: source?.size ?? null,
|
|
12170
12299
|
// The row says a copy was kept; only the file itself says it still is.
|
|
12171
|
-
kept: source === void 0 ? null : source.copy !== null &&
|
|
12300
|
+
kept: source === void 0 ? null : source.copy !== null && existsSync12(source.copy) ? "copy" : "text",
|
|
12172
12301
|
chars: note.text.length,
|
|
12173
12302
|
text: text3,
|
|
12174
12303
|
textTruncated: truncated,
|
|
@@ -13294,14 +13423,19 @@ var createProgram = /* @__PURE__ */ __name(({ streams: raw = processStreams, env
|
|
|
13294
13423
|
program.addCommand(scheduleCommand(env));
|
|
13295
13424
|
digestCommand(program, streams, env);
|
|
13296
13425
|
commandsCommand(program, streams);
|
|
13297
|
-
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
|
|
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.", () => {
|
|
13298
13427
|
const out = answers(program, streams, env);
|
|
13428
|
+
let brief;
|
|
13299
13429
|
const skill3 = skillCommand(APP, new URL("../skills/cli-memo/SKILL.md", new URL("../program.js", import.meta.url).href), (command) => {
|
|
13300
13430
|
const json5 = command.opts().json === true;
|
|
13301
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");
|
|
13302
13436
|
return {
|
|
13303
|
-
renderer: json5 ? { ...renderer, result
|
|
13304
|
-
streams,
|
|
13437
|
+
renderer: json5 ? { ...renderer, result } : renderer,
|
|
13438
|
+
streams: { ...streams, data: /* @__PURE__ */ __name((text3) => streams.data(withBrief(text3, brief)), "data") },
|
|
13305
13439
|
env
|
|
13306
13440
|
};
|
|
13307
13441
|
}, {
|
|
@@ -13312,8 +13446,10 @@ var createProgram = /* @__PURE__ */ __name(({ streams: raw = processStreams, env
|
|
|
13312
13446
|
for (const command of skill3.commands)
|
|
13313
13447
|
command.option("--json", "print JSON");
|
|
13314
13448
|
const show = skill3.commands.find((command) => command.name() === "show");
|
|
13315
|
-
|
|
13316
|
-
|
|
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
|
+
});
|
|
13317
13453
|
return skill3;
|
|
13318
13454
|
}, SHELL_OVERRIDES.skill);
|
|
13319
13455
|
program.addCommand(skill2);
|