@wirecat/cli-memo 0.131.69 → 0.131.71
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/README.md +3 -3
- package/THIRD_PARTY_NOTICES +2 -0
- package/dist/actions/actions.d.ts +2 -1
- package/dist/actions/actions.d.ts.map +1 -1
- package/dist/actions/actions.js +5 -3
- package/dist/actions/actions.js.map +1 -1
- package/dist/actions/command.d.ts.map +1 -1
- package/dist/actions/command.js +15 -6
- package/dist/actions/command.js.map +1 -1
- package/dist/answer.d.ts +1 -0
- package/dist/answer.d.ts.map +1 -1
- package/dist/answer.js +2 -1
- package/dist/answer.js.map +1 -1
- package/dist/bin/memo.js +2 -2
- package/dist/bin/memo.js.map +1 -1
- package/dist/bundle/{all-profiles-6JKSPBBO.js → all-profiles-G6S5HOBT.js} +5 -5
- package/dist/bundle/{anthropic-YA2N6EJ4.js → anthropic-LA6PXTPQ.js} +2 -2
- package/dist/bundle/{app-server-UP3AL2XQ.js → app-server-W622CBPF.js} +35 -35
- package/dist/bundle/auto-WUU2MYGS.js +85 -0
- package/dist/bundle/{bun-OUFOAYV4.js → bun-PZNVNH4G.js} +2 -2
- package/dist/bundle/{bun-sqlite-5RZTFU2Q.js → bun-sqlite-VICDK5FS.js} +2 -2
- package/dist/bundle/{chunk-3TFK7RBA.js → chunk-2LTQ6ZBS.js} +23908 -22107
- package/dist/bundle/{chunk-IHHXGTMX.js → chunk-3LS76TFB.js} +1 -1
- package/dist/bundle/{chunk-IJAILIZR.js → chunk-3PIKTX3U.js} +18 -18
- package/dist/bundle/{chunk-N73YBQ42.js → chunk-3ZSPTUG3.js} +9 -7
- package/dist/bundle/{chunk-RHW3DDWI.js → chunk-6B3GQMR6.js} +1 -1
- package/dist/bundle/{chunk-LYAJUZM4.js → chunk-6EIWRE6E.js} +30 -30
- package/dist/bundle/{chunk-EDPA54WQ.js → chunk-6Z62U7NY.js} +3 -3
- package/dist/bundle/{chunk-JMGQATR6.js → chunk-ASDOPGKC.js} +2 -2
- package/dist/bundle/{chunk-EKSOPEFQ.js → chunk-BE22RDTR.js} +4 -4
- package/dist/bundle/{chunk-FZHYGJQ2.js → chunk-CLQXHFKG.js} +5 -5
- package/dist/bundle/{chunk-VPKJZKXV.js → chunk-CPUQC7UF.js} +1 -1
- package/dist/bundle/{chunk-GGFL64HF.js → chunk-CZUAGRL7.js} +13168 -11987
- package/dist/bundle/{chunk-GVP6CAPH.js → chunk-DW6CDBXA.js} +33 -586
- package/dist/bundle/{chunk-5MUR6D2G.js → chunk-DXWDHC2K.js} +44 -2
- package/dist/bundle/{chunk-5OMM4CDT.js → chunk-ESYCZ575.js} +2 -2
- package/dist/bundle/{chunk-OBQ7TSUB.js → chunk-FHIGY5K6.js} +1 -1
- package/dist/bundle/{chunk-MK6SQ32Q.js → chunk-FPWF2XLH.js} +12 -12
- package/dist/bundle/{chunk-MYLNRBDF.js → chunk-FVJSDDSV.js} +46 -13
- package/dist/bundle/{chunk-TV75OHKJ.js → chunk-G3FQTKHT.js} +7 -7
- package/dist/bundle/{chunk-WNA2WNDK.js → chunk-G7XOBQB5.js} +3 -3
- package/dist/bundle/{chunk-PSYQPO6D.js → chunk-H3LAORYX.js} +2 -2
- package/dist/bundle/{chunk-2DQYP2K3.js → chunk-HIHZNBR7.js} +1 -1
- package/dist/bundle/{chunk-QAXIZHK7.js → chunk-HNQGX4AG.js} +33 -33
- package/dist/bundle/{chunk-22CDLXSR.js → chunk-I4HWKPQR.js} +4 -4
- package/dist/bundle/{chunk-2NFI7SDW.js → chunk-INQAQ55X.js} +2304 -1111
- package/dist/bundle/{chunk-XTEJXJJ3.js → chunk-IP5CA3CW.js} +10 -10
- package/dist/bundle/{chunk-EO4JMJFZ.js → chunk-IXZWUHSG.js} +7 -7
- package/dist/bundle/{chunk-MWQI6FSU.js → chunk-K55WZ67L.js} +3 -3
- package/dist/bundle/{chunk-YTJWIJIG.js → chunk-KH43CUE2.js} +5 -5
- package/dist/bundle/{chunk-2C7Z7CKD.js → chunk-LIF2HXIQ.js} +1 -1
- package/dist/bundle/{chunk-GVEY6743.js → chunk-LRS5X7G3.js} +9 -9
- package/dist/bundle/{chunk-3LGLKLBA.js → chunk-M2DAITNE.js} +2 -2
- package/dist/bundle/{chunk-OAO5UCPJ.js → chunk-MAGAWAPG.js} +1366 -1574
- package/dist/bundle/{chunk-7JFLHRQL.js → chunk-MKOQDN3I.js} +1 -1
- package/dist/bundle/{chunk-67VEVKMJ.js → chunk-MSTWHRLN.js} +1 -1
- package/dist/bundle/{chunk-YXXAPVAZ.js → chunk-NLRPCKUS.js} +8 -8
- package/dist/bundle/{chunk-W2FFA7T5.js → chunk-NNUS57F4.js} +5 -5
- package/dist/bundle/{chunk-3YVLNOPE.js → chunk-OHBP2KPQ.js} +4 -4
- package/dist/bundle/{chunk-BJJULUUC.js → chunk-OWFC6BAF.js} +5 -5
- package/dist/bundle/{chunk-267N22E4.js → chunk-PGOMGFXA.js} +1 -1
- package/dist/bundle/{chunk-4HSWIXYE.js → chunk-PHL53ERQ.js} +4 -4
- package/dist/bundle/{chunk-5EHUHZU5.js → chunk-QNJ4EKKW.js} +80 -68
- package/dist/bundle/{chunk-53EAI4VZ.js → chunk-QUPPO7DB.js} +1 -1
- package/dist/bundle/{chunk-276KPJI5.js → chunk-RF6KPQWV.js} +2 -2
- package/dist/bundle/{chunk-TXOXPQN2.js → chunk-SL2LXOCN.js} +2 -2
- package/dist/bundle/{chunk-QZU5IM5E.js → chunk-SR7C53CS.js} +2 -2
- package/dist/bundle/{chunk-ECHN36DC.js → chunk-STJWETNW.js} +4 -4
- package/dist/bundle/{chunk-BGWPKEKK.js → chunk-SVVSGUMU.js} +4 -4
- package/dist/bundle/{chunk-FQ54GW57.js → chunk-TG3XWDFI.js} +8360 -8360
- package/dist/bundle/{chunk-V2YS63Z5.js → chunk-U3P5F57B.js} +1 -1
- package/dist/bundle/{chunk-PHSYMVYX.js → chunk-UCRR7R6Q.js} +2 -2
- package/dist/bundle/{chunk-2F35N6BI.js → chunk-UX52EWLQ.js} +1 -1
- package/dist/bundle/{chunk-OHA7HDPX.js → chunk-V6BJM3XW.js} +1024 -676
- package/dist/bundle/{chunk-TVZXLAID.js → chunk-X337K4BD.js} +10 -6
- package/dist/bundle/{chunk-UEMI6FXR.js → chunk-XNX3U6GD.js} +6 -6
- package/dist/bundle/{chunk-7L4PBN5S.js → chunk-ZM6J47GY.js} +2 -2
- package/dist/bundle/{command-contract-OGW2DX4C.js → command-contract-7QECBB6M.js} +11 -11
- package/dist/bundle/{decode-IJMDTGTW.js → decode-WRWXOJML.js} +2 -2
- package/dist/bundle/{echarts-EHYUXOKP.js → echarts-MTCNTCST.js} +2 -2
- package/dist/bundle/{embed-RUY3UIVC.js → embed-PPPCHSTE.js} +3 -3
- package/dist/bundle/{embedder-P6WBMEGP.js → embedder-UJBIX6A2.js} +6 -6
- package/dist/bundle/{entry-7S2ONYSF.js → entry-4P5556KI.js} +4 -4
- package/dist/bundle/failure-3F3YHF7G.js +65 -0
- package/dist/bundle/{first-run-MLIFZSVH.js → first-run-EKRDZLLY.js} +5 -5
- package/dist/bundle/{first-screen-DGTTK6VK.js → first-screen-FRRTKWFB.js} +12 -12
- package/dist/bundle/{instructions-ZMG4FLGO.js → instructions-JKIO4JF7.js} +1 -1
- package/dist/bundle/{mcp-CFIL7WZU.js → mcp-FQPK2KAF.js} +35 -35
- package/dist/bundle/memo.js +14 -11
- package/dist/bundle/{node-QYL4B7JS.js → node-3AIXDDDR.js} +2 -2
- package/dist/bundle/{node-sqlite-ESTT2OCF.js → node-sqlite-NX722DXD.js} +3 -3
- package/dist/bundle/{oauth-CFQFSIRQ.js → oauth-2NPSI7Q3.js} +4 -4
- package/dist/bundle/{open-3XO2HMIT.js → open-AFRN6Q36.js} +2 -2
- package/dist/bundle/{openai-STUNDBD6.js → openai-U5CQFLRU.js} +7 -7
- package/dist/bundle/{process-P4UAJCZX.js → process-J2IBN6X7.js} +1 -1
- package/dist/bundle/{program-BXL5ZOVQ.js → program-L5IM35PO.js} +1433 -531
- package/dist/bundle/{prompt-ZCYMFMIG.js → prompt-6XNKR4VQ.js} +2 -2
- package/dist/bundle/{recognize-V3BY33FK.js → recognize-G3GI32QS.js} +1 -1
- package/dist/bundle/{remote-IP4QR7SP.js → remote-DJO255PT.js} +4 -4
- package/dist/bundle/{rerank-VKUSF3DM.js → rerank-5SBZRIHF.js} +4 -4
- package/dist/bundle/{serve-VBIUARHJ.js → serve-BZVBKGU3.js} +6 -6
- package/dist/bundle/server-GCESLOOF.js +48 -0
- package/dist/bundle/server-JUSMYLIQ.js +61 -0
- package/dist/bundle/{server-JLPZUC42.js → server-LWQAHDBH.js} +55 -52
- package/dist/bundle/{state-UBAIZ2WP.js → state-A57F7T5D.js} +3 -3
- package/dist/bundle/{store-VQQVUA4W.js → store-WG2GYWTG.js} +9 -9
- package/dist/bundle/store-maintenance-command-GTY6VU76.js +47 -0
- package/dist/bundle/update-LICMP7UR.js +68 -0
- package/dist/context/command.d.ts +2 -1
- package/dist/context/command.d.ts.map +1 -1
- package/dist/context/command.js +34 -12
- package/dist/context/command.js.map +1 -1
- package/dist/context/context.d.ts +20 -8
- package/dist/context/context.d.ts.map +1 -1
- package/dist/context/context.js +65 -40
- package/dist/context/context.js.map +1 -1
- package/dist/contract-overrides/search.js +1 -1
- package/dist/contract-overrides/search.js.map +1 -1
- 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/digest/digest.d.ts.map +1 -1
- package/dist/digest/digest.js +2 -1
- package/dist/digest/digest.js.map +1 -1
- package/dist/discovery/command.d.ts.map +1 -1
- package/dist/discovery/command.js +2 -0
- package/dist/discovery/command.js.map +1 -1
- package/dist/doctor/command.d.ts +22 -2
- package/dist/doctor/command.d.ts.map +1 -1
- package/dist/examples.d.ts.map +1 -1
- package/dist/examples.js +51 -10
- package/dist/examples.js.map +1 -1
- package/dist/facts/command.d.ts.map +1 -1
- package/dist/facts/command.js +7 -6
- package/dist/facts/command.js.map +1 -1
- package/dist/finance/deal-text.d.ts +4 -0
- package/dist/finance/deal-text.d.ts.map +1 -0
- package/dist/finance/deal-text.js +34 -0
- package/dist/finance/deal-text.js.map +1 -0
- package/dist/finance/deals-command.d.ts +1 -1
- package/dist/finance/deals-command.d.ts.map +1 -1
- package/dist/finance/deals-command.js +113 -13
- package/dist/finance/deals-command.js.map +1 -1
- package/dist/knowledge/business-text.d.ts +7 -0
- package/dist/knowledge/business-text.d.ts.map +1 -0
- package/dist/knowledge/business-text.js +19 -0
- package/dist/knowledge/business-text.js.map +1 -0
- package/dist/knowledge/command.d.ts +1 -1
- package/dist/knowledge/command.d.ts.map +1 -1
- package/dist/knowledge/command.js +131 -42
- package/dist/knowledge/command.js.map +1 -1
- package/dist/knowledge/money-text.d.ts +4 -0
- package/dist/knowledge/money-text.d.ts.map +1 -0
- package/dist/knowledge/money-text.js +16 -0
- package/dist/knowledge/money-text.js.map +1 -0
- package/dist/knowledge/organization-text.d.ts +7 -0
- package/dist/knowledge/organization-text.d.ts.map +1 -0
- package/dist/knowledge/organization-text.js +24 -0
- package/dist/knowledge/organization-text.js.map +1 -0
- package/dist/knowledge/project-actions-command.js +1 -1
- package/dist/knowledge/project-actions-command.js.map +1 -1
- package/dist/knowledge/project-actions.d.ts +1 -1
- package/dist/knowledge/project-actions.d.ts.map +1 -1
- package/dist/knowledge/project-actions.js +2 -2
- package/dist/knowledge/project-actions.js.map +1 -1
- package/dist/knowledge/project-context.d.ts +27 -1
- package/dist/knowledge/project-context.d.ts.map +1 -1
- package/dist/knowledge/project-context.js +9 -5
- package/dist/knowledge/project-context.js.map +1 -1
- package/dist/knowledge/project-status-command.d.ts.map +1 -1
- package/dist/knowledge/project-status-command.js +21 -5
- package/dist/knowledge/project-status-command.js.map +1 -1
- package/dist/knowledge/relationships.d.ts +27 -23
- package/dist/knowledge/relationships.d.ts.map +1 -1
- package/dist/knowledge/relationships.js +65 -52
- package/dist/knowledge/relationships.js.map +1 -1
- package/dist/knowledge/roles-command.d.ts +8 -0
- package/dist/knowledge/roles-command.d.ts.map +1 -0
- package/dist/knowledge/roles-command.js +65 -0
- package/dist/knowledge/roles-command.js.map +1 -0
- package/dist/mcp/catalogue.d.ts +1 -1
- package/dist/mcp/catalogue.d.ts.map +1 -1
- package/dist/mcp/catalogue.js +3 -1
- package/dist/mcp/catalogue.js.map +1 -1
- package/dist/mcp/server.js +1 -1
- package/dist/mcp/server.js.map +1 -1
- package/dist/memories/command.d.ts.map +1 -1
- package/dist/memories/command.js +6 -5
- package/dist/memories/command.js.map +1 -1
- package/dist/memories/sources.js +2 -2
- package/dist/memories/sources.js.map +1 -1
- package/dist/models/command.d.ts +1 -1
- package/dist/models/command.d.ts.map +1 -1
- package/dist/models/command.js +2 -1
- package/dist/models/command.js.map +1 -1
- package/dist/notes/command.d.ts.map +1 -1
- package/dist/notes/command.js +13 -8
- package/dist/notes/command.js.map +1 -1
- package/dist/notes/embed.d.ts +6 -1
- package/dist/notes/embed.d.ts.map +1 -1
- package/dist/notes/embed.js +17 -8
- package/dist/notes/embed.js.map +1 -1
- package/dist/people/command.d.ts.map +1 -1
- package/dist/people/command.js +2 -1
- package/dist/people/command.js.map +1 -1
- package/dist/program.d.ts +13 -1
- package/dist/program.d.ts.map +1 -1
- package/dist/program.js +173 -11
- package/dist/program.js.map +1 -1
- package/dist/reasons.d.ts.map +1 -1
- package/dist/reasons.js +42 -0
- package/dist/reasons.js.map +1 -1
- package/dist/review/command.js +2 -2
- package/dist/review/command.js.map +1 -1
- package/dist/review/review.d.ts +3 -3
- package/dist/review/review.d.ts.map +1 -1
- package/dist/review/review.js +6 -6
- package/dist/review/review.js.map +1 -1
- package/dist/review/status.d.ts.map +1 -1
- package/dist/review/status.js +5 -4
- package/dist/review/status.js.map +1 -1
- package/dist/run/import.d.ts +2 -2
- package/dist/run/import.d.ts.map +1 -1
- package/dist/run/import.js +9 -3
- package/dist/run/import.js.map +1 -1
- package/dist/search/command.d.ts.map +1 -1
- package/dist/search/command.js +21 -3
- package/dist/search/command.js.map +1 -1
- package/dist/search/denied.d.ts +10 -0
- package/dist/search/denied.d.ts.map +1 -0
- package/dist/search/denied.js +10 -0
- package/dist/search/denied.js.map +1 -0
- package/dist/search/people.d.ts.map +1 -1
- package/dist/search/people.js +11 -1
- package/dist/search/people.js.map +1 -1
- package/dist/search/search.d.ts +2 -0
- package/dist/search/search.d.ts.map +1 -1
- package/dist/search/search.js +37 -12
- package/dist/search/search.js.map +1 -1
- package/dist/store/group.d.ts +38 -0
- package/dist/store/group.d.ts.map +1 -0
- package/dist/store/group.js +112 -0
- package/dist/store/group.js.map +1 -0
- package/dist/store/groups-command.d.ts +10 -0
- package/dist/store/groups-command.d.ts.map +1 -0
- package/dist/store/groups-command.js +88 -0
- package/dist/store/groups-command.js.map +1 -0
- package/dist/store/guard.d.ts +29 -0
- package/dist/store/guard.d.ts.map +1 -0
- package/dist/store/guard.js +94 -0
- package/dist/store/guard.js.map +1 -0
- package/dist/store/scope.d.ts +3 -3
- package/dist/store/scope.d.ts.map +1 -1
- package/dist/store/scope.js +7 -6
- package/dist/store/scope.js.map +1 -1
- package/dist/store/source-list.d.ts +5 -1
- package/dist/store/source-list.d.ts.map +1 -1
- package/dist/store/source-list.js +30 -15
- package/dist/store/source-list.js.map +1 -1
- package/dist/tags/command.d.ts.map +1 -1
- package/dist/tags/command.js +3 -2
- package/dist/tags/command.js.map +1 -1
- package/dist/tasks/shared.d.ts.map +1 -1
- package/dist/tasks/shared.js +2 -1
- package/dist/tasks/shared.js.map +1 -1
- package/dist/tasks/tasks.js +3 -3
- package/dist/tasks/tasks.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +5 -4
- package/skills/cli-memo/SKILL.md +7 -7
- package/skills/cli-memo/topics/mcp.md +9 -0
- package/skills/cli-memo/topics/money.md +14 -1
- package/skills/cli-memo/topics/projects.md +2 -1
- package/skills/cli-memo/topics/search.md +12 -4
- package/dist/bundle/auto-IKZIROGF.js +0 -85
- package/dist/bundle/failure-NRZUB77S.js +0 -65
- package/dist/bundle/server-AASCSGCI.js +0 -61
- package/dist/bundle/server-YQLPZK4Z.js +0 -48
- package/dist/bundle/store-maintenance-command-GCBABKEZ.js +0 -47
- package/dist/bundle/update-M54Z3SEU.js +0 -68
- /package/dist/bundle/{chunk-AWVQHWIS.js → chunk-YSYFOIW7.js} +0 -0
|
@@ -6,28 +6,30 @@ import {
|
|
|
6
6
|
autoState,
|
|
7
7
|
lastAutoRun,
|
|
8
8
|
recordAutoRun
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-BE22RDTR.js";
|
|
10
10
|
import {
|
|
11
11
|
installer,
|
|
12
12
|
latest,
|
|
13
13
|
upgradeCommand
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-OWFC6BAF.js";
|
|
15
15
|
import {
|
|
16
16
|
mcpOwnerAllowed,
|
|
17
|
+
memoLevels,
|
|
17
18
|
readOnlyAvailability,
|
|
18
19
|
refuseWritesUnderLock
|
|
19
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-NNUS57F4.js";
|
|
20
21
|
import {
|
|
21
22
|
answers,
|
|
22
23
|
atDetail,
|
|
23
24
|
itemAnswer,
|
|
24
25
|
listAnswer,
|
|
26
|
+
openMemoStore,
|
|
25
27
|
plainText,
|
|
26
28
|
snakeKeys as snakeKeys2,
|
|
27
29
|
trackAnswers,
|
|
28
30
|
wholeList,
|
|
29
31
|
withStore
|
|
30
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-X337K4BD.js";
|
|
31
33
|
import {
|
|
32
34
|
ATTACHMENT_CHARS,
|
|
33
35
|
DIALECTS,
|
|
@@ -59,15 +61,15 @@ import {
|
|
|
59
61
|
showMail,
|
|
60
62
|
unsetConfigKey,
|
|
61
63
|
updateConfig
|
|
62
|
-
} from "./chunk-
|
|
64
|
+
} from "./chunk-TG3XWDFI.js";
|
|
63
65
|
import "./chunk-QP3KNC5D.js";
|
|
64
|
-
import "./chunk-
|
|
65
|
-
import "./chunk-
|
|
66
|
-
import "./chunk-
|
|
66
|
+
import "./chunk-SL2LXOCN.js";
|
|
67
|
+
import "./chunk-IXZWUHSG.js";
|
|
68
|
+
import "./chunk-K55WZ67L.js";
|
|
67
69
|
import {
|
|
68
70
|
errorObject,
|
|
69
71
|
recognisable
|
|
70
|
-
} from "./chunk-
|
|
72
|
+
} from "./chunk-OHBP2KPQ.js";
|
|
71
73
|
import {
|
|
72
74
|
AGENT_INPUT_MAX_CHARS,
|
|
73
75
|
DISCOVERY_DESCRIPTIONS,
|
|
@@ -77,9 +79,12 @@ import {
|
|
|
77
79
|
addMeetingPreparationCommand,
|
|
78
80
|
advancePastSkipped,
|
|
79
81
|
backfillScheduleRun,
|
|
82
|
+
baseStagesCommand,
|
|
80
83
|
checkJson,
|
|
81
84
|
dateOrNone,
|
|
85
|
+
deniedKindsOf,
|
|
82
86
|
entityFields,
|
|
87
|
+
groupAware,
|
|
83
88
|
guideCommand,
|
|
84
89
|
liftJson,
|
|
85
90
|
mailWaiting,
|
|
@@ -101,6 +106,8 @@ import {
|
|
|
101
106
|
readMailFindingsJson,
|
|
102
107
|
readSchedule,
|
|
103
108
|
recordRuns,
|
|
109
|
+
refKinds,
|
|
110
|
+
refuseOutsideGroup,
|
|
104
111
|
runsCommand,
|
|
105
112
|
scheduleCommandFor,
|
|
106
113
|
scheduleFile,
|
|
@@ -112,54 +119,65 @@ import {
|
|
|
112
119
|
tasksStatsCommand,
|
|
113
120
|
templatesCommand,
|
|
114
121
|
withSqliteSidecars
|
|
115
|
-
} from "./chunk-
|
|
116
|
-
import "./chunk-
|
|
117
|
-
import "./chunk-
|
|
122
|
+
} from "./chunk-V6BJM3XW.js";
|
|
123
|
+
import "./chunk-MKOQDN3I.js";
|
|
124
|
+
import "./chunk-6B3GQMR6.js";
|
|
118
125
|
import {
|
|
119
126
|
allHitItem,
|
|
120
127
|
coverageGaps,
|
|
121
128
|
messageHitItem,
|
|
122
129
|
noteHitItem,
|
|
123
130
|
shownOf
|
|
124
|
-
} from "./chunk-
|
|
125
|
-
import "./chunk-
|
|
131
|
+
} from "./chunk-6EIWRE6E.js";
|
|
132
|
+
import "./chunk-FHIGY5K6.js";
|
|
126
133
|
import {
|
|
127
134
|
REASONS as REASONS2,
|
|
128
135
|
SKILL_TARGETS,
|
|
129
136
|
skillCommand,
|
|
130
137
|
skillPath,
|
|
131
138
|
skillVersion
|
|
132
|
-
} from "./chunk-
|
|
139
|
+
} from "./chunk-FVJSDDSV.js";
|
|
133
140
|
import {
|
|
134
141
|
recoveryNotes,
|
|
135
142
|
storeInfo,
|
|
136
143
|
storeRecoveryCheck,
|
|
137
144
|
storeRecoveryRun,
|
|
138
145
|
storeSummary
|
|
139
|
-
} from "./chunk-
|
|
140
|
-
import "./chunk-
|
|
146
|
+
} from "./chunk-QNJ4EKKW.js";
|
|
147
|
+
import "./chunk-DW6CDBXA.js";
|
|
141
148
|
import {
|
|
142
149
|
LIST_QUERY_GUIDE,
|
|
150
|
+
RESOURCES_SEARCHED,
|
|
143
151
|
STATUS_SIGNALS,
|
|
152
|
+
addGroupMember,
|
|
144
153
|
approveAsTask,
|
|
145
154
|
calendarAccounts,
|
|
155
|
+
canonicalPersonContext,
|
|
146
156
|
closedStateOf,
|
|
147
157
|
createMeetingPassageCommand,
|
|
148
158
|
createMeetingPreparationService,
|
|
149
159
|
createMeetingSearchCommand,
|
|
160
|
+
dealBrief,
|
|
161
|
+
dealContext,
|
|
150
162
|
documentPassage,
|
|
151
163
|
embedMail,
|
|
152
164
|
embedNotes,
|
|
153
165
|
excerpt,
|
|
154
166
|
extractText,
|
|
155
167
|
gatherStoredProject,
|
|
168
|
+
groupGuardOf,
|
|
169
|
+
groupLockOf,
|
|
156
170
|
importEngine,
|
|
171
|
+
inGroupOf,
|
|
157
172
|
ingest,
|
|
158
173
|
ingestLines,
|
|
159
174
|
ingestVcard,
|
|
160
175
|
isVcard,
|
|
161
176
|
jsonlLines,
|
|
177
|
+
listAccountGroups,
|
|
178
|
+
listContextOf,
|
|
162
179
|
listQuery,
|
|
180
|
+
lockedRegistry,
|
|
163
181
|
mailTurn,
|
|
164
182
|
meaningLane,
|
|
165
183
|
meetingHitSearchRequest,
|
|
@@ -167,9 +185,12 @@ import {
|
|
|
167
185
|
meetingSearchArguments,
|
|
168
186
|
meetingSearchMeta,
|
|
169
187
|
modelGateway,
|
|
188
|
+
moveGroupMember,
|
|
170
189
|
nativeField,
|
|
171
190
|
nativeTerms,
|
|
191
|
+
organizationContext,
|
|
172
192
|
parseProposalIds,
|
|
193
|
+
personBusiness,
|
|
173
194
|
personContext,
|
|
174
195
|
pickPerson,
|
|
175
196
|
previewProjectAnnotationSnapshot,
|
|
@@ -182,7 +203,9 @@ import {
|
|
|
182
203
|
questionLookup,
|
|
183
204
|
readMeetingPassage,
|
|
184
205
|
readWithRegistry,
|
|
206
|
+
removeGroupMember,
|
|
185
207
|
scanProjectLinks,
|
|
208
|
+
scopeToGroup,
|
|
186
209
|
searchAll,
|
|
187
210
|
searchMeetingHits,
|
|
188
211
|
searchNotesOf,
|
|
@@ -197,18 +220,18 @@ import {
|
|
|
197
220
|
timeLimit,
|
|
198
221
|
typedQuery,
|
|
199
222
|
withQuery
|
|
200
|
-
} from "./chunk-
|
|
223
|
+
} from "./chunk-2LTQ6ZBS.js";
|
|
201
224
|
import {
|
|
202
225
|
readBoundedUtf8File,
|
|
203
226
|
writeFileAtomic
|
|
204
|
-
} from "./chunk-
|
|
227
|
+
} from "./chunk-FPWF2XLH.js";
|
|
205
228
|
import {
|
|
206
229
|
commandsText,
|
|
207
230
|
inSection,
|
|
208
231
|
installHelp
|
|
209
|
-
} from "./chunk-
|
|
232
|
+
} from "./chunk-XNX3U6GD.js";
|
|
210
233
|
import "./chunk-HTQTIKWP.js";
|
|
211
|
-
import "./chunk-
|
|
234
|
+
import "./chunk-ASDOPGKC.js";
|
|
212
235
|
import {
|
|
213
236
|
Command,
|
|
214
237
|
DEFAULT_TEXT_MODEL,
|
|
@@ -224,6 +247,7 @@ import {
|
|
|
224
247
|
answerEntity,
|
|
225
248
|
assertSharedContracts,
|
|
226
249
|
chosenTextModel,
|
|
250
|
+
commandWords,
|
|
227
251
|
commandsDocument,
|
|
228
252
|
customizeSharedCommand,
|
|
229
253
|
environmentOf,
|
|
@@ -231,6 +255,7 @@ import {
|
|
|
231
255
|
grantsAuthority,
|
|
232
256
|
hasSharedContract,
|
|
233
257
|
itemOf,
|
|
258
|
+
liftProfile,
|
|
234
259
|
metaOf,
|
|
235
260
|
outputFor,
|
|
236
261
|
overrideSharedContract,
|
|
@@ -239,29 +264,29 @@ import {
|
|
|
239
264
|
progressOf,
|
|
240
265
|
proposesOnly,
|
|
241
266
|
provide,
|
|
242
|
-
|
|
267
|
+
runGroup,
|
|
243
268
|
settingRows,
|
|
244
269
|
settingsFor,
|
|
245
270
|
snakeKeys,
|
|
246
271
|
textModels,
|
|
247
272
|
textModelsFile
|
|
248
|
-
} from "./chunk-
|
|
249
|
-
import "./chunk-
|
|
250
|
-
import "./chunk-
|
|
273
|
+
} from "./chunk-MAGAWAPG.js";
|
|
274
|
+
import "./chunk-3ZSPTUG3.js";
|
|
275
|
+
import "./chunk-IP5CA3CW.js";
|
|
251
276
|
import {
|
|
252
277
|
isNewer
|
|
253
278
|
} from "./chunk-LJCT7YG6.js";
|
|
254
279
|
import "./chunk-L62FWN3Y.js";
|
|
255
|
-
import "./chunk-
|
|
256
|
-
import "./chunk-
|
|
257
|
-
import "./chunk-
|
|
258
|
-
import "./chunk-
|
|
280
|
+
import "./chunk-6Z62U7NY.js";
|
|
281
|
+
import "./chunk-LRS5X7G3.js";
|
|
282
|
+
import "./chunk-HIHZNBR7.js";
|
|
283
|
+
import "./chunk-I4HWKPQR.js";
|
|
259
284
|
import {
|
|
260
285
|
releaseLock,
|
|
261
286
|
servingProfiles,
|
|
262
287
|
takeLock
|
|
263
|
-
} from "./chunk-
|
|
264
|
-
import "./chunk-
|
|
288
|
+
} from "./chunk-ZM6J47GY.js";
|
|
289
|
+
import "./chunk-3LS76TFB.js";
|
|
265
290
|
import {
|
|
266
291
|
EVIDENCE_FINDINGS_KIND,
|
|
267
292
|
MAIL_FINDINGS_KIND,
|
|
@@ -285,27 +310,20 @@ import {
|
|
|
285
310
|
assertMayDecide,
|
|
286
311
|
contextEvidenceFingerprint,
|
|
287
312
|
decodeProjectAnnotationSnapshot,
|
|
288
|
-
entriesOfList,
|
|
289
313
|
envelopeOfText,
|
|
290
|
-
formatLocator,
|
|
291
|
-
formatReference,
|
|
292
|
-
isFolderProvider,
|
|
293
314
|
isGoogleDocumentHost,
|
|
294
|
-
isImportedProvider,
|
|
295
|
-
kindOf,
|
|
296
|
-
looksLikeReference,
|
|
297
315
|
mailFindingFieldsHelp,
|
|
298
316
|
mailOwnText,
|
|
299
317
|
openOf,
|
|
300
318
|
openStore,
|
|
301
|
-
parseLocator,
|
|
302
|
-
parseReference,
|
|
303
319
|
plainQuery,
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
320
|
+
refLabel,
|
|
321
|
+
storedProfilesFor,
|
|
322
|
+
writesWithOf
|
|
323
|
+
} from "./chunk-CZUAGRL7.js";
|
|
307
324
|
import {
|
|
308
325
|
CATALOG_KINDS,
|
|
326
|
+
CATEGORIES,
|
|
309
327
|
CONTRACT_KINDS,
|
|
310
328
|
CONTRACT_STATUSES,
|
|
311
329
|
DEAL_KINDS,
|
|
@@ -324,8 +342,13 @@ import {
|
|
|
324
342
|
MONEY_DIRECTIONS,
|
|
325
343
|
ORDER_PURPOSES,
|
|
326
344
|
ORDER_STATUSES,
|
|
345
|
+
ORGANIZATION_ROLES,
|
|
327
346
|
PRIORITY_LABELS,
|
|
347
|
+
PROJECT_ROLES,
|
|
348
|
+
REF_KINDS,
|
|
349
|
+
RELATION_KINDS,
|
|
328
350
|
SOURCE_REVIEW_KIND,
|
|
351
|
+
STANDINGS,
|
|
329
352
|
SUBSCRIPTION_STATUSES,
|
|
330
353
|
TASK_STATES,
|
|
331
354
|
TASK_TYPES,
|
|
@@ -336,39 +359,54 @@ import {
|
|
|
336
359
|
createUpcomingMeetingReader,
|
|
337
360
|
dateRange,
|
|
338
361
|
dayBoundary,
|
|
362
|
+
entriesOfList,
|
|
339
363
|
event,
|
|
340
364
|
eventItem,
|
|
365
|
+
formatLocator,
|
|
341
366
|
formatMeetingReference,
|
|
367
|
+
formatReference,
|
|
342
368
|
isClosedState,
|
|
369
|
+
isFolderProvider,
|
|
370
|
+
isImportedProvider,
|
|
371
|
+
isUsable,
|
|
372
|
+
keyOf,
|
|
373
|
+
kindIn,
|
|
374
|
+
kindOf,
|
|
375
|
+
looksLikeReference,
|
|
343
376
|
markStoreDamaged,
|
|
344
377
|
meetingHitsList,
|
|
345
378
|
minorUnits,
|
|
346
379
|
moneyOf,
|
|
347
380
|
normalizeTag,
|
|
381
|
+
parseLocator,
|
|
348
382
|
parseLucene,
|
|
349
383
|
parseMeetingReference,
|
|
384
|
+
parseReference,
|
|
350
385
|
paymentTitle,
|
|
351
386
|
priorityOf,
|
|
387
|
+
providerNamed,
|
|
352
388
|
queryError,
|
|
353
389
|
queryFieldsOf,
|
|
390
|
+
runsDirFor,
|
|
391
|
+
standingOf,
|
|
354
392
|
timezoneOf,
|
|
355
393
|
validateQuery,
|
|
356
394
|
walkQuery
|
|
357
|
-
} from "./chunk-
|
|
358
|
-
import "./chunk-
|
|
359
|
-
import "./chunk-
|
|
360
|
-
import "./chunk-
|
|
361
|
-
import "./chunk-
|
|
362
|
-
import "./chunk-
|
|
363
|
-
import "./chunk-
|
|
364
|
-
import "./chunk-
|
|
365
|
-
import "./chunk-
|
|
395
|
+
} from "./chunk-INQAQ55X.js";
|
|
396
|
+
import "./chunk-M2DAITNE.js";
|
|
397
|
+
import "./chunk-G3FQTKHT.js";
|
|
398
|
+
import "./chunk-SVVSGUMU.js";
|
|
399
|
+
import "./chunk-UCRR7R6Q.js";
|
|
400
|
+
import "./chunk-LIF2HXIQ.js";
|
|
401
|
+
import "./chunk-ESYCZ575.js";
|
|
402
|
+
import "./chunk-SR7C53CS.js";
|
|
403
|
+
import "./chunk-CLQXHFKG.js";
|
|
366
404
|
import {
|
|
367
405
|
sharedModelsDirectory
|
|
368
|
-
} from "./chunk-
|
|
406
|
+
} from "./chunk-G7XOBQB5.js";
|
|
369
407
|
import {
|
|
370
408
|
storePath
|
|
371
|
-
} from "./chunk-
|
|
409
|
+
} from "./chunk-U3P5F57B.js";
|
|
372
410
|
import {
|
|
373
411
|
provideTerminal,
|
|
374
412
|
terminalOf
|
|
@@ -378,12 +416,12 @@ import {
|
|
|
378
416
|
REASONS,
|
|
379
417
|
STORE_CLIENT,
|
|
380
418
|
VERSION
|
|
381
|
-
} from "./chunk-
|
|
419
|
+
} from "./chunk-DXWDHC2K.js";
|
|
382
420
|
import "./chunk-DSU6UR2X.js";
|
|
383
421
|
import "./chunk-SYWHHQMC.js";
|
|
384
422
|
import "./chunk-D72URWJE.js";
|
|
385
|
-
import "./chunk-
|
|
386
|
-
import "./chunk-
|
|
423
|
+
import "./chunk-KH43CUE2.js";
|
|
424
|
+
import "./chunk-MSTWHRLN.js";
|
|
387
425
|
import {
|
|
388
426
|
configFilePath,
|
|
389
427
|
createDeadline,
|
|
@@ -423,7 +461,7 @@ import {
|
|
|
423
461
|
errorCodes,
|
|
424
462
|
isCliError
|
|
425
463
|
} from "./chunk-ZTONSM5X.js";
|
|
426
|
-
import "./chunk-
|
|
464
|
+
import "./chunk-CPUQC7UF.js";
|
|
427
465
|
import {
|
|
428
466
|
__name
|
|
429
467
|
} from "./chunk-ZVVMGPBJ.js";
|
|
@@ -512,6 +550,90 @@ var fromAppOption = /* @__PURE__ */ __name((command) => command.option("--from-a
|
|
|
512
550
|
var byOption = /* @__PURE__ */ __name((command) => fromAppOption(command.option("--as-owner", "act as you although an agent's terminal runs memo (AI_AGENT or CLAUDECODE set); asks y/N at the terminal")), "byOption");
|
|
513
551
|
var reasonOption = /* @__PURE__ */ __name((command) => command.option("--reason <text>", "why, in a few words; required when an agent decides for you"), "reasonOption");
|
|
514
552
|
|
|
553
|
+
// dist/store/group.js
|
|
554
|
+
var MEMO_ACCOUNT = { provider: "notes", account: "internal" };
|
|
555
|
+
var memoListContext = /* @__PURE__ */ __name(async (store, env) => {
|
|
556
|
+
const held = await store.accounts.storedAccounts();
|
|
557
|
+
const context = await listContextOf(store, MEMO_ACCOUNT, APP, held, env);
|
|
558
|
+
return {
|
|
559
|
+
...context,
|
|
560
|
+
held: context.held.filter((one2) => one2.id !== 0 || keyOf(one2) !== keyOf(MEMO_ACCOUNT))
|
|
561
|
+
};
|
|
562
|
+
}, "memoListContext");
|
|
563
|
+
var groupOf = /* @__PURE__ */ __name((env, word) => runGroup(APP, env, word), "groupOf");
|
|
564
|
+
var scopeIn = /* @__PURE__ */ __name((run, context) => {
|
|
565
|
+
scopeToGroup(run, {}, context);
|
|
566
|
+
const accounts = entriesOfList(`group:${run.name}`, context).flatMap((entry) => entry.accounts.map(({ provider, account: account2 }) => ({ provider, account: account2 })));
|
|
567
|
+
return { run, accounts, has: inGroupOf(context, run.name) };
|
|
568
|
+
}, "scopeIn");
|
|
569
|
+
var groupScopeOf = /* @__PURE__ */ __name(async (store, env) => {
|
|
570
|
+
const run = groupOf(env);
|
|
571
|
+
return run === void 0 ? void 0 : scopeIn(run, await memoListContext(store, env));
|
|
572
|
+
}, "groupScopeOf");
|
|
573
|
+
var OWN_BUSINESS = { provider: "business", account: "internal" };
|
|
574
|
+
var accountsByKind = /* @__PURE__ */ __name((scope, imports = []) => {
|
|
575
|
+
const kinds2 = {
|
|
576
|
+
messages: [],
|
|
577
|
+
mail: [],
|
|
578
|
+
notes: [MEMO_ACCOUNT],
|
|
579
|
+
events: [],
|
|
580
|
+
crm: [],
|
|
581
|
+
business: [OWN_BUSINESS, ...imports.filter(scope.has)]
|
|
582
|
+
};
|
|
583
|
+
for (const key of scope.accounts) {
|
|
584
|
+
const kind = kindIn(key.provider);
|
|
585
|
+
if (kind === "documents")
|
|
586
|
+
kinds2.notes.push(key);
|
|
587
|
+
else if (kind !== void 0 && kind !== "meetings" && kind in kinds2)
|
|
588
|
+
kinds2[kind].push(key);
|
|
589
|
+
}
|
|
590
|
+
return kinds2;
|
|
591
|
+
}, "accountsByKind");
|
|
592
|
+
var scopedAccounts = /* @__PURE__ */ __name(async (store, env) => {
|
|
593
|
+
const all = await store.accounts.accounts();
|
|
594
|
+
const scope = await groupScopeOf(store, env);
|
|
595
|
+
return scope === void 0 ? all : all.filter(scope.has);
|
|
596
|
+
}, "scopedAccounts");
|
|
597
|
+
var inGroup = /* @__PURE__ */ __name(async (store, env, keys) => {
|
|
598
|
+
const scope = await groupScopeOf(store, env);
|
|
599
|
+
return scope === void 0 ? [...keys] : keys.filter(scope.has);
|
|
600
|
+
}, "inGroup");
|
|
601
|
+
var refInGroup = /* @__PURE__ */ __name(async (store, scope, ref) => {
|
|
602
|
+
const accounts = await store.refs.accounts(ref);
|
|
603
|
+
return !accounts?.length || accounts.some(scope.has);
|
|
604
|
+
}, "refInGroup");
|
|
605
|
+
var keepInGroup = /* @__PURE__ */ __name(async (store, env, items, refOf2) => {
|
|
606
|
+
const scope = await groupScopeOf(store, env);
|
|
607
|
+
if (scope === void 0)
|
|
608
|
+
return [...items];
|
|
609
|
+
const kept = [];
|
|
610
|
+
for (const item of items)
|
|
611
|
+
if (await refInGroup(store, scope, refOf2(item)))
|
|
612
|
+
kept.push(item);
|
|
613
|
+
return kept;
|
|
614
|
+
}, "keepInGroup");
|
|
615
|
+
var optionValue = /* @__PURE__ */ __name((command, name2) => {
|
|
616
|
+
const value = command.getOptionValue(name2);
|
|
617
|
+
return typeof value === "string" ? value : void 0;
|
|
618
|
+
}, "optionValue");
|
|
619
|
+
var declares = /* @__PURE__ */ __name((command, name2) => command.options.some((option) => option.attributeName() === name2), "declares");
|
|
620
|
+
var scopeRunsToGroup = /* @__PURE__ */ __name((program, env, word) => {
|
|
621
|
+
program.hook("preAction", async (_root, command) => {
|
|
622
|
+
const run = groupOf(env, word);
|
|
623
|
+
if (run === void 0)
|
|
624
|
+
return;
|
|
625
|
+
await withStore(env, async (store) => {
|
|
626
|
+
await refuseOutsideGroup(command, { app: APP, env, store });
|
|
627
|
+
const context = await memoListContext(store, env);
|
|
628
|
+
const source = declares(command, "source") ? optionValue(command, "source") : void 0;
|
|
629
|
+
const account2 = declares(command, "account") ? optionValue(command, "account") : void 0;
|
|
630
|
+
const scoped3 = scopeToGroup(run, { ...source === void 0 ? {} : { source }, ...account2 === void 0 ? {} : { account: account2 } }, context);
|
|
631
|
+
if (declares(command, "source") && scoped3.source !== void 0 && command.getOptionValue("all") !== true)
|
|
632
|
+
command.setOptionValue("source", scoped3.source);
|
|
633
|
+
});
|
|
634
|
+
});
|
|
635
|
+
}, "scopeRunsToGroup");
|
|
636
|
+
|
|
515
637
|
// dist/store/source-list.js
|
|
516
638
|
var MAIL = /* @__PURE__ */ new Set(["mail", "email"]);
|
|
517
639
|
var MESSENGERS = /* @__PURE__ */ new Set(["messages", "telegram", "tg", "max", "whatsapp", "wa", "personal", "bots"]);
|
|
@@ -532,8 +654,9 @@ var filesAccounts = /* @__PURE__ */ __name(async (store) => {
|
|
|
532
654
|
return (one2) => ids.has(String(one2.id));
|
|
533
655
|
}, "filesAccounts");
|
|
534
656
|
var messengers = /* @__PURE__ */ __name((entry) => new CliError("validation_error", `${entry}: mentions in chats are the messenger's \u2014 tg <profile> mentions list`), "messengers");
|
|
535
|
-
var listedOf = /* @__PURE__ */ __name(async (store, value) => {
|
|
536
|
-
const
|
|
657
|
+
var listedOf = /* @__PURE__ */ __name(async (store, env, value) => {
|
|
658
|
+
const context = await memoListContext(store, env);
|
|
659
|
+
const { held } = context;
|
|
537
660
|
const holdsFiles = await filesAccounts(store);
|
|
538
661
|
const named5 = /* @__PURE__ */ __name(async (entry) => {
|
|
539
662
|
const [provider = "", ...rest] = entry.trim().split(":");
|
|
@@ -549,19 +672,22 @@ var listedOf = /* @__PURE__ */ __name(async (store, value) => {
|
|
|
549
672
|
return `email:${(await mailboxOf(store, account2)).account}`;
|
|
550
673
|
}, "named");
|
|
551
674
|
const each = /* @__PURE__ */ __name((entries) => Promise.all(entries.filter((one2) => one2.trim()).map(named5)), "each");
|
|
552
|
-
const groups = Object.fromEntries(await Promise.all(Object.entries(
|
|
675
|
+
const groups = Object.fromEntries(await Promise.all(Object.entries(context.groups).map(async ([name2, members]) => [name2, await each(members)])));
|
|
553
676
|
return entriesOfList((await each(value.split(","))).join(","), {
|
|
554
|
-
|
|
677
|
+
...context,
|
|
555
678
|
groups,
|
|
556
|
-
profiles: await store.accounts.profiles(),
|
|
557
679
|
running: { provider: "email", command: "memo" }
|
|
558
680
|
});
|
|
559
681
|
}, "listedOf");
|
|
560
|
-
var sourceListOf = /* @__PURE__ */ __name(async (store, env, value) => {
|
|
561
|
-
const listed2 = await listedOf(store, value);
|
|
682
|
+
var sourceListOf = /* @__PURE__ */ __name(async (store, env, value, only) => {
|
|
683
|
+
const listed2 = await listedOf(store, env, value);
|
|
684
|
+
const typed = new Set(value.split(",").map((item) => item.trim()));
|
|
562
685
|
const list = { mail: [], notes: false, documents: false };
|
|
563
686
|
for (const { entry, accounts } of listed2) {
|
|
564
687
|
const word = entry.split(":")[0] ?? "";
|
|
688
|
+
const group = word === "group" || !typed.has(entry.trim());
|
|
689
|
+
if (only !== void 0 && group && accounts.every(({ kind }) => kind !== only))
|
|
690
|
+
continue;
|
|
565
691
|
if (MESSENGERS.has(word))
|
|
566
692
|
throw messengers(entry);
|
|
567
693
|
if (word === "notes" || word === "all")
|
|
@@ -572,11 +698,13 @@ var sourceListOf = /* @__PURE__ */ __name(async (store, env, value) => {
|
|
|
572
698
|
if (kind === "mail") {
|
|
573
699
|
if (!list.mail.some((one2) => one2.account === account2))
|
|
574
700
|
list.mail.push({ provider, account: account2 });
|
|
575
|
-
} else if (
|
|
701
|
+
} else if (group && only !== void 0)
|
|
702
|
+
continue;
|
|
703
|
+
else if (kind === "notes")
|
|
576
704
|
list.notes = true;
|
|
577
705
|
else if (kind === "documents")
|
|
578
706
|
list.documents = true;
|
|
579
|
-
else if (word !== "all")
|
|
707
|
+
else if (word !== "all" && !group)
|
|
580
708
|
throw messengers(entry);
|
|
581
709
|
}
|
|
582
710
|
}
|
|
@@ -585,9 +713,11 @@ var sourceListOf = /* @__PURE__ */ __name(async (store, env, value) => {
|
|
|
585
713
|
var SOURCE_HELP = `which texts, separated by commas: ${SHAPES}`;
|
|
586
714
|
var MAIL_SOURCES = "email:<address>, email or group:<name>";
|
|
587
715
|
var mailboxesOf = /* @__PURE__ */ __name(async (store, env, value) => {
|
|
588
|
-
const list = await sourceListOf(store, env, value);
|
|
716
|
+
const list = await sourceListOf(store, env, value, "mail");
|
|
589
717
|
if (list.notes || list.documents)
|
|
590
718
|
throw new CliError("validation_error", `${value}: this reads mail only \u2014 ${MAIL_SOURCES}`);
|
|
719
|
+
if (list.mail.length === 0 && value.split(",").some((entry) => entry.trim().startsWith("group:")))
|
|
720
|
+
throw new CliError("not_found", `${value} holds no mailbox`);
|
|
591
721
|
return list.mail;
|
|
592
722
|
}, "mailboxesOf");
|
|
593
723
|
var ACCOUNTS_HELP = `which accounts, separated by commas: ${SHAPES}`;
|
|
@@ -596,14 +726,14 @@ var MEETING_WRITE_HELP = "the meeting account it acts as: provider:account, such
|
|
|
596
726
|
var ONE_ACCOUNT_HELP = "the one account: provider:account (telegram:500, email:personal), or a provider or group:<name> that holds only one";
|
|
597
727
|
var accountsOf = /* @__PURE__ */ __name(async (store, env, value) => {
|
|
598
728
|
const keys = [];
|
|
599
|
-
for (const { accounts } of await listedOf(store, value))
|
|
729
|
+
for (const { accounts } of await listedOf(store, env, value))
|
|
600
730
|
for (const { provider, account: account2 } of accounts)
|
|
601
731
|
if (!keys.some((one2) => one2.provider === provider && one2.account === account2))
|
|
602
732
|
keys.push({ provider, account: account2 });
|
|
603
733
|
return keys;
|
|
604
734
|
}, "accountsOf");
|
|
605
735
|
var named = /* @__PURE__ */ __name((keys) => keys.map((key) => accountName(key)).join(", "), "named");
|
|
606
|
-
var unnamed = /* @__PURE__ */ __name(async (store, option = "--source") => new CliError("validation_error", `give ${option} <provider>:<account> \u2014 the store holds ${named(await store
|
|
736
|
+
var unnamed = /* @__PURE__ */ __name(async (store, env, option = "--source") => new CliError("validation_error", `give ${option} <provider>:<account> \u2014 the store holds ${named(await scopedAccounts(store, env)) || "no account yet"}`), "unnamed");
|
|
607
737
|
var storedKeysOf = /* @__PURE__ */ __name(async (store, env, value) => {
|
|
608
738
|
const held = await store.accounts.storedAccounts();
|
|
609
739
|
const holdsFiles = await filesAccounts(store);
|
|
@@ -621,7 +751,7 @@ var storedKeysOf = /* @__PURE__ */ __name(async (store, env, value) => {
|
|
|
621
751
|
var noStoredAccount = /* @__PURE__ */ __name((value) => new CliError("not_found", `${value} names no stored account; notes written with memo notes add belong to none \u2014 name a notes folder (notes:<id>), a mailbox or a messenger account`), "noStoredAccount");
|
|
622
752
|
var oneAccountOf = /* @__PURE__ */ __name(async (store, env, value, option = "--source") => {
|
|
623
753
|
if (value === void 0)
|
|
624
|
-
throw await unnamed(store, option);
|
|
754
|
+
throw await unnamed(store, env, option);
|
|
625
755
|
const keys = await storedKeysOf(store, env, value);
|
|
626
756
|
if (option === "--account" && !value.includes(":") && keys.length === 1)
|
|
627
757
|
throw new CliError("validation_error", `give --account ${named(keys)}; a provider alone does not name an acting account`);
|
|
@@ -636,7 +766,7 @@ var contextSourcesOf = /* @__PURE__ */ __name(async (store, env, value) => {
|
|
|
636
766
|
const holdsFiles = await filesAccounts(store);
|
|
637
767
|
const sources = [];
|
|
638
768
|
const unread = [];
|
|
639
|
-
for (const { entry, accounts } of await listedOf(store, value)) {
|
|
769
|
+
for (const { entry, accounts } of await listedOf(store, env, value)) {
|
|
640
770
|
let read = 0;
|
|
641
771
|
for (const { provider, account: account2, kind } of accounts) {
|
|
642
772
|
const stored = kind === "notes" ? held.find((one2) => holdsFiles(one2) && String(one2.id) === account2) : kind === "messages" || kind === "mail" || kind === "meetings" ? held.find((one2) => one2.provider === provider && one2.account === account2) : void 0;
|
|
@@ -665,7 +795,7 @@ var theAccount = /* @__PURE__ */ __name((store, env, options, warn) => oneAccoun
|
|
|
665
795
|
var theAccounts = /* @__PURE__ */ __name(async (store, env, options, warn) => {
|
|
666
796
|
const value = sourceOf(options, warn);
|
|
667
797
|
if (value === void 0)
|
|
668
|
-
return store
|
|
798
|
+
return scopedAccounts(store, env);
|
|
669
799
|
const keys = await storedKeysOf(store, env, value);
|
|
670
800
|
if (keys.length === 0)
|
|
671
801
|
throw noStoredAccount(value);
|
|
@@ -673,7 +803,7 @@ var theAccounts = /* @__PURE__ */ __name(async (store, env, options, warn) => {
|
|
|
673
803
|
}, "theAccounts");
|
|
674
804
|
var namedAccounts = /* @__PURE__ */ __name(async (store, env, options, warn) => {
|
|
675
805
|
if (sourceOf(options, warn) === void 0)
|
|
676
|
-
throw await unnamed(store);
|
|
806
|
+
throw await unnamed(store, env);
|
|
677
807
|
return theAccounts(store, env, options, warn);
|
|
678
808
|
}, "namedAccounts");
|
|
679
809
|
var accountName = /* @__PURE__ */ __name(({ provider, account: account2 }) => `${provider}:${account2}`, "accountName");
|
|
@@ -710,7 +840,7 @@ var readScope = /* @__PURE__ */ __name((command, help = ONE_ACCOUNT_HELP) => sou
|
|
|
710
840
|
var writeScope = /* @__PURE__ */ __name((command, help) => writeOptions(command, help).option("--json", "print JSON; --json=id,title keeps only those fields"), "writeScope");
|
|
711
841
|
var jsonOption = /* @__PURE__ */ __name((command, fields = "ref,title") => command.option("--json", `print JSON; --json=${fields} keeps only those fields`), "jsonOption");
|
|
712
842
|
|
|
713
|
-
// node_modules/.pnpm/@wirecat+cli-core@0.
|
|
843
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.619.0_@wirecat+cli-base@0.91.0_commander@15.0.0_esbuild@0.28.2_type_25b690dd810be59ade44e4d26e61c9f5/node_modules/@wirecat/cli-core/dist/mail/sender-scores.js
|
|
714
844
|
var SCORED = "mail_sender_scores";
|
|
715
845
|
var DAY = 864e5;
|
|
716
846
|
var RECENT = 2 * 365 * DAY;
|
|
@@ -726,27 +856,10 @@ var demotedSenders = /* @__PURE__ */ __name(async (store) => {
|
|
|
726
856
|
return senders;
|
|
727
857
|
}, "demotedSenders");
|
|
728
858
|
|
|
729
|
-
// node_modules/.pnpm/@wirecat+cli-core@0.
|
|
859
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.619.0_@wirecat+cli-base@0.91.0_commander@15.0.0_esbuild@0.28.2_type_25b690dd810be59ade44e4d26e61c9f5/node_modules/@wirecat/cli-core/dist/mail/sync.js
|
|
730
860
|
var DAY2 = 864e5;
|
|
731
861
|
var EDGE = 2 * DAY2;
|
|
732
862
|
|
|
733
|
-
// dist/vocabulary/project.js
|
|
734
|
-
var canonicalProject = /* @__PURE__ */ __name(async (store, reference2, limits = {}) => {
|
|
735
|
-
if (/^project:[1-9]\d*$/.test(reference2)) {
|
|
736
|
-
const catalog = await store.knowledge.vocabulary({ kind: "project", ...limits });
|
|
737
|
-
if (!catalog.entries.some((entry2) => entry2.id === reference2.slice(8)))
|
|
738
|
-
throw new CliError("not_found", "the owner project is unavailable");
|
|
739
|
-
return reference2;
|
|
740
|
-
}
|
|
741
|
-
const found = await store.knowledge.resolveVocabulary(reference2, { kind: "project", ...limits });
|
|
742
|
-
if (found.matches.length !== 1)
|
|
743
|
-
throw new CliError(found.matches.length ? "validation_error" : "not_found", found.matches.length ? `${reference2} names ${found.matches.length} projects; give one by its key, as memo vocabulary show ${reference2} lists them` : `no project ${reference2}; memo projects list shows yours, memo projects add creates one`, { candidates: found.matches.map((entry2) => ({ id: entry2.id, key: entry2.key, name: entry2.name })) });
|
|
744
|
-
const entry = found.matches[0];
|
|
745
|
-
if (!entry)
|
|
746
|
-
throw new CliError("not_found", "the owner project is unavailable");
|
|
747
|
-
return `project:${entry.id}`;
|
|
748
|
-
}, "canonicalProject");
|
|
749
|
-
|
|
750
863
|
// dist/review/kinds.js
|
|
751
864
|
var REVIEW_KINDS = [
|
|
752
865
|
"relationship",
|
|
@@ -787,6 +900,101 @@ var reviewRegistry = /* @__PURE__ */ __name((store) => {
|
|
|
787
900
|
};
|
|
788
901
|
}, "reviewRegistry");
|
|
789
902
|
|
|
903
|
+
// dist/store/guard.js
|
|
904
|
+
var guardOf = /* @__PURE__ */ __name((store, env) => groupGuardOf(store, APP, env), "guardOf");
|
|
905
|
+
var reviewOf = /* @__PURE__ */ __name(async (store, env) => {
|
|
906
|
+
const guard = await guardOf(store, env);
|
|
907
|
+
return guard === void 0 ? reviewRegistry(store) : lockedRegistry(reviewRegistry(store), guard);
|
|
908
|
+
}, "reviewOf");
|
|
909
|
+
var proposalsOf = /* @__PURE__ */ __name(async (store, env) => {
|
|
910
|
+
const guard = await guardOf(store, env);
|
|
911
|
+
return guard === void 0 ? proposalRegistry(store) : lockedRegistry(proposalRegistry(store), guard);
|
|
912
|
+
}, "proposalsOf");
|
|
913
|
+
var stripped = /* @__PURE__ */ __name(async (store, env, value) => {
|
|
914
|
+
const guard = await guardOf(store, env);
|
|
915
|
+
if (guard === void 0)
|
|
916
|
+
return value;
|
|
917
|
+
const { value: kept, out_of_scope } = await guard.strip(value);
|
|
918
|
+
if (out_of_scope === 0 || kept === null || typeof kept !== "object" || Array.isArray(kept))
|
|
919
|
+
return kept;
|
|
920
|
+
if ("items" in kept) {
|
|
921
|
+
const missing = kept.missing ?? [];
|
|
922
|
+
const why = `${out_of_scope} evidence references outside group ${guard.group} left out`;
|
|
923
|
+
return { ...kept, missing: [...missing, { field: "out_of_scope", why }] };
|
|
924
|
+
}
|
|
925
|
+
return { ...kept, out_of_scope };
|
|
926
|
+
}, "stripped");
|
|
927
|
+
var sourcesIn = /* @__PURE__ */ __name(async (store, env, sources) => {
|
|
928
|
+
const guard = await guardOf(store, env);
|
|
929
|
+
if (guard === void 0)
|
|
930
|
+
return { sources: [...sources] };
|
|
931
|
+
const kept = [];
|
|
932
|
+
for (const one2 of sources)
|
|
933
|
+
if (one2.ref === null || await guard.visible(one2.ref))
|
|
934
|
+
kept.push(one2);
|
|
935
|
+
return { sources: kept, ...kept.length < sources.length ? { out_of_scope: sources.length - kept.length } : {} };
|
|
936
|
+
}, "sourcesIn");
|
|
937
|
+
var lockedCoverage = /* @__PURE__ */ __name(async (store, env, value) => {
|
|
938
|
+
const guard = await guardOf(store, env);
|
|
939
|
+
const scope = guard === void 0 ? void 0 : await groupScopeOf(store, env);
|
|
940
|
+
if (guard === void 0 || scope === void 0)
|
|
941
|
+
return value;
|
|
942
|
+
const held = new Set((await store.accounts.storedAccounts()).map(({ provider, account: account2 }) => `${provider}:${account2}`));
|
|
943
|
+
const outside2 = /* @__PURE__ */ __name((source) => held.has(source) && !scope.accounts.some((key) => `${key.provider}:${key.account}` === source), "outside");
|
|
944
|
+
const walk = /* @__PURE__ */ __name((node) => {
|
|
945
|
+
if (Array.isArray(node))
|
|
946
|
+
return node.map(walk);
|
|
947
|
+
if (node === null || typeof node !== "object")
|
|
948
|
+
return node;
|
|
949
|
+
return Object.fromEntries(Object.entries(node).map(([key, inner]) => {
|
|
950
|
+
if (key !== "notRead" || !Array.isArray(inner))
|
|
951
|
+
return [key, walk(inner)];
|
|
952
|
+
const rows = inner;
|
|
953
|
+
const away = rows.filter((one2) => outside2(one2.source)).length;
|
|
954
|
+
const kept = rows.filter((one2) => !outside2(one2.source));
|
|
955
|
+
return [
|
|
956
|
+
key,
|
|
957
|
+
away ? [...kept, { source: "other accounts", reason: `${away} outside group ${guard.group}` }] : kept
|
|
958
|
+
];
|
|
959
|
+
}));
|
|
960
|
+
}, "walk");
|
|
961
|
+
return walk(value);
|
|
962
|
+
}, "lockedCoverage");
|
|
963
|
+
var refuseOutsideAction = /* @__PURE__ */ __name(async (store, env, id) => {
|
|
964
|
+
const guard = await guardOf(store, env);
|
|
965
|
+
if (guard !== void 0 && !await guard.visible(`action:${id}`))
|
|
966
|
+
throw new CliError("permission_error", `this process is locked to group ${guard.group} \u2014 action ${id} is outside it`, {
|
|
967
|
+
reason: "group.outside"
|
|
968
|
+
});
|
|
969
|
+
}, "refuseOutsideAction");
|
|
970
|
+
var actionsIn = /* @__PURE__ */ __name(async (store, env, actions) => {
|
|
971
|
+
const guard = await guardOf(store, env);
|
|
972
|
+
if (guard === void 0)
|
|
973
|
+
return [...actions];
|
|
974
|
+
const kept = [];
|
|
975
|
+
for (const one2 of actions)
|
|
976
|
+
if (await guard.visible(`action:${one2.id}`))
|
|
977
|
+
kept.push(one2);
|
|
978
|
+
return kept;
|
|
979
|
+
}, "actionsIn");
|
|
980
|
+
|
|
981
|
+
// dist/vocabulary/project.js
|
|
982
|
+
var canonicalProject = /* @__PURE__ */ __name(async (store, reference2, limits = {}) => {
|
|
983
|
+
if (/^project:[1-9]\d*$/.test(reference2)) {
|
|
984
|
+
const catalog = await store.knowledge.vocabulary({ kind: "project", ...limits });
|
|
985
|
+
if (!catalog.entries.some((entry2) => entry2.id === reference2.slice(8)))
|
|
986
|
+
throw new CliError("not_found", "the owner project is unavailable");
|
|
987
|
+
return reference2;
|
|
988
|
+
}
|
|
989
|
+
const found = await store.knowledge.resolveVocabulary(reference2, { kind: "project", ...limits });
|
|
990
|
+
if (found.matches.length !== 1)
|
|
991
|
+
throw new CliError(found.matches.length ? "validation_error" : "not_found", found.matches.length ? `${reference2} names ${found.matches.length} projects; give one by its key, as memo vocabulary show ${reference2} lists them` : `no project ${reference2}; memo projects list shows yours, memo projects add creates one`, { candidates: found.matches.map((entry2) => ({ id: entry2.id, key: entry2.key, name: entry2.name })) });
|
|
992
|
+
const entry = found.matches[0];
|
|
993
|
+
if (!entry)
|
|
994
|
+
throw new CliError("not_found", "the owner project is unavailable");
|
|
995
|
+
return `project:${entry.id}`;
|
|
996
|
+
}, "canonicalProject");
|
|
997
|
+
|
|
790
998
|
// dist/review/review.js
|
|
791
999
|
var STATUSES = ["proposed", "confirmed", "rejected", "all"];
|
|
792
1000
|
var REVIEW_QUERY = {
|
|
@@ -890,15 +1098,15 @@ var reviewItem = /* @__PURE__ */ __name((row, label) => ({
|
|
|
890
1098
|
var rowRefs = /* @__PURE__ */ __name((row) => [row.subject, row.object, row.project], "rowRefs");
|
|
891
1099
|
var listReview = /* @__PURE__ */ __name(async (store, env, words, { limit, page }) => {
|
|
892
1100
|
const filter = await filterOf(store, words);
|
|
893
|
-
const found = await
|
|
1101
|
+
const found = await (await reviewOf(store, env)).list({ ...filter, limit, offset: (page - 1) * limit });
|
|
894
1102
|
const label = await labelsFor(store, found.items.flatMap(rowRefs));
|
|
895
1103
|
return { items: found.items.map((row) => reviewItem(row, label)), hasMore: found.hasMore };
|
|
896
1104
|
}, "listReview");
|
|
897
1105
|
var REVIEW_SOURCES = "memo review list kind:memory_source_review";
|
|
898
|
-
var
|
|
1106
|
+
var reviewItemOf = /* @__PURE__ */ __name(async (store, id) => {
|
|
899
1107
|
const row = await reviewRegistry(store).get(id);
|
|
900
1108
|
return reviewItem(row, await labelsFor(store, rowRefs(row)));
|
|
901
|
-
}, "
|
|
1109
|
+
}, "reviewItemOf");
|
|
902
1110
|
var TEXT_SHOWN = 2e3;
|
|
903
1111
|
var shown = /* @__PURE__ */ __name((text3) => text3 === null || text3.length <= TEXT_SHOWN ? text3 : `${text3.slice(0, TEXT_SHOWN - 1)}\u2026`, "shown");
|
|
904
1112
|
var sourceReviewDetail = /* @__PURE__ */ __name(async (store, id, target) => {
|
|
@@ -921,7 +1129,7 @@ var sourceReviewDetail = /* @__PURE__ */ __name(async (store, id, target) => {
|
|
|
921
1129
|
};
|
|
922
1130
|
}),
|
|
923
1131
|
challenges: payload.challenges,
|
|
924
|
-
suggestions: (payload.suggestions ?? []).map(({ author, body, evidence, at }) => ({ author, body, evidence, at })),
|
|
1132
|
+
suggestions: (payload.suggestions ?? []).map(({ author, body, evidence, at: at2 }) => ({ author, body, evidence, at: at2 })),
|
|
925
1133
|
decide: {
|
|
926
1134
|
stillTrue: `memo review confirm ${id}`,
|
|
927
1135
|
dismiss: `memo review reject ${id} --reason <why>`,
|
|
@@ -932,7 +1140,7 @@ var sourceReviewDetail = /* @__PURE__ */ __name(async (store, id, target) => {
|
|
|
932
1140
|
};
|
|
933
1141
|
}, "sourceReviewDetail");
|
|
934
1142
|
var showReview = /* @__PURE__ */ __name(async (store, env, id) => {
|
|
935
|
-
const row = await
|
|
1143
|
+
const row = await (await reviewOf(store, env)).get(id);
|
|
936
1144
|
const label = await labelsFor(store, [...rowRefs(row), ...row.evidence]);
|
|
937
1145
|
return {
|
|
938
1146
|
...reviewItem(row, label),
|
|
@@ -962,12 +1170,12 @@ var senderOf = /* @__PURE__ */ __name(async (store, ref) => {
|
|
|
962
1170
|
var idRanges = /* @__PURE__ */ __name((ids) => {
|
|
963
1171
|
const numbers = ids.filter((id) => /^\d+$/.test(id)).map(Number).sort((a, b) => a - b);
|
|
964
1172
|
const spans = [];
|
|
965
|
-
for (let
|
|
966
|
-
let end =
|
|
1173
|
+
for (let at2 = 0; at2 < numbers.length; ) {
|
|
1174
|
+
let end = at2;
|
|
967
1175
|
while (end + 1 < numbers.length && numbers[end + 1] === numbers[end] + 1)
|
|
968
1176
|
end++;
|
|
969
|
-
spans.push(end ===
|
|
970
|
-
|
|
1177
|
+
spans.push(end === at2 ? String(numbers[at2]) : `${numbers[at2]}-${numbers[end]}`);
|
|
1178
|
+
at2 = end + 1;
|
|
971
1179
|
}
|
|
972
1180
|
return [...spans, ...ids.filter((id) => !/^\d+$/.test(id))].join(",");
|
|
973
1181
|
}, "idRanges");
|
|
@@ -986,14 +1194,14 @@ var SHOW_STEP = {
|
|
|
986
1194
|
why: "one proposal with its evidence"
|
|
987
1195
|
};
|
|
988
1196
|
var reviewSteps = /* @__PURE__ */ __name((items) => {
|
|
989
|
-
const
|
|
990
|
-
const first =
|
|
1197
|
+
const pending = items.filter((item) => item.status === "proposed");
|
|
1198
|
+
const first = pending[0];
|
|
991
1199
|
if (first === void 0)
|
|
992
1200
|
return [];
|
|
993
1201
|
return [
|
|
994
1202
|
stepOf(CONFIRM_STEP, {
|
|
995
|
-
args: { ids: idRanges(
|
|
996
|
-
values: { count:
|
|
1203
|
+
args: { ids: idRanges(pending.map((item) => item.id)) },
|
|
1204
|
+
values: { count: pending.length }
|
|
997
1205
|
}),
|
|
998
1206
|
stepOf(SHOW_STEP, { args: { id: first.id } })
|
|
999
1207
|
];
|
|
@@ -1012,8 +1220,8 @@ var reviewText = /* @__PURE__ */ __name((items, hasMore) => {
|
|
|
1012
1220
|
for (const item of items)
|
|
1013
1221
|
groups.set(sourceOf2(item), [...groups.get(sourceOf2(item)) ?? [], item]);
|
|
1014
1222
|
const pad = " ".repeat(width);
|
|
1015
|
-
const lines2 = [...groups].flatMap(([source, group],
|
|
1016
|
-
...
|
|
1223
|
+
const lines2 = [...groups].flatMap(([source, group], at2) => [
|
|
1224
|
+
...at2 === 0 ? [] : [""],
|
|
1017
1225
|
source,
|
|
1018
1226
|
...group.flatMap((item) => {
|
|
1019
1227
|
const head = [
|
|
@@ -1041,8 +1249,8 @@ var decisionOf = /* @__PURE__ */ __name((confirm, by, reason) => {
|
|
|
1041
1249
|
const why = reason?.trim();
|
|
1042
1250
|
return { confirm, by, ...by === "owner" && why ? { reason: why } : {} };
|
|
1043
1251
|
}, "decisionOf");
|
|
1044
|
-
var decideOne = /* @__PURE__ */ __name(async (store, id, decision) => {
|
|
1045
|
-
const { decided, refused: refused2 } = await
|
|
1252
|
+
var decideOne = /* @__PURE__ */ __name(async (store, env, id, decision) => {
|
|
1253
|
+
const { decided, refused: refused2 } = await (await proposalsOf(store, env)).decide([id], decision);
|
|
1046
1254
|
const refusal2 = refused2[0];
|
|
1047
1255
|
if (refusal2)
|
|
1048
1256
|
throw new CliError(refusal2.code, refusal2.message, { reason: refusal2.reason });
|
|
@@ -1062,8 +1270,8 @@ var pageOf = /* @__PURE__ */ __name(async (command, limit, read, { fallback = 10
|
|
|
1062
1270
|
|
|
1063
1271
|
// dist/store/scope.js
|
|
1064
1272
|
var choices = /* @__PURE__ */ __name((keys) => keys.length ? `; choose one of ${keys.map(({ provider, account: account2 }) => `${provider}:${account2}`).join(", ")}` : "", "choices");
|
|
1065
|
-
var selectAccount = /* @__PURE__ */ __name(async (store, scope) => {
|
|
1066
|
-
const held = await store
|
|
1273
|
+
var selectAccount = /* @__PURE__ */ __name(async (store, env, scope) => {
|
|
1274
|
+
const held = await scopedAccounts(store, env);
|
|
1067
1275
|
if (!scope.provider)
|
|
1068
1276
|
throw new CliError("validation_error", `give --account <provider>:<account>${choices(held)}`);
|
|
1069
1277
|
const matches2 = held.filter((key) => key.provider === scope.provider && (scope.account === void 0 || key.account === scope.account));
|
|
@@ -1071,16 +1279,16 @@ var selectAccount = /* @__PURE__ */ __name(async (store, scope) => {
|
|
|
1071
1279
|
throw new CliError(matches2.length ? "validation_error" : "not_found", matches2.length ? `several accounts match; give one${choices(matches2)}` : `the store holds no ${scope.provider} account matching this selection${choices(held)}`);
|
|
1072
1280
|
return matches2[0];
|
|
1073
1281
|
}, "selectAccount");
|
|
1074
|
-
var meetingReference = /* @__PURE__ */ __name(async (store, id, scope) => {
|
|
1282
|
+
var meetingReference = /* @__PURE__ */ __name(async (store, env, id, scope) => {
|
|
1075
1283
|
if (!/^\d+$/.test(id))
|
|
1076
1284
|
throw new CliError("validation_error", "--meeting takes the meeting's id in the store");
|
|
1077
|
-
const account2 = await store.accounts.storedAccount(await selectAccount(store, scope));
|
|
1285
|
+
const account2 = await store.accounts.storedAccount(await selectAccount(store, env, scope));
|
|
1078
1286
|
const found = await store.meetings.meeting(Number(id));
|
|
1079
1287
|
if (found === null || found.meeting.accountId !== account2.id)
|
|
1080
1288
|
throw new CliError("not_found", `the ${account2.provider} account ${account2.account} holds no meeting ${id}`);
|
|
1081
1289
|
return `meeting:${account2.id}/${found.meeting.id}`;
|
|
1082
1290
|
}, "meetingReference");
|
|
1083
|
-
var selectTarget = /* @__PURE__ */ __name(async (store, input) => {
|
|
1291
|
+
var selectTarget = /* @__PURE__ */ __name(async (store, env, input) => {
|
|
1084
1292
|
const choices2 = ["message", "chat", "contact", "person", "task", "organization", "project", "meeting"];
|
|
1085
1293
|
const selected = choices2.filter((name2) => input[name2] !== void 0);
|
|
1086
1294
|
if (selected.length !== 1)
|
|
@@ -1098,7 +1306,7 @@ var selectTarget = /* @__PURE__ */ __name(async (store, input) => {
|
|
|
1098
1306
|
throw new CliError("validation_error", "locator and selected account disagree");
|
|
1099
1307
|
return { key: { provider: parsed.provider, account: parsed.account }, target: { type, locator } };
|
|
1100
1308
|
}
|
|
1101
|
-
return { key: await selectAccount(store, input), target: { type, id: input[type] } };
|
|
1309
|
+
return { key: await selectAccount(store, env, input), target: { type, id: input[type] } };
|
|
1102
1310
|
}, "selectTarget");
|
|
1103
1311
|
var scopeOf = /* @__PURE__ */ __name(async (store, env, options, warn) => {
|
|
1104
1312
|
const value = writeAccountOf(options, warn);
|
|
@@ -1147,8 +1355,8 @@ var chatOf = /* @__PURE__ */ __name((reference2) => {
|
|
|
1147
1355
|
if (!reference2.startsWith("msg:") && !reference2.startsWith("chat:"))
|
|
1148
1356
|
return void 0;
|
|
1149
1357
|
try {
|
|
1150
|
-
const
|
|
1151
|
-
return { key: { provider:
|
|
1358
|
+
const at2 = parseLocator(reference2);
|
|
1359
|
+
return { key: { provider: at2.provider, account: at2.account }, chat: at2.chat };
|
|
1152
1360
|
} catch {
|
|
1153
1361
|
return void 0;
|
|
1154
1362
|
}
|
|
@@ -1198,8 +1406,8 @@ var actionItems = /* @__PURE__ */ __name(async (store, actions, { brief = false
|
|
|
1198
1406
|
if (batch?.project && !names.has(batch.project))
|
|
1199
1407
|
for (const project of await store.knowledge.projects())
|
|
1200
1408
|
names.set(project.ref, project.name);
|
|
1201
|
-
return Promise.all(actions.map(async (action,
|
|
1202
|
-
const batch = batches[
|
|
1409
|
+
return Promise.all(actions.map(async (action, at2) => {
|
|
1410
|
+
const batch = batches[at2];
|
|
1203
1411
|
const project = batch?.project ?? (action.target?.startsWith("project:") ? action.target : null);
|
|
1204
1412
|
const projectName = project === null ? null : names.get(project) ?? null;
|
|
1205
1413
|
const targetName = action.target === null ? null : names.get(action.target) ?? null;
|
|
@@ -1218,7 +1426,8 @@ var actionItems = /* @__PURE__ */ __name(async (store, actions, { brief = false
|
|
|
1218
1426
|
}, "actionItems");
|
|
1219
1427
|
var listActions = /* @__PURE__ */ __name((store, query, limit, options = {}) => {
|
|
1220
1428
|
const status = queryTerms(query, ACTION_QUERY, "actions list").get("status");
|
|
1221
|
-
|
|
1429
|
+
const { keep: keep2 = /* @__PURE__ */ __name(async (rows) => rows, "keep"), ...shown3 } = options;
|
|
1430
|
+
return pageOf("actions list", limit, async (most) => actionItems(store, await keep2(await store.proposedActions.list({ limit: most, ...status === void 0 ? {} : { status } })), shown3));
|
|
1222
1431
|
}, "listActions");
|
|
1223
1432
|
var showAction = /* @__PURE__ */ __name(async (store, id) => (await actionItems(store, [await store.proposedActions.get(id)]))[0], "showAction");
|
|
1224
1433
|
var BATCHES = {
|
|
@@ -1262,7 +1471,7 @@ var decideBatch = /* @__PURE__ */ __name(async (store, id, decision) => {
|
|
|
1262
1471
|
throw new CliError(refusal2.code, refusal2.message, { reason: refusal2.reason });
|
|
1263
1472
|
return decided[0];
|
|
1264
1473
|
}, "decideBatch");
|
|
1265
|
-
var propose = /* @__PURE__ */ __name(async (store, proposal, by) => {
|
|
1474
|
+
var propose = /* @__PURE__ */ __name(async (store, env, proposal, by) => {
|
|
1266
1475
|
let payload;
|
|
1267
1476
|
if (proposal.payload !== void 0) {
|
|
1268
1477
|
try {
|
|
@@ -1274,7 +1483,7 @@ var propose = /* @__PURE__ */ __name(async (store, proposal, by) => {
|
|
|
1274
1483
|
return store.proposedActions.propose({
|
|
1275
1484
|
kind: proposal.kind,
|
|
1276
1485
|
by,
|
|
1277
|
-
account: await selectAccount(store, proposal),
|
|
1486
|
+
account: await selectAccount(store, env, proposal),
|
|
1278
1487
|
reason: proposal.reason,
|
|
1279
1488
|
...proposal.target === void 0 ? {} : { target: proposal.target },
|
|
1280
1489
|
...payload === void 0 ? {} : { payload }
|
|
@@ -1288,27 +1497,35 @@ var actionsCommand = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
1288
1497
|
writeOptions(byOption(annotate(actions.command("add"), { effects: LOCAL_WRITE }).description("propose an action, such as a reply or a ban, in the account that would act")).argument("<kind>", "a lower-case word: reply, send, ban, mute, pin, invite, create_task, \u2026").requiredOption("--reason <text>", "why it should be done"), "the account that would act: provider:account, such as telegram:1").option("--target <ref>", "what it acts on: msg:, chat:, contact:, person:, task:, \u2026").option("--payload <json>", "what to do, as JSON, such as the reply's text").option("--json", "print JSON; --json=id,title keeps only those fields").action((kind, { asOwner, account: account2, ...options }, command) => run(options.json, async (store) => {
|
|
1289
1498
|
const by = await whoRuns(command, env, { asOwner, question: "propose this action as yours?" });
|
|
1290
1499
|
const key = await writeAccount(store, env, { account: account2 }, (text3) => streams.diagnostic(text3));
|
|
1291
|
-
return itemAnswer(await propose(store, { ...options, ...key, kind }, by));
|
|
1500
|
+
return itemAnswer(await propose(store, env, { ...options, ...key, kind }, by));
|
|
1501
|
+
}));
|
|
1502
|
+
withQuery(annotate(actions.command("list"), { effects: LOCAL_READ, output: { entity: "proposed_action" } }).description("proposed actions, newest first"), ACTION_QUERY).option("--limit <n>", "most actions, up to 500", positive, 100).option("--brief", "without each findings batch's cited sources").option("--json", "print JSON; --json=id,title keeps only those fields").action((words, options) => run(options.json, async (store) => stripped(store, env, await listActions(store, words, options.limit, {
|
|
1503
|
+
brief: options.brief === true,
|
|
1504
|
+
keep: /* @__PURE__ */ __name((rows) => actionsIn(store, env, rows), "keep")
|
|
1505
|
+
}))));
|
|
1506
|
+
annotate(actions.command("show"), { effects: LOCAL_READ }).description("one proposed action; a findings batch with its fingerprint and sources").argument("<id>", "the action's id, as actions list gives it").option("--json", "print JSON; --json=id,title keeps only those fields").action((id, options) => run(options.json, async (store) => {
|
|
1507
|
+
await refuseOutsideAction(store, env, id);
|
|
1508
|
+
return itemAnswer(await stripped(store, env, await showAction(store, id)));
|
|
1292
1509
|
}));
|
|
1293
|
-
withQuery(annotate(actions.command("list"), { effects: LOCAL_READ, output: { entity: "proposed_action" } }).description("proposed actions, newest first"), ACTION_QUERY).option("--limit <n>", "most actions, up to 500", positive, 100).option("--brief", "without each findings batch's cited sources").option("--json", "print JSON; --json=id,title keeps only those fields").action((words, options) => run(options.json, (store) => listActions(store, words, options.limit, { brief: options.brief === true })));
|
|
1294
|
-
annotate(actions.command("show"), { effects: LOCAL_READ }).description("one proposed action; a findings batch with its fingerprint and sources").argument("<id>", "the action's id, as actions list gives it").option("--json", "print JSON; --json=id,title keeps only those fields").action((id, options) => run(options.json, async (store) => itemAnswer(await showAction(store, id))));
|
|
1295
1510
|
byOption(annotate(actions.command("confirm"), { effects: LOCAL_WRITE })).summary("confirm it: a task to act on, or a findings batch's facts and tasks").description("confirm it: it becomes a task in the account that would act, nothing is sent; for a findings batch, create the named findings (all when none is named) and reject the rest").argument("<id>", "the action's id, as actions list gives it").argument("[findings...]", "a findings batch: the finding IDs to create").option("--fingerprint <hash>", "a findings batch: the fingerprint actions show gives").option("--reason <text>", "why, in a few words; required when an agent decides for you").option("--json", "print JSON; --json=id,title keeps only those fields").action(async (id, findings, options, command) => {
|
|
1296
1511
|
const by = await deciderOf(command, env, { ...options, question: `confirm action ${id} as you, the owner?` });
|
|
1297
1512
|
await run(options.json, async (store) => {
|
|
1513
|
+
await refuseOutsideAction(store, env, id);
|
|
1298
1514
|
const findingsAnswer = await decideFindings(store, id, { ...options, accept: findings, confirm: true, by });
|
|
1299
1515
|
if (findingsAnswer)
|
|
1300
1516
|
return itemAnswer(findingsAnswer);
|
|
1301
|
-
assertMayDecide(await
|
|
1517
|
+
assertMayDecide(await (await proposalsOf(store, env)).get(id), by, store.decisionPolicy);
|
|
1302
1518
|
return itemAnswer(await approveAsTask(store, id, by));
|
|
1303
1519
|
});
|
|
1304
1520
|
});
|
|
1305
1521
|
byOption(annotate(actions.command("reject"), { effects: LOCAL_WRITE })).description("reject it; nothing is done. For a findings batch, every new finding").argument("<id>", "the action's id, as actions list gives it").option("--fingerprint <hash>", "a findings batch: the fingerprint actions show gives").option("--reason <text>", "why, in a few words; required when an agent decides for you").option("--json", "print JSON; --json=id,title keeps only those fields").action(async (id, options, command) => {
|
|
1306
1522
|
const by = await deciderOf(command, env, { ...options, question: `reject action ${id} as you, the owner?` });
|
|
1307
1523
|
await run(options.json, async (store) => {
|
|
1524
|
+
await refuseOutsideAction(store, env, id);
|
|
1308
1525
|
const findingsAnswer = await decideFindings(store, id, { ...options, accept: [], confirm: false, by });
|
|
1309
1526
|
if (findingsAnswer)
|
|
1310
1527
|
return itemAnswer(findingsAnswer);
|
|
1311
|
-
await decideOne(store, id, decisionOf(false, by, options.reason));
|
|
1528
|
+
await decideOne(store, env, id, decisionOf(false, by, options.reason));
|
|
1312
1529
|
return itemAnswer(await store.proposedActions.get(id));
|
|
1313
1530
|
});
|
|
1314
1531
|
});
|
|
@@ -1447,12 +1664,12 @@ var markKey = /* @__PURE__ */ __name(async (store, project, ref, reason, author)
|
|
|
1447
1664
|
return describe(store, link2);
|
|
1448
1665
|
}, "markKey");
|
|
1449
1666
|
var proposeKey = /* @__PURE__ */ __name(async (store, project, ref, reason, author, source) => {
|
|
1450
|
-
const
|
|
1667
|
+
const pending = await store.proposedActions.list({
|
|
1451
1668
|
kinds: ["key_document"],
|
|
1452
1669
|
status: "proposed",
|
|
1453
1670
|
project: project.ref
|
|
1454
1671
|
});
|
|
1455
|
-
const proposal =
|
|
1672
|
+
const proposal = pending.find((one2) => one2.payload?.ref === ref) ?? await store.proposedActions.propose({
|
|
1456
1673
|
kind: "key_document",
|
|
1457
1674
|
by: author,
|
|
1458
1675
|
target: ref,
|
|
@@ -1614,7 +1831,7 @@ var personTasks = /* @__PURE__ */ __name(async (store, person, accounts, limit)
|
|
|
1614
1831
|
|
|
1615
1832
|
// dist/search/search.js
|
|
1616
1833
|
var CHATS_CHECKED = 500;
|
|
1617
|
-
var MEMO =
|
|
1834
|
+
var MEMO = MEMO_ACCOUNT;
|
|
1618
1835
|
var unifiedSearch = /* @__PURE__ */ __name(async (store, query, options) => {
|
|
1619
1836
|
const limit = options.limit ?? 20, offset = options.offset ?? 0;
|
|
1620
1837
|
if (!Number.isInteger(limit) || limit < 1 || limit > 100 || !Number.isInteger(offset) || offset < 0 || offset > 1e3)
|
|
@@ -1731,7 +1948,7 @@ var searchAccounts = /* @__PURE__ */ __name(async (store, env, options) => {
|
|
|
1731
1948
|
if (options.all && options.source !== void 0)
|
|
1732
1949
|
throw new CliError("validation_error", "use --all alone, or name the accounts with --source");
|
|
1733
1950
|
if (options.all)
|
|
1734
|
-
return { keys: (await store
|
|
1951
|
+
return { keys: (await scopedAccounts(store, env)).filter(({ provider }) => provider !== "notes"), notes: true };
|
|
1735
1952
|
if (options.source === void 0)
|
|
1736
1953
|
throw new CliError("validation_error", "give --all, or name the accounts with --source: telegram:1,email,notes");
|
|
1737
1954
|
const keys = await accountsOf(store, env, options.source);
|
|
@@ -1755,20 +1972,41 @@ var allowedPage = /* @__PURE__ */ __name(async (ask, limit, shows) => {
|
|
|
1755
1972
|
const { nextOffset: _, ...rest } = first;
|
|
1756
1973
|
return { ...rest, items: items.slice(0, limit), hasMore: items.length > limit || page.hasMore };
|
|
1757
1974
|
}, "allowedPage");
|
|
1975
|
+
var groupScoped = /* @__PURE__ */ __name(async (store, env, only) => {
|
|
1976
|
+
const scope = await groupScopeOf(store, env);
|
|
1977
|
+
if (scope === void 0)
|
|
1978
|
+
return void 0;
|
|
1979
|
+
const kinds2 = accountsByKind(scope, await store.business.accounts());
|
|
1980
|
+
const wanted = only ?? RESOURCES_SEARCHED;
|
|
1981
|
+
const kept = wanted.filter((kind) => kinds2[kind].length > 0);
|
|
1982
|
+
if (kept.length === 0)
|
|
1983
|
+
throw new CliError("validation_error", `group ${scope.run.name} holds no account of ${wanted.join(", ")}`);
|
|
1984
|
+
return {
|
|
1985
|
+
only: kept,
|
|
1986
|
+
scope: Object.fromEntries(kept.map((kind) => [kind, kinds2[kind]])),
|
|
1987
|
+
skipped: wanted.filter((kind) => !kept.includes(kind)).map((resource) => ({
|
|
1988
|
+
resource,
|
|
1989
|
+
code: "not_found",
|
|
1990
|
+
reason: `group ${scope.run.name} holds no account of it`
|
|
1991
|
+
}))
|
|
1992
|
+
};
|
|
1993
|
+
}, "groupScoped");
|
|
1758
1994
|
var searchEverywhere = /* @__PURE__ */ __name(async (store, env, { text: text3, limit, only, crmKinds, exact, timezone, plainOrder, shows }) => {
|
|
1759
|
-
const accounts = await store
|
|
1995
|
+
const accounts = await scopedAccounts(store, env);
|
|
1996
|
+
const group = await groupScoped(store, env, only);
|
|
1760
1997
|
const messenger2 = { app: { ...APP, command: "tg" }, hintCommand: "memo" };
|
|
1761
1998
|
const ask = /* @__PURE__ */ __name((offset) => searchAll(store, MEMO, {
|
|
1762
1999
|
text: text3,
|
|
1763
2000
|
limit,
|
|
1764
2001
|
env,
|
|
1765
2002
|
...offset === void 0 ? {} : { offset },
|
|
1766
|
-
...only === void 0 ? {} : { only },
|
|
2003
|
+
...group === void 0 ? only === void 0 ? {} : { only } : { only: group.only, scope: group.scope },
|
|
1767
2004
|
...crmKinds === void 0 ? {} : { crmKinds },
|
|
1768
2005
|
...exact ? { exact: true } : {},
|
|
1769
2006
|
...timezone === void 0 ? {} : { timezone }
|
|
1770
2007
|
}, messenger2, (query) => searchStore(store, MEMO, query, messenger2), meaningLane({ env, store: /* @__PURE__ */ __name(async () => store, "store"), messenger: { app: { command: "memo" } } })), "ask");
|
|
1771
|
-
const
|
|
2008
|
+
const searched = shows === void 0 ? await ask() : await allowedPage(ask, limit, shows);
|
|
2009
|
+
const found = group === void 0 ? searched : { ...searched, skipped: [...group.skipped, ...searched.skipped] };
|
|
1772
2010
|
const tasks = [];
|
|
1773
2011
|
let tasksIncomplete = false;
|
|
1774
2012
|
const sources = found.items.map((item) => item.ref);
|
|
@@ -1822,7 +2060,7 @@ var searchKind = /* @__PURE__ */ __name(async (store, kind, { text: text3, limit
|
|
|
1822
2060
|
return searchStore(store, MEMO, {
|
|
1823
2061
|
text: text3,
|
|
1824
2062
|
kind,
|
|
1825
|
-
...hasSource(parseLucene(plain).root) ? {} : { source: "all" },
|
|
2063
|
+
...hasSource(parseLucene(plain).root) || accounts !== void 0 ? {} : { source: "all" },
|
|
1826
2064
|
limit,
|
|
1827
2065
|
...scope,
|
|
1828
2066
|
// As search all does: a question finds a short reply by the message it answers, and records holding some words.
|
|
@@ -1938,7 +2176,7 @@ var configCommand = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
1938
2176
|
const values = rows.map((row) => `${JSON.stringify(row.value)}${row.from === "default" ? " (default)" : ""}`);
|
|
1939
2177
|
const wide = /* @__PURE__ */ __name((texts) => texts.reduce((most, text3) => Math.max(most, text3.length), 0), "wide");
|
|
1940
2178
|
const [settingWidth, valueWidth] = [wide(rows.map((row) => row.setting)), wide(values)];
|
|
1941
|
-
const lines2 = rows.map((row,
|
|
2179
|
+
const lines2 = rows.map((row, at2) => `${row.setting.padEnd(settingWidth)} ${values[at2]?.padEnd(valueWidth)} ${row.description}`);
|
|
1942
2180
|
print(options.json, itemAnswer({ path: configPath(env), found: raw !== void 0, settings: rows }), [configPath(env), ...lines2].join("\n"));
|
|
1943
2181
|
});
|
|
1944
2182
|
annotate(config.command("migrate"), { effects: LOCAL_WRITE }).description("write each setting the file lacks at its default, keeping yours").option("--json", "print JSON; --json=id,title keeps only those fields").action((options) => {
|
|
@@ -1951,6 +2189,18 @@ var configCommand = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
1951
2189
|
});
|
|
1952
2190
|
}, "configCommand");
|
|
1953
2191
|
|
|
2192
|
+
// dist/knowledge/business-text.js
|
|
2193
|
+
var relatedLine = /* @__PURE__ */ __name(({ ref, name: name2, roles }) => ` ${name2 ?? ref} ${ref} ${roles.map((role) => [role.kind, role.role, role.position && `(${role.position})`, role.standing, role.account && `by ${role.account}`].filter(Boolean).join(" ")).join("; ")}`, "relatedLine");
|
|
2194
|
+
var sectionLines = /* @__PURE__ */ __name((title, section2, line3 = relatedLine) => section2.items.length === 0 ? [] : [
|
|
2195
|
+
title,
|
|
2196
|
+
...section2.items.map(line3),
|
|
2197
|
+
...section2.hasMore ? [` ${section2.total} in all${section2.next ? ` \u2014 memo ${section2.next}` : ""}`] : []
|
|
2198
|
+
], "sectionLines");
|
|
2199
|
+
var coverageLines = /* @__PURE__ */ __name((coverage) => [
|
|
2200
|
+
`Read: ${coverage.accounts.join(", ") || "no account"}`,
|
|
2201
|
+
...coverage.notRead.map(({ source, reason }) => `Not read: ${source} \u2014 ${reason}`)
|
|
2202
|
+
], "coverageLines");
|
|
2203
|
+
|
|
1954
2204
|
// dist/notes/bound.js
|
|
1955
2205
|
import { resolve as resolve2 } from "node:path";
|
|
1956
2206
|
|
|
@@ -1971,22 +2221,22 @@ var withFolders = /* @__PURE__ */ __name((config, folders) => ({
|
|
|
1971
2221
|
}
|
|
1972
2222
|
}), "withFolders");
|
|
1973
2223
|
var bindFolder = /* @__PURE__ */ __name((config, folder) => {
|
|
1974
|
-
const
|
|
2224
|
+
const at2 = resolve(folder.path);
|
|
1975
2225
|
const folders = noteFolders(config.notes);
|
|
1976
|
-
const index = folders.findIndex((other) => other.path ===
|
|
1977
|
-
const bound = { ...folder, path:
|
|
1978
|
-
const kept = folders.map((other, position) => position === index ? bound : other).filter((other, position) => position === index || other.id !== folder.id && other.path !==
|
|
2226
|
+
const index = folders.findIndex((other) => other.path === at2);
|
|
2227
|
+
const bound = { ...folder, path: at2 };
|
|
2228
|
+
const kept = folders.map((other, position) => position === index ? bound : other).filter((other, position) => position === index || other.id !== folder.id && other.path !== at2);
|
|
1979
2229
|
return withFolders(config, index < 0 ? [...kept, bound] : kept);
|
|
1980
2230
|
}, "bindFolder");
|
|
1981
2231
|
var attachFolder = /* @__PURE__ */ __name((config, id, path, format) => {
|
|
1982
|
-
const
|
|
2232
|
+
const at2 = resolve(path);
|
|
1983
2233
|
const folders = noteFolders(config.notes);
|
|
1984
|
-
const taken = folders.find((folder2) => folder2.path ===
|
|
2234
|
+
const taken = folders.find((folder2) => folder2.path === at2 && folder2.id !== null && folder2.id !== id);
|
|
1985
2235
|
if (taken)
|
|
1986
|
-
throw new CliError("validation_error", `${
|
|
2236
|
+
throw new CliError("validation_error", `${at2} is already folder ${taken.id} \u2014 attach that id elsewhere first, or remove it from the config`);
|
|
1987
2237
|
const previous = folders.find((folder2) => folder2.id === id);
|
|
1988
|
-
const folder = { id, path:
|
|
1989
|
-
const kept = folders.filter((other) => other.id !== id && other.path !==
|
|
2238
|
+
const folder = { id, path: at2, format: format ?? previous?.format ?? "obsidian" };
|
|
2239
|
+
const kept = folders.filter((other) => other.id !== id && other.path !== at2);
|
|
1990
2240
|
return { config: withFolders(config, [...kept, folder]), folder };
|
|
1991
2241
|
}, "attachFolder");
|
|
1992
2242
|
var unbindFolder = /* @__PURE__ */ __name((config, path) => withFolders(config, noteFolders(config.notes).filter((folder) => folder.path !== resolve(path))), "unbindFolder");
|
|
@@ -2019,11 +2269,11 @@ var folderIds = /* @__PURE__ */ __name(async (store, env, selected) => {
|
|
|
2019
2269
|
return [.../* @__PURE__ */ new Set([...selected.filter((value) => known2.has(value)), ...bound.map(({ id }) => id)])];
|
|
2020
2270
|
}, "folderIds");
|
|
2021
2271
|
var folderOfFile = /* @__PURE__ */ __name((folders, file) => {
|
|
2022
|
-
const
|
|
2023
|
-
const folder = folders.find((candidate) =>
|
|
2272
|
+
const at2 = resolve2(file);
|
|
2273
|
+
const folder = folders.find((candidate) => at2.startsWith(`${candidate.path}/`));
|
|
2024
2274
|
if (!folder)
|
|
2025
|
-
throw new CliError("not_found", `${
|
|
2026
|
-
return { folder, path:
|
|
2275
|
+
throw new CliError("not_found", `${at2} is in no configured folder of notes`, { reason: "folder.not-found" });
|
|
2276
|
+
return { folder, path: at2.slice(folder.path.length + 1) };
|
|
2027
2277
|
}, "folderOfFile");
|
|
2028
2278
|
|
|
2029
2279
|
// dist/people/notes-map.js
|
|
@@ -2035,7 +2285,7 @@ import { createHash } from "node:crypto";
|
|
|
2035
2285
|
import { existsSync, readFileSync as readFileSync2, statSync } from "node:fs";
|
|
2036
2286
|
import { basename, extname, relative, sep } from "node:path";
|
|
2037
2287
|
|
|
2038
|
-
// node_modules/.pnpm/@wirecat+cli-core@0.
|
|
2288
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.619.0_@wirecat+cli-base@0.91.0_commander@15.0.0_esbuild@0.28.2_type_25b690dd810be59ade44e4d26e61c9f5/node_modules/@wirecat/cli-core/dist/services/documents/extraction.js
|
|
2039
2289
|
var Proposal = object({
|
|
2040
2290
|
kind: picklist(["summary", "digest", "fact", "preference"]),
|
|
2041
2291
|
body: pipe(string(), trim(), minLength(1), maxLength(15e3)),
|
|
@@ -2043,13 +2293,13 @@ var Proposal = object({
|
|
|
2043
2293
|
});
|
|
2044
2294
|
var Proposals = object({ items: pipe(array(Proposal), maxLength(20)) });
|
|
2045
2295
|
|
|
2046
|
-
// node_modules/.pnpm/@wirecat+cli-core@0.
|
|
2296
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.619.0_@wirecat+cli-base@0.91.0_commander@15.0.0_esbuild@0.28.2_type_25b690dd810be59ade44e4d26e61c9f5/node_modules/@wirecat/cli-core/dist/services/documents/mirrors.js
|
|
2047
2297
|
var ID = pipe(string(), regex(/^[A-Za-z0-9_-]{1,200}$/));
|
|
2048
2298
|
|
|
2049
|
-
// node_modules/.pnpm/@wirecat+cli-core@0.
|
|
2299
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.619.0_@wirecat+cli-base@0.91.0_commander@15.0.0_esbuild@0.28.2_type_25b690dd810be59ade44e4d26e61c9f5/node_modules/@wirecat/cli-core/dist/services/documents/sync.js
|
|
2050
2300
|
var MAX_PICTURE_BYTES = 25 * 1024 * 1024;
|
|
2051
2301
|
|
|
2052
|
-
// node_modules/.pnpm/@wirecat+cli-core@0.
|
|
2302
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.619.0_@wirecat+cli-base@0.91.0_commander@15.0.0_esbuild@0.28.2_type_25b690dd810be59ade44e4d26e61c9f5/node_modules/@wirecat/cli-core/dist/fetch/addresses.js
|
|
2053
2303
|
import { isIP } from "node:net";
|
|
2054
2304
|
var within3 = /* @__PURE__ */ __name((address, [prefix, bits]) => {
|
|
2055
2305
|
for (let bit = 0; bit < bits; bit++) {
|
|
@@ -2100,9 +2350,9 @@ var v6Bytes = /* @__PURE__ */ __name((text3) => {
|
|
|
2100
2350
|
const left = groups(head);
|
|
2101
2351
|
const right = tail === void 0 ? [] : groups(tail);
|
|
2102
2352
|
const all = [...left, ...new Array(8 - left.length - right.length).fill(0), ...right];
|
|
2103
|
-
all.forEach((group,
|
|
2104
|
-
bytes[
|
|
2105
|
-
bytes[
|
|
2353
|
+
all.forEach((group, at2) => {
|
|
2354
|
+
bytes[at2 * 2] = group >> 8;
|
|
2355
|
+
bytes[at2 * 2 + 1] = group & 255;
|
|
2106
2356
|
});
|
|
2107
2357
|
return bytes;
|
|
2108
2358
|
}, "v6Bytes");
|
|
@@ -2114,13 +2364,13 @@ var isPublicAddress = /* @__PURE__ */ __name((address) => {
|
|
|
2114
2364
|
if (family !== 6)
|
|
2115
2365
|
return false;
|
|
2116
2366
|
const bytes = v6Bytes(address);
|
|
2117
|
-
for (const [prefix,
|
|
2367
|
+
for (const [prefix, at2] of V6_CARRIERS)
|
|
2118
2368
|
if (within3(bytes, prefix))
|
|
2119
|
-
return publicV4(bytes.subarray(
|
|
2369
|
+
return publicV4(bytes.subarray(at2, at2 + 4));
|
|
2120
2370
|
return within3(bytes, [[32], 3]) && !V6_PRIVATE.some((prefix) => within3(bytes, prefix));
|
|
2121
2371
|
}, "isPublicAddress");
|
|
2122
2372
|
|
|
2123
|
-
// node_modules/.pnpm/@wirecat+cli-core@0.
|
|
2373
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.619.0_@wirecat+cli-base@0.91.0_commander@15.0.0_esbuild@0.28.2_type_25b690dd810be59ade44e4d26e61c9f5/node_modules/@wirecat/cli-core/dist/fetch/page.js
|
|
2124
2374
|
import { lookup as dnsLookup } from "node:dns/promises";
|
|
2125
2375
|
import { request as httpRequest } from "node:http";
|
|
2126
2376
|
import { request as httpsRequest } from "node:https";
|
|
@@ -2209,14 +2459,14 @@ var readBody = /* @__PURE__ */ __name(async (response, limit) => {
|
|
|
2209
2459
|
chunks.push(chunk);
|
|
2210
2460
|
}
|
|
2211
2461
|
const bytes = new Uint8Array(size);
|
|
2212
|
-
let
|
|
2462
|
+
let at2 = 0;
|
|
2213
2463
|
for (const chunk of chunks) {
|
|
2214
|
-
bytes.set(chunk,
|
|
2215
|
-
|
|
2464
|
+
bytes.set(chunk, at2);
|
|
2465
|
+
at2 += chunk.byteLength;
|
|
2216
2466
|
}
|
|
2217
2467
|
return bytes;
|
|
2218
2468
|
}, "readBody");
|
|
2219
|
-
var needsSignIn = /* @__PURE__ */ __name((url) => new CliError("authentication_error", `${url.hostname} asks for a sign-in:
|
|
2469
|
+
var needsSignIn = /* @__PURE__ */ __name((url) => new CliError("authentication_error", `${url.hostname} asks for a sign-in: add a private Google document through Drive, with drive documents add <url> --profiles <names|all>`, {
|
|
2220
2470
|
reason: "source.needs-sign-in"
|
|
2221
2471
|
}), "needsSignIn");
|
|
2222
2472
|
var isSignInPage = /* @__PURE__ */ __name((bytes, contentType) => {
|
|
@@ -2395,11 +2645,11 @@ var notesNamed = /* @__PURE__ */ __name((source, target, documents) => {
|
|
|
2395
2645
|
return documents.filter((doc) => [stem(posix.basename(doc.path)), ...doc.aliases].some((known2) => fold2(known2) === name2));
|
|
2396
2646
|
}, "notesNamed");
|
|
2397
2647
|
var fileLinks = /* @__PURE__ */ __name((source, links, documents) => links.map(({ target, anchor }) => {
|
|
2398
|
-
const
|
|
2648
|
+
const at2 = anchor === null ? {} : { anchor };
|
|
2399
2649
|
if (isReference(target))
|
|
2400
|
-
return { to: target, kind: "links-to", ...
|
|
2650
|
+
return { to: target, kind: "links-to", ...at2 };
|
|
2401
2651
|
const named5 = notesNamed(source, target, documents);
|
|
2402
|
-
return named5.length === 1 ? { to: `document:${named5[0].id}`, kind: "links-to", ...
|
|
2652
|
+
return named5.length === 1 ? { to: `document:${named5[0].id}`, kind: "links-to", ...at2 } : { targetText: posix.basename(target.replace(/\\/g, "/")) || target, kind: "links-to", ...at2 };
|
|
2403
2653
|
}), "fileLinks");
|
|
2404
2654
|
|
|
2405
2655
|
// dist/notes/renames.js
|
|
@@ -2654,12 +2904,12 @@ var importNotesMap = /* @__PURE__ */ __name(async (store, env, folders) => {
|
|
|
2654
2904
|
done = JSON.parse(readFileSync3(donePath(env), "utf8"));
|
|
2655
2905
|
} catch {
|
|
2656
2906
|
}
|
|
2657
|
-
const
|
|
2658
|
-
if (
|
|
2907
|
+
const pending = Object.entries(map).filter(([uid]) => !done.includes(uid));
|
|
2908
|
+
if (pending.length === 0)
|
|
2659
2909
|
return 0;
|
|
2660
2910
|
const byFolder = /* @__PURE__ */ new Map();
|
|
2661
2911
|
let linked2 = 0;
|
|
2662
|
-
for (const [uid, file] of
|
|
2912
|
+
for (const [uid, file] of pending) {
|
|
2663
2913
|
let place;
|
|
2664
2914
|
try {
|
|
2665
2915
|
place = folderOfFile(folders, file);
|
|
@@ -2689,7 +2939,7 @@ var importNotesMap = /* @__PURE__ */ __name(async (store, env, folders) => {
|
|
|
2689
2939
|
// dist/review/status.js
|
|
2690
2940
|
var MOST_PAGES = 10;
|
|
2691
2941
|
var counted2 = /* @__PURE__ */ __name(async (store, env, filter, since) => {
|
|
2692
|
-
const registry =
|
|
2942
|
+
const registry = await reviewOf(store, env);
|
|
2693
2943
|
const byKind = {};
|
|
2694
2944
|
let total = 0;
|
|
2695
2945
|
for (let page = 0; page < MOST_PAGES; page++) {
|
|
@@ -2705,7 +2955,7 @@ var counted2 = /* @__PURE__ */ __name(async (store, env, filter, since) => {
|
|
|
2705
2955
|
}, "counted");
|
|
2706
2956
|
var waitingAbout = /* @__PURE__ */ __name(async (store, env, refs) => {
|
|
2707
2957
|
const wanted = new Set(refs);
|
|
2708
|
-
const registry =
|
|
2958
|
+
const registry = await reviewOf(store, env);
|
|
2709
2959
|
const kinds2 = {};
|
|
2710
2960
|
let count = 0;
|
|
2711
2961
|
for (let page = 0; page < MOST_PAGES; page++) {
|
|
@@ -2722,7 +2972,7 @@ var waitingAbout = /* @__PURE__ */ __name(async (store, env, refs) => {
|
|
|
2722
2972
|
}, "waitingAbout");
|
|
2723
2973
|
var reviewStatus = /* @__PURE__ */ __name(async (store, env, since, now = Date.now()) => {
|
|
2724
2974
|
const mail = [];
|
|
2725
|
-
for (const key of (await store
|
|
2975
|
+
for (const key of (await scopedAccounts(store, env)).filter((one2) => one2.provider === "email")) {
|
|
2726
2976
|
const stored = await store.accounts.storedAccount(key);
|
|
2727
2977
|
const turns = (await store.mail.threadActivity(stored.id, now - OWED_DAYS * 864e5)).map((thread) => ({
|
|
2728
2978
|
at: thread.lastEmailAt,
|
|
@@ -2737,14 +2987,14 @@ var reviewStatus = /* @__PURE__ */ __name(async (store, env, since, now = Date.n
|
|
|
2737
2987
|
});
|
|
2738
2988
|
}
|
|
2739
2989
|
const proposed = await counted2(store, env, { status: "all" }, since);
|
|
2740
|
-
const
|
|
2990
|
+
const pending = await counted2(store, env, { status: "proposed" });
|
|
2741
2991
|
return {
|
|
2742
2992
|
since: new Date(since).toISOString(),
|
|
2743
2993
|
at: new Date(now).toISOString(),
|
|
2744
2994
|
mail,
|
|
2745
2995
|
proposed: { count: proposed.total, kinds: proposed.byKind, complete: proposed.complete },
|
|
2746
|
-
waiting: { count:
|
|
2747
|
-
quiet: proposed.total === 0 &&
|
|
2996
|
+
waiting: { count: pending.total, kinds: pending.byKind, complete: pending.complete },
|
|
2997
|
+
quiet: proposed.total === 0 && pending.total === 0 && mail.every((one2) => one2.threads === 0 && one2.owed === 0 && one2.waiting === 0)
|
|
2748
2998
|
};
|
|
2749
2999
|
}, "reviewStatus");
|
|
2750
3000
|
var kindsText = /* @__PURE__ */ __name((kinds2) => Object.entries(kinds2).sort(([, a], [, b]) => b - a).map(([kind, count]) => `${kind} ${count}`).join(", "), "kindsText");
|
|
@@ -2762,6 +3012,10 @@ var reviewStatusText = /* @__PURE__ */ __name((status) => {
|
|
|
2762
3012
|
].join("\n");
|
|
2763
3013
|
}, "reviewStatusText");
|
|
2764
3014
|
|
|
3015
|
+
// dist/search/denied.js
|
|
3016
|
+
var deniedCrm = /* @__PURE__ */ __name((command, env) => deniedKindsOf(memoLevels(env, environmentOf(command).agent?.overrides ?? []), DEAL_KINDS, "memo's permissions"), "deniedCrm");
|
|
3017
|
+
var deniedCrmKinds = /* @__PURE__ */ __name((command, env) => deniedCrm(command, env).map(({ kind }) => kind), "deniedCrmKinds");
|
|
3018
|
+
|
|
2765
3019
|
// dist/people/owner.js
|
|
2766
3020
|
var withOwner = /* @__PURE__ */ __name(async (store, reference2) => {
|
|
2767
3021
|
if (reference2.trim() !== "person:me")
|
|
@@ -2779,7 +3033,6 @@ var UNTRUSTED_EVENT_FIELDS = [
|
|
|
2779
3033
|
"events.recent.title",
|
|
2780
3034
|
"events.recent.location"
|
|
2781
3035
|
];
|
|
2782
|
-
var RELATIONS = /* @__PURE__ */ new Set(["member-of", "related-to"]);
|
|
2783
3036
|
var SOURCE_REPORTS = /* @__PURE__ */ new Set(["google-drive:files.get"]);
|
|
2784
3037
|
var reportedFiles = /* @__PURE__ */ __name(async (store, links, limit) => {
|
|
2785
3038
|
const files = [];
|
|
@@ -2806,43 +3059,53 @@ var reportedFiles = /* @__PURE__ */ __name(async (store, links, limit) => {
|
|
|
2806
3059
|
}
|
|
2807
3060
|
return files;
|
|
2808
3061
|
}, "reportedFiles");
|
|
2809
|
-
var
|
|
2810
|
-
const
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
throw new CliError("not_found", `no person:${uid} in the store`);
|
|
2819
|
-
const seen = person.identities.flatMap((identity) => identity.accounts.map((held) => ({
|
|
2820
|
-
reference: `${identity.provider}:${identity.id}`,
|
|
2821
|
-
provider: identity.provider,
|
|
2822
|
-
account: held
|
|
2823
|
-
})));
|
|
2824
|
-
const matches2 = seen.filter((one2) => source === void 0 || one2.provider === source.provider && one2.account === source.account);
|
|
2825
|
-
const accounts = [...new Set(matches2.map((one2) => `${one2.provider}:${one2.account}`))];
|
|
2826
|
-
const [first] = matches2;
|
|
2827
|
-
if (accounts.length === 1 && first)
|
|
2828
|
-
return first;
|
|
2829
|
-
throw new CliError(matches2.length === 0 ? "not_found" : "validation_error", matches2.length === 0 ? `no account in the store has seen person:${uid}` : `person:${uid} was seen by ${accounts.length} accounts; give one with --source: ${accounts.join(", ")}`);
|
|
2830
|
-
}, "anchorOf");
|
|
2831
|
-
var memoContext = /* @__PURE__ */ __name(async (store, reference2, { limit = 20, source } = {}) => {
|
|
3062
|
+
var contextAccountsOf = /* @__PURE__ */ __name(async (store, env, person, source) => {
|
|
3063
|
+
const provider = person.startsWith("person:") ? void 0 : person.split(":")[0];
|
|
3064
|
+
const keys = (await accountsOf(store, env, source)).filter((key) => provider === void 0 || key.provider === provider);
|
|
3065
|
+
if (keys.length === 0)
|
|
3066
|
+
throw new CliError("validation_error", `${source} is not an account of ${person}'s messenger`, { param: "source" });
|
|
3067
|
+
return keys;
|
|
3068
|
+
}, "contextAccountsOf");
|
|
3069
|
+
var accountIn = /* @__PURE__ */ __name((keys) => keys?.length === 1 ? { account: keys[0].account } : {}, "accountIn");
|
|
3070
|
+
var memoContext = /* @__PURE__ */ __name(async (store, env, reference2, { limit = 20, sources, deniedKinds = [] } = {}) => {
|
|
2832
3071
|
const named5 = (await withOwner(store, reference2)).trim();
|
|
3072
|
+
const scope = await groupScopeOf(store, env);
|
|
2833
3073
|
if (named5.startsWith("person:")) {
|
|
2834
|
-
const
|
|
2835
|
-
|
|
3074
|
+
const accounts2 = sources === void 0 ? scope?.accounts : [...sources];
|
|
3075
|
+
const { events: events2, business: business2, coverage, ...messages2 } = await canonicalPersonContext(store, named5, {
|
|
3076
|
+
messages: limit,
|
|
3077
|
+
limit,
|
|
3078
|
+
deniedKinds,
|
|
3079
|
+
...accounts2 === void 0 ? {} : { accounts: accounts2 }
|
|
3080
|
+
});
|
|
3081
|
+
const same2 = /* @__PURE__ */ __name((one2) => (key) => key.provider === one2.provider && key.account === one2.account, "same");
|
|
3082
|
+
const read = accounts2 === void 0 ? await scopedAccounts(store, env) : (await store.accounts.accounts()).filter((one2) => accounts2.some(same2(one2)));
|
|
3083
|
+
const calendars2 = (await calendarAccounts(store)).filter((one2) => accounts2 === void 0 || accounts2.some(same2(one2)));
|
|
3084
|
+
return withNotesAndTasks(store, env, { messages: messages2, events: events2, business: business2, coverage }, { accounts: read, calendars: calendars2, deniedKinds, ...accounts2 === void 0 ? {} : { scope: accounts2 } }, limit);
|
|
2836
3085
|
}
|
|
2837
3086
|
const [, provider, who] = /^([a-z][a-z0-9-]*):(.+)$/.exec(reference2.trim()) ?? [];
|
|
2838
3087
|
if (provider === void 0 || who === void 0)
|
|
2839
3088
|
throw new CliError("validation_error", `"${reference2}" names no messenger \u2014 write it as <messenger>:<name or id>`, {
|
|
2840
3089
|
reason: "identity.no-messenger"
|
|
2841
3090
|
});
|
|
2842
|
-
const accounts = await store
|
|
2843
|
-
const
|
|
2844
|
-
const
|
|
2845
|
-
const calendars = await calendarAccounts(store);
|
|
3091
|
+
const accounts = await scopedAccounts(store, env);
|
|
3092
|
+
const own = sources?.filter((one2) => one2.provider === provider);
|
|
3093
|
+
const asked = own?.length === 1 ? own[0] : await selectAccount(store, env, { provider, ...accountIn(own) });
|
|
3094
|
+
const calendars = await inGroup(store, env, await calendarAccounts(store));
|
|
3095
|
+
const calendarIds = scope === void 0 ? void 0 : await Promise.all(calendars.map(async (key) => (await store.accounts.storedAccount(key)).id));
|
|
3096
|
+
const { events, ...messages } = await personContext(store, asked, who, {
|
|
3097
|
+
messages: limit,
|
|
3098
|
+
...calendarIds === void 0 ? {} : { calendarIds }
|
|
3099
|
+
});
|
|
3100
|
+
const business = scope === void 0 && deniedKinds.length === 0 ? await personBusiness(store, messages.person.uid, { limit }) : (await canonicalPersonContext(store, `person:${messages.person.uid}`, {
|
|
3101
|
+
...scope === void 0 ? {} : { accounts: scope.accounts },
|
|
3102
|
+
deniedKinds,
|
|
3103
|
+
limit,
|
|
3104
|
+
messages: 1
|
|
3105
|
+
})).business;
|
|
3106
|
+
return withNotesAndTasks(store, env, { messages, events, business }, { accounts, calendars, deniedKinds, ...scope === void 0 ? {} : { scope: scope.accounts } }, limit);
|
|
3107
|
+
}, "memoContext");
|
|
3108
|
+
var withNotesAndTasks = /* @__PURE__ */ __name(async (store, env, { messages, events, business, coverage }, { accounts, calendars, scope, deniedKinds = [] }, limit) => {
|
|
2846
3109
|
const person = `person:${messages.person.uid}`;
|
|
2847
3110
|
const linked2 = await notesAbout(store, { ref: person, person: messages.person }, limit);
|
|
2848
3111
|
const yourNotes = [];
|
|
@@ -2861,25 +3124,32 @@ var memoContext = /* @__PURE__ */ __name(async (store, reference2, { limit = 20,
|
|
|
2861
3124
|
source: "mail",
|
|
2862
3125
|
reason: "no mail address linked to them \u2014 tg <profile> contacts link <person> email:<address>"
|
|
2863
3126
|
});
|
|
2864
|
-
if (calendars.length === 0)
|
|
3127
|
+
if (calendars.length === 0 && coverage === void 0)
|
|
2865
3128
|
notRead.push({ source: "events", reason: "no calendar in the store \u2014 gcal <profile> sync" });
|
|
2866
3129
|
const tasks = await personTasks(store, messages.person, accounts, limit);
|
|
2867
3130
|
const incoming = await store.notes.links({ to: person });
|
|
2868
|
-
const relationships =
|
|
3131
|
+
const relationships = (await store.knowledge.listRelations({
|
|
3132
|
+
about: person,
|
|
3133
|
+
...scope === void 0 ? {} : { accounts: scope },
|
|
3134
|
+
...deniedKinds.length ? { deniedKinds: [...deniedKinds] } : {},
|
|
3135
|
+
limit: 500
|
|
3136
|
+
})).items.filter((one2) => isUsable(one2.standing));
|
|
2869
3137
|
const files = await reportedFiles(store, incoming, limit);
|
|
2870
3138
|
const { subject: _, name: __, ...notes2 } = linked2;
|
|
2871
3139
|
return {
|
|
2872
3140
|
messages,
|
|
2873
|
-
events: { ...events, accounts: calendars.map(({ provider
|
|
3141
|
+
events: { ...events, accounts: calendars.map(({ provider, account: account2 }) => `${provider}:${account2}`) },
|
|
2874
3142
|
notes: { ...notes2, about: notes2.about.filter((note) => note.source === "file") },
|
|
2875
3143
|
yourNotes,
|
|
2876
3144
|
notRead,
|
|
2877
3145
|
tasks,
|
|
2878
3146
|
relationships,
|
|
3147
|
+
business,
|
|
3148
|
+
...coverage === void 0 ? {} : { coverage },
|
|
2879
3149
|
files,
|
|
2880
3150
|
untrusted: UNTRUSTED_EVENT_FIELDS
|
|
2881
3151
|
};
|
|
2882
|
-
}, "
|
|
3152
|
+
}, "withNotesAndTasks");
|
|
2883
3153
|
var withOwnMailText = /* @__PURE__ */ __name((context) => {
|
|
2884
3154
|
const own = /* @__PURE__ */ __name((message) => message?.provider === "email" ? { ...message, text: mailOwnText(message.text) } : message, "own");
|
|
2885
3155
|
const { last, recent, mentions } = context.messages;
|
|
@@ -2900,7 +3170,18 @@ var one = /* @__PURE__ */ __name((message) => message === null ? "\u2014" : `${m
|
|
|
2900
3170
|
var eventLine = /* @__PURE__ */ __name((event2) => ` ${(event2.allDay ? event2.startsAt?.slice(0, 10) : event2.startsAt?.slice(0, 16).replace("T", " ")) ?? "\u2014"} ${(event2.title ?? "untitled").replace(/\s+/g, " ").slice(0, MAX_TEXT2)}${event2.location ? ` ${event2.location}` : ""} ${event2.ref}`, "eventLine");
|
|
2901
3171
|
var noteLine = /* @__PURE__ */ __name((note) => ` ${note.ref}${note.path ?? note.title ? ` ${note.path ?? note.title}` : ""}`, "noteLine");
|
|
2902
3172
|
var fileLine = /* @__PURE__ */ __name((file) => ` ${file.ref} ${file.role ?? ""} ${file.title ?? ""} ${file.modifiedAt?.slice(0, 16).replace("T", " ") ?? ""} ${file.url ?? ""}`, "fileLine");
|
|
2903
|
-
var
|
|
3173
|
+
var businessLines = /* @__PURE__ */ __name((business) => {
|
|
3174
|
+
const lines2 = [
|
|
3175
|
+
...sectionLines("Organizations", business.organizations),
|
|
3176
|
+
...sectionLines("Reports to", business.reportsTo),
|
|
3177
|
+
...sectionLines("Direct reports", business.directReports),
|
|
3178
|
+
...sectionLines("Deals and leads", business.deals),
|
|
3179
|
+
...sectionLines("Projects", business.projects),
|
|
3180
|
+
...business.categories.length ? [`Categories ${business.categories.join(", ")}`] : []
|
|
3181
|
+
];
|
|
3182
|
+
return lines2.length ? ["", "Business", ...lines2] : [];
|
|
3183
|
+
}, "businessLines");
|
|
3184
|
+
var contextText = /* @__PURE__ */ __name(({ messages, events, notes: notes2, notRead, tasks, yourNotes, files, proposals, business, coverage }) => {
|
|
2904
3185
|
const { person, last, recent, shared } = messages;
|
|
2905
3186
|
return [
|
|
2906
3187
|
`${person.name ?? person.uid} person:${person.uid}`,
|
|
@@ -2916,6 +3197,7 @@ var contextText = /* @__PURE__ */ __name(({ messages, events, notes: notes2, not
|
|
|
2916
3197
|
...recent.groups.length === 0 ? [] : ["", "Recent, in groups", ...recent.groups.map((m) => ` ${one(m)}`)],
|
|
2917
3198
|
...events.upcoming.length === 0 ? [] : ["", "Upcoming events", ...events.upcoming.map(eventLine)],
|
|
2918
3199
|
...events.recent.length === 0 ? [] : ["", "Recent events", ...events.recent.map(eventLine)],
|
|
3200
|
+
...businessLines(business),
|
|
2919
3201
|
"",
|
|
2920
3202
|
"",
|
|
2921
3203
|
...notes2.about.length === 0 ? ["Note about them none \u2014 memo notes links add <identity> <path>"] : ["Notes about them", ...notes2.about.map(noteLine)],
|
|
@@ -2925,6 +3207,8 @@ var contextText = /* @__PURE__ */ __name(({ messages, events, notes: notes2, not
|
|
|
2925
3207
|
...files.length === 0 ? [] : ["", "Files, as Google reports", ...files.map(fileLine)],
|
|
2926
3208
|
...messages.complete ? [] : ["", `Not read in full: ${messages.notRead.length} chats \u2014 messages sync <chat>`],
|
|
2927
3209
|
...notRead.map(({ source, reason }) => `Not read: ${source} \u2014 ${reason}`),
|
|
3210
|
+
...(coverage?.notRead ?? []).map(({ source, reason }) => `Not read: ${source} \u2014 ${reason}`),
|
|
3211
|
+
...coverage ? [`Read: ${coverage.accounts.join(", ") || "no account"}`] : [],
|
|
2928
3212
|
...tasks.items.length ? [
|
|
2929
3213
|
"",
|
|
2930
3214
|
"Open tasks",
|
|
@@ -2939,20 +3223,21 @@ var contextText = /* @__PURE__ */ __name(({ messages, events, notes: notes2, not
|
|
|
2939
3223
|
}, "contextText");
|
|
2940
3224
|
var contextCommand = /* @__PURE__ */ __name((program, streams, env) => {
|
|
2941
3225
|
const { print } = answers(program, streams, env);
|
|
2942
|
-
annotate(program.command("context"), { effects: LOCAL_READ }).description("messages, mail, notes and events about a person, each with a link to its source; `proposals` counts what waits for you about them, by kind (`complete: false` means at least), and `next` names the command that lists them").summary("messages, mail, notes and events about a person, each with a link to its source").argument("<person>", "<messenger>:<name or id>, e.g. telegram:Ana or email:ana@example.com, person:<id>, or person:me for you").option("--limit <n>", "most messages, notes and events of each kind", positive, 20).option("--json", "print JSON; --json=id,title keeps only those fields").option("--source <accounts>", "the
|
|
3226
|
+
annotate(program.command("context"), { effects: LOCAL_READ, output: { entity: "person_context_memo" } }).description("messages, mail, notes and events about a person, each with a link to its source, and `business`: their organizations, reporting lines, deals and projects, each relationship with its standing (`reported` is a CRM's word only). person:<id> reads every account; `coverage` names what was read and what was not. `proposals` counts what waits for you about them, by kind (`complete: false` means at least), and `next` names the command that lists them").summary("messages, mail, notes and events about a person, each with a link to its source").argument("<person>", "<messenger>:<name or id>, e.g. telegram:Ana or email:ana@example.com, person:<id>, or person:me for you").option("--limit <n>", "most messages, notes and events of each kind", positive, 20).option("--json", "print JSON; --json=id,title keeps only those fields").option("--source <accounts>", "the accounts to read: every one when left out, or the group's in a group run; for <messenger>:<name>, the one account of that messenger").option("--trimmed", "each email's own text, without quoted earlier mail or the signature \u2014 for an agent's reads").action(async (person, options, command) => {
|
|
2943
3227
|
const answer = await withStore(env, async (store) => {
|
|
2944
3228
|
await importNotesMap(store, env, await boundFolders(store, env, { strict: false }));
|
|
2945
|
-
const
|
|
2946
|
-
const found = await memoContext(store, person, {
|
|
3229
|
+
const sources = options.source === void 0 ? void 0 : await contextAccountsOf(store, env, person, options.source);
|
|
3230
|
+
const found = await memoContext(store, env, person, {
|
|
2947
3231
|
limit: options.limit,
|
|
2948
|
-
|
|
3232
|
+
deniedKinds: deniedCrmKinds(command, env),
|
|
3233
|
+
...sources === void 0 ? {} : { sources }
|
|
2949
3234
|
});
|
|
2950
3235
|
const { uid, identities } = found.messages.person;
|
|
2951
3236
|
const refs = [`person:${uid}`, ...identities.map(({ provider, id }) => `${provider}:${id}`)];
|
|
2952
|
-
return {
|
|
3237
|
+
return lockedCoverage(store, env, {
|
|
2953
3238
|
...options.trimmed ? withOwnMailText(found) : found,
|
|
2954
3239
|
proposals: { ...await waitingAbout(store, env, refs), next: { command: "review list" } }
|
|
2955
|
-
};
|
|
3240
|
+
});
|
|
2956
3241
|
});
|
|
2957
3242
|
print(options.json, itemAnswer(answer), contextText(answer));
|
|
2958
3243
|
});
|
|
@@ -3878,7 +4163,7 @@ var search = [
|
|
|
3878
4163
|
command: ["search", "all"],
|
|
3879
4164
|
field: "summary",
|
|
3880
4165
|
before: "search stored messages, notes, calendar events and selected meeting transcripts",
|
|
3881
|
-
after: "messages, mail, notes and
|
|
4166
|
+
after: "messages, mail, notes, events and deals ranked together",
|
|
3882
4167
|
reason: "Memo searches imported accounts, mail and native notes without a live messenger; its scope, ranking and output controls are explicit provider differences."
|
|
3883
4168
|
},
|
|
3884
4169
|
{
|
|
@@ -4348,7 +4633,8 @@ var search = [
|
|
|
4348
4633
|
];
|
|
4349
4634
|
|
|
4350
4635
|
// dist/contract-overrides/skill.js
|
|
4351
|
-
var REASON2 = "Memo installs its own stored-data instructions through its environment, prints the packaged
|
|
4636
|
+
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.";
|
|
4637
|
+
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
4638
|
var JSON_OPTION2 = { flags: "--json", description: "print JSON", takes_value: false, mandatory: false };
|
|
4353
4639
|
var SHOW_FOR = {
|
|
4354
4640
|
flags: "--for <agents>",
|
|
@@ -4368,15 +4654,9 @@ var INSTALL_FOR = {
|
|
|
4368
4654
|
var skill = [
|
|
4369
4655
|
{
|
|
4370
4656
|
command: ["skill", "show"],
|
|
4371
|
-
field: "
|
|
4372
|
-
before:
|
|
4373
|
-
|
|
4374
|
-
local: "read"
|
|
4375
|
-
},
|
|
4376
|
-
after: {
|
|
4377
|
-
remote: "none",
|
|
4378
|
-
local: "none"
|
|
4379
|
-
},
|
|
4657
|
+
field: "description",
|
|
4658
|
+
before: SHOW_DESCRIPTION,
|
|
4659
|
+
after: `${SHOW_DESCRIPTION}; morning-digest ends with your brief from \`memo digest brief\` when you wrote one`,
|
|
4380
4660
|
reason: REASON2
|
|
4381
4661
|
},
|
|
4382
4662
|
{
|
|
@@ -4434,12 +4714,122 @@ var skill = [
|
|
|
4434
4714
|
var SHELL_OVERRIDES = { search, doctor, skill, mcp, commands, notes, meetings };
|
|
4435
4715
|
|
|
4436
4716
|
// dist/digest/backfill.js
|
|
4437
|
-
import { existsSync as
|
|
4438
|
-
import { join as
|
|
4717
|
+
import { existsSync as existsSync7, readdirSync as readdirSync4 } from "node:fs";
|
|
4718
|
+
import { join as join7 } from "node:path";
|
|
4719
|
+
|
|
4720
|
+
// dist/digest/brief.js
|
|
4721
|
+
import { spawnSync } from "node:child_process";
|
|
4722
|
+
import { existsSync as existsSync3, mkdtempSync, readFileSync as readFileSync4, rmSync as rmSync2, writeFileSync as writeFileSync3 } from "node:fs";
|
|
4723
|
+
import { tmpdir } from "node:os";
|
|
4724
|
+
import { join as join3 } from "node:path";
|
|
4725
|
+
var BRIEF = { key: "digest/brief", channel: "text", language: "any" };
|
|
4726
|
+
var BRIEF_LIMIT = 4e3;
|
|
4727
|
+
var readBrief = /* @__PURE__ */ __name(async (env) => {
|
|
4728
|
+
if (!existsSync3(storePath(env)))
|
|
4729
|
+
return void 0;
|
|
4730
|
+
return withStore(env, async (store) => store.templates.get(BRIEF)?.body);
|
|
4731
|
+
}, "readBrief");
|
|
4732
|
+
var withBrief = /* @__PURE__ */ __name((skill2, brief) => brief === void 0 ? skill2 : `${skill2}
|
|
4733
|
+
|
|
4734
|
+
## The owner's brief
|
|
4735
|
+
|
|
4736
|
+
The owner wrote this himself: it adds to everything above, and where it contradicts a rule of this skill, the brief wins.
|
|
4737
|
+
|
|
4738
|
+
${brief.trim()}`, "withBrief");
|
|
4739
|
+
var systemEditor = /* @__PURE__ */ __name((path, env) => {
|
|
4740
|
+
const editor = env.VISUAL?.trim() || env.EDITOR?.trim();
|
|
4741
|
+
if (!editor)
|
|
4742
|
+
throw new CliError("validation_error", "set VISUAL or EDITOR, or pass the brief with --file", {
|
|
4743
|
+
reason: "brief.no-editor"
|
|
4744
|
+
});
|
|
4745
|
+
const [program = editor, ...args] = editor.split(/\s+/);
|
|
4746
|
+
const ran = spawnSync(program, [...args, path], { stdio: "inherit", env });
|
|
4747
|
+
if (ran.status !== 0)
|
|
4748
|
+
throw new CliError("validation_error", `the editor exited with ${ran.status ?? ran.signal}; nothing was saved`);
|
|
4749
|
+
}, "systemEditor");
|
|
4750
|
+
var refuseAgent = /* @__PURE__ */ __name((env) => {
|
|
4751
|
+
if (authorOf(env) !== "owner")
|
|
4752
|
+
throw new CliError("permission_error", "only the owner changes the digest brief, not an agent", {
|
|
4753
|
+
reason: "brief.owner-only"
|
|
4754
|
+
});
|
|
4755
|
+
}, "refuseAgent");
|
|
4756
|
+
var historyOf = /* @__PURE__ */ __name((store) => store.templates.history(BRIEF).map((entry) => ({
|
|
4757
|
+
saved_at: new Date(entry.savedAt).toISOString(),
|
|
4758
|
+
saved_by: entry.savedBy,
|
|
4759
|
+
replaced_at: new Date(entry.replacedAt).toISOString(),
|
|
4760
|
+
chars: entry.body.length
|
|
4761
|
+
})), "historyOf");
|
|
4762
|
+
var briefCommand = /* @__PURE__ */ __name((digest, print, env, editor = systemEditor) => {
|
|
4763
|
+
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`);
|
|
4764
|
+
digest.addCommand(brief);
|
|
4765
|
+
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) => {
|
|
4766
|
+
const item = existsSync3(storePath(env)) ? await withStore(env, async (store) => {
|
|
4767
|
+
const row = store.templates.get(BRIEF);
|
|
4768
|
+
return {
|
|
4769
|
+
body: row?.body ?? null,
|
|
4770
|
+
chars: row?.body.length ?? 0,
|
|
4771
|
+
limit: BRIEF_LIMIT,
|
|
4772
|
+
updated_at: row ? new Date(row.updatedAt).toISOString() : null,
|
|
4773
|
+
updated_by: row?.updatedBy ?? null,
|
|
4774
|
+
history: historyOf(store)
|
|
4775
|
+
};
|
|
4776
|
+
}) : { body: null, chars: 0, limit: BRIEF_LIMIT, updated_at: null, updated_by: null, history: [] };
|
|
4777
|
+
print(given2.json, itemAnswer(item), item.body ?? "No brief: the morning digest follows its skill alone. `memo digest brief edit` writes one.");
|
|
4778
|
+
});
|
|
4779
|
+
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) => {
|
|
4780
|
+
refuseAgent(env);
|
|
4781
|
+
const { current, previous } = await withStore(env, async (store) => ({
|
|
4782
|
+
current: store.templates.get(BRIEF)?.body,
|
|
4783
|
+
previous: store.templates.history(BRIEF, 1)[0]?.body
|
|
4784
|
+
}));
|
|
4785
|
+
let draft;
|
|
4786
|
+
let body;
|
|
4787
|
+
if (given2.undo) {
|
|
4788
|
+
if (previous === void 0)
|
|
4789
|
+
throw new CliError("validation_error", "the brief has no earlier body to put back", {
|
|
4790
|
+
reason: "brief.no-history"
|
|
4791
|
+
});
|
|
4792
|
+
body = previous;
|
|
4793
|
+
} else if (given2.file !== void 0) {
|
|
4794
|
+
body = readFileSync4(given2.file === "-" ? 0 : given2.file, "utf8");
|
|
4795
|
+
} else {
|
|
4796
|
+
draft = join3(mkdtempSync(join3(tmpdir(), "memo-brief-")), "brief.md");
|
|
4797
|
+
writeFileSync3(draft, current ?? "", { mode: 384 });
|
|
4798
|
+
editor(draft, env);
|
|
4799
|
+
body = readFileSync4(draft, "utf8");
|
|
4800
|
+
}
|
|
4801
|
+
const kept = draft ? `. Your text is in ${draft}; fix it and run again with --file ${draft}` : "";
|
|
4802
|
+
body = body.trim();
|
|
4803
|
+
if (!body)
|
|
4804
|
+
throw new CliError("validation_error", `the brief is empty; memo digest brief reset removes it${kept}`, {
|
|
4805
|
+
reason: "brief.empty"
|
|
4806
|
+
});
|
|
4807
|
+
if (body.length > BRIEF_LIMIT)
|
|
4808
|
+
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 });
|
|
4809
|
+
if (draft)
|
|
4810
|
+
rmSync2(join3(draft, ".."), { recursive: true, force: true });
|
|
4811
|
+
if (body === current) {
|
|
4812
|
+
print(given2.json, itemAnswer({ changed: false, chars: body.length }), "The brief is unchanged; nothing saved.");
|
|
4813
|
+
return;
|
|
4814
|
+
}
|
|
4815
|
+
const saved = await withStore(env, async (store) => store.templates.save(BRIEF, body, "memo"));
|
|
4816
|
+
print(given2.json, itemAnswer({
|
|
4817
|
+
changed: true,
|
|
4818
|
+
chars: body.length,
|
|
4819
|
+
limit: BRIEF_LIMIT,
|
|
4820
|
+
updated_at: new Date(saved.updatedAt).toISOString()
|
|
4821
|
+
}), `Saved the brief (${body.length} of ${BRIEF_LIMIT} characters); the next morning digest follows it.`);
|
|
4822
|
+
});
|
|
4823
|
+
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) => {
|
|
4824
|
+
refuseAgent(env);
|
|
4825
|
+
const changed = await withStore(env, async (store) => store.templates.reset(BRIEF));
|
|
4826
|
+
print(given2.json, itemAnswer({ changed }), changed ? "Removed the brief; memo digest brief edit --undo brings it back." : "There was no brief.");
|
|
4827
|
+
});
|
|
4828
|
+
}, "briefCommand");
|
|
4439
4829
|
|
|
4440
4830
|
// dist/digest/tasks.js
|
|
4441
|
-
import { existsSync as
|
|
4442
|
-
import { join as
|
|
4831
|
+
import { existsSync as existsSync6, readdirSync as readdirSync3 } from "node:fs";
|
|
4832
|
+
import { join as join6 } from "node:path";
|
|
4443
4833
|
|
|
4444
4834
|
// dist/tasks/list.js
|
|
4445
4835
|
import { createHash as createHash2 } from "node:crypto";
|
|
@@ -4520,17 +4910,17 @@ var accountTasks = /* @__PURE__ */ __name(async (store, keys, options) => {
|
|
|
4520
4910
|
});
|
|
4521
4911
|
}, "accountTasks");
|
|
4522
4912
|
var accountTerms = /* @__PURE__ */ __name((query) => {
|
|
4523
|
-
const
|
|
4524
|
-
const other =
|
|
4913
|
+
const leaves3 = query ? walkQuery(query.root) : [];
|
|
4914
|
+
const other = leaves3.find(({ field: field2 }) => !ACCOUNT_FIELDS.has(field2));
|
|
4525
4915
|
if (other)
|
|
4526
4916
|
throw new CliError("validation_error", `${other.field}: narrows project tasks: add project:<key>, or project:* for every project`);
|
|
4527
|
-
const states = new Set(
|
|
4917
|
+
const states = new Set(leaves3.filter(({ field: field2 }) => field2 === "state").map(({ value }) => value.toLowerCase()));
|
|
4528
4918
|
if ((states.has("todo") || states.has("in_progress")) && !states.has("open"))
|
|
4529
4919
|
throw new CliError("validation_error", "todo and in_progress are steps of a project task: add project:");
|
|
4530
4920
|
const closed = [...states].filter(isClosedState);
|
|
4531
4921
|
if (closed.length > 1 || closed.length === 1 && states.size > 1)
|
|
4532
4922
|
throw new CliError("validation_error", "an account's tasks are listed in one state: state:open, done or dismissed");
|
|
4533
|
-
const sources =
|
|
4923
|
+
const sources = leaves3.filter(({ field: field2 }) => field2 === "source").map(({ value }) => value);
|
|
4534
4924
|
if (sources.length > 1)
|
|
4535
4925
|
throw new CliError("validation_error", "source: only once here");
|
|
4536
4926
|
return { state: closed[0] ?? "open", source: sources[0] };
|
|
@@ -4586,9 +4976,9 @@ var listTasks = /* @__PURE__ */ __name(async (store, words, options, accounts) =
|
|
|
4586
4976
|
}
|
|
4587
4977
|
const typed = typedQuery(words);
|
|
4588
4978
|
const query = listQuery(typed, TASKS_LIST_QUERY, "tasks list", { defaultField: "text" });
|
|
4589
|
-
const
|
|
4590
|
-
if (
|
|
4591
|
-
if (
|
|
4979
|
+
const leaves3 = query ? walkQuery(query.root) : [];
|
|
4980
|
+
if (leaves3.some(({ field: field2 }) => field2 === "project")) {
|
|
4981
|
+
if (leaves3.some(({ field: field2 }) => field2 === "source"))
|
|
4592
4982
|
throw new CliError("validation_error", "source: narrows an account's tasks, not a project's");
|
|
4593
4983
|
return projectTasks(store, typed, await resolveProjects(store, query), options);
|
|
4594
4984
|
}
|
|
@@ -4609,13 +4999,13 @@ var countTasks = /* @__PURE__ */ __name(async (store, words) => {
|
|
|
4609
4999
|
}, "countTasks");
|
|
4610
5000
|
|
|
4611
5001
|
// dist/digest/sync-health.js
|
|
4612
|
-
import { existsSync as
|
|
4613
|
-
import { join as
|
|
5002
|
+
import { existsSync as existsSync5, readdirSync as readdirSync2, readFileSync as readFileSync6 } from "node:fs";
|
|
5003
|
+
import { join as join5 } from "node:path";
|
|
4614
5004
|
|
|
4615
5005
|
// dist/knowledge/messenger-sync.js
|
|
4616
5006
|
import { spawn } from "node:child_process";
|
|
4617
|
-
import { existsSync as
|
|
4618
|
-
import { delimiter, join as
|
|
5007
|
+
import { existsSync as existsSync4, readdirSync, readFileSync as readFileSync5, realpathSync, statSync as statSync2 } from "node:fs";
|
|
5008
|
+
import { delimiter, join as join4 } from "node:path";
|
|
4619
5009
|
var STATE = {
|
|
4620
5010
|
tg: { appName: "tg-cli", envPrefix: "TG" },
|
|
4621
5011
|
max: { appName: "max-cli", envPrefix: "MAX" },
|
|
@@ -4635,10 +5025,10 @@ var syncProfileOf = /* @__PURE__ */ __name((value, previous = {}) => {
|
|
|
4635
5025
|
throw new InvalidArgumentError(`one profile per tool; ${tool} is already ${previous[tool]}`);
|
|
4636
5026
|
return { ...previous, [tool]: profile };
|
|
4637
5027
|
}, "syncProfileOf");
|
|
4638
|
-
var accountsDir = /* @__PURE__ */ __name((tool, env) =>
|
|
5028
|
+
var accountsDir = /* @__PURE__ */ __name((tool, env) => join4(resolvePaths({ appName: tool.appName, prefix: tool.envPrefix, env }).state, "accounts"), "accountsDir");
|
|
4639
5029
|
var signedInAccount = /* @__PURE__ */ __name((tool, profile, env) => {
|
|
4640
5030
|
try {
|
|
4641
|
-
return JSON.parse(
|
|
5031
|
+
return JSON.parse(readFileSync5(join4(accountsDir(tool, env), `${profile}.json`), "utf8"))?.account;
|
|
4642
5032
|
} catch {
|
|
4643
5033
|
return void 0;
|
|
4644
5034
|
}
|
|
@@ -4648,7 +5038,7 @@ var profileFor = /* @__PURE__ */ __name((provider, account2, env, chosen = {}) =
|
|
|
4648
5038
|
if (!tool)
|
|
4649
5039
|
return void 0;
|
|
4650
5040
|
const dir = accountsDir(tool, env);
|
|
4651
|
-
const profiles =
|
|
5041
|
+
const profiles = existsSync4(dir) ? readdirSync(dir).filter((name2) => name2.endsWith(".json")).map((name2) => name2.slice(0, -".json".length)).sort() : [];
|
|
4652
5042
|
const accountOf = /* @__PURE__ */ __name((profile) => signedInAccount(tool, profile, env), "accountOf");
|
|
4653
5043
|
const all = profiles.join(", ") || "none";
|
|
4654
5044
|
const pick = chosen[tool.tool];
|
|
@@ -4668,7 +5058,7 @@ var profileFor = /* @__PURE__ */ __name((provider, account2, env, chosen = {}) =
|
|
|
4668
5058
|
};
|
|
4669
5059
|
return { why: `no ${tool.tool} profile here is signed in to account ${account2}; profiles: ${all}`, profiles: [] };
|
|
4670
5060
|
}, "profileFor");
|
|
4671
|
-
var onPath = /* @__PURE__ */ __name((name2, env) => (env.PATH ?? "").split(delimiter).filter(Boolean).map((dir) =>
|
|
5061
|
+
var onPath = /* @__PURE__ */ __name((name2, env) => (env.PATH ?? "").split(delimiter).filter(Boolean).map((dir) => join4(dir, name2)).find((path) => {
|
|
4672
5062
|
try {
|
|
4673
5063
|
return statSync2(path).isFile();
|
|
4674
5064
|
} catch {
|
|
@@ -4678,13 +5068,13 @@ var onPath = /* @__PURE__ */ __name((name2, env) => (env.PATH ?? "").split(delim
|
|
|
4678
5068
|
var runChild = /* @__PURE__ */ __name((command, args, { env, signal, onStderr }) => new Promise((resolve6, reject) => {
|
|
4679
5069
|
const child = spawn(command, args, { env, stdio: ["ignore", "pipe", "pipe"] });
|
|
4680
5070
|
let stdout = "";
|
|
4681
|
-
let
|
|
5071
|
+
let pending = "";
|
|
4682
5072
|
child.stdout.setEncoding("utf8").on("data", (chunk) => {
|
|
4683
5073
|
stdout += chunk;
|
|
4684
5074
|
});
|
|
4685
5075
|
child.stderr.setEncoding("utf8").on("data", (chunk) => {
|
|
4686
|
-
const lines2 = (
|
|
4687
|
-
|
|
5076
|
+
const lines2 = (pending + chunk).split("\n");
|
|
5077
|
+
pending = lines2.pop() ?? "";
|
|
4688
5078
|
for (const line3 of lines2)
|
|
4689
5079
|
if (line3)
|
|
4690
5080
|
onStderr?.(line3);
|
|
@@ -4699,8 +5089,8 @@ var runChild = /* @__PURE__ */ __name((command, args, { env, signal, onStderr })
|
|
|
4699
5089
|
child.on("close", (code) => {
|
|
4700
5090
|
clearTimeout(hard);
|
|
4701
5091
|
signal?.removeEventListener("abort", stop);
|
|
4702
|
-
if (
|
|
4703
|
-
onStderr?.(
|
|
5092
|
+
if (pending)
|
|
5093
|
+
onStderr?.(pending);
|
|
4704
5094
|
resolve6({ code, stdout });
|
|
4705
5095
|
});
|
|
4706
5096
|
}), "runChild");
|
|
@@ -4724,7 +5114,7 @@ var binaryOf = /* @__PURE__ */ __name(async (provider, env, run) => {
|
|
|
4724
5114
|
const real = realpathSync(short);
|
|
4725
5115
|
if (real.includes(`/${mark}/`))
|
|
4726
5116
|
return short;
|
|
4727
|
-
return statSync2(real).size < 65536 &&
|
|
5117
|
+
return statSync2(real).size < 65536 && readFileSync5(real, "utf8").includes(mark) ? short : void 0;
|
|
4728
5118
|
}, "binaryOf");
|
|
4729
5119
|
var answerOf = /* @__PURE__ */ __name((stdout) => {
|
|
4730
5120
|
try {
|
|
@@ -4832,13 +5222,13 @@ var SOURCE_WORDS = {
|
|
|
4832
5222
|
var toolOf = /* @__PURE__ */ __name((provider) => provider === "email" ? MAIL2 : messengerToolOf(provider), "toolOf");
|
|
4833
5223
|
var stateDirs = /* @__PURE__ */ __name((tool, env) => resolvePaths({ appName: tool.appName, prefix: tool.envPrefix, env }), "stateDirs");
|
|
4834
5224
|
var schedulesOf = /* @__PURE__ */ __name((state) => {
|
|
4835
|
-
const dir =
|
|
4836
|
-
if (!
|
|
5225
|
+
const dir = join5(state, "schedules");
|
|
5226
|
+
if (!existsSync5(dir))
|
|
4837
5227
|
return [];
|
|
4838
5228
|
const last = new Map(scheduledRuns(state).map((one2) => [one2.job, one2.last]));
|
|
4839
5229
|
return readdirSync2(dir).flatMap((name2) => {
|
|
4840
5230
|
try {
|
|
4841
|
-
const schedule = JSON.parse(
|
|
5231
|
+
const schedule = JSON.parse(readFileSync6(join5(dir, name2, "schedule.json"), "utf8"));
|
|
4842
5232
|
return [
|
|
4843
5233
|
{
|
|
4844
5234
|
name: String(schedule.name),
|
|
@@ -4853,15 +5243,15 @@ var schedulesOf = /* @__PURE__ */ __name((state) => {
|
|
|
4853
5243
|
}
|
|
4854
5244
|
});
|
|
4855
5245
|
}, "schedulesOf");
|
|
4856
|
-
var signedIn = /* @__PURE__ */ __name((dir) =>
|
|
5246
|
+
var signedIn = /* @__PURE__ */ __name((dir) => existsSync5(dir) ? readdirSync2(dir).filter((name2) => name2.endsWith(".json")).map((name2) => name2.slice(0, -".json".length)) : [], "signedIn");
|
|
4857
5247
|
var profilesOf = /* @__PURE__ */ __name((provider, tool, env) => {
|
|
4858
5248
|
if (provider !== "email")
|
|
4859
|
-
return new Map(signedIn(
|
|
5249
|
+
return new Map(signedIn(join5(stateDirs(tool, env).state, "accounts")).map((profile) => [
|
|
4860
5250
|
profile,
|
|
4861
5251
|
signedInAccount(tool, profile, env)
|
|
4862
5252
|
]));
|
|
4863
5253
|
try {
|
|
4864
|
-
const config = JSON.parse(
|
|
5254
|
+
const config = JSON.parse(readFileSync6(configFilePath(stateDirs(MAIL2, env).config), "utf8"));
|
|
4865
5255
|
return new Map(Object.entries(config?.profiles ?? {}).map(([profile, one2]) => [
|
|
4866
5256
|
profile,
|
|
4867
5257
|
one2?.address
|
|
@@ -4910,7 +5300,7 @@ var QUIET_AFTER = 3 * DAY3;
|
|
|
4910
5300
|
var QUIET_GAPS = 3;
|
|
4911
5301
|
var hours = /* @__PURE__ */ __name((from, now) => Math.max(0, Math.floor((now - from) / HOUR)), "hours");
|
|
4912
5302
|
var healthOf = /* @__PURE__ */ __name((sync, activity, now) => {
|
|
4913
|
-
const recent = /* @__PURE__ */ __name((
|
|
5303
|
+
const recent = /* @__PURE__ */ __name((at2) => at2 !== null && at2 >= now - DAY3, "recent");
|
|
4914
5304
|
if (recent(activity.storedAt) || sync.runs.some((run) => run.exitCode === 0 && recent(Date.parse(run.at))))
|
|
4915
5305
|
return void 0;
|
|
4916
5306
|
if (!sync.serving && sync.runs.length > 0 && sync.runs.every((run) => run.exitCode !== 0)) {
|
|
@@ -4951,12 +5341,12 @@ var runTime = /* @__PURE__ */ __name((file) => {
|
|
|
4951
5341
|
}, "runTime");
|
|
4952
5342
|
var digestReportTimes = /* @__PURE__ */ __name((env) => {
|
|
4953
5343
|
const { state, schedule } = digestSchedule(env);
|
|
4954
|
-
const runs = schedule ?
|
|
4955
|
-
if (!runs || !
|
|
5344
|
+
const runs = schedule ? join6(state, "schedules", schedule.name, "runs") : void 0;
|
|
5345
|
+
if (!runs || !existsSync6(runs))
|
|
4956
5346
|
return [];
|
|
4957
|
-
return readdirSync3(runs).filter((file) => file.endsWith(".report.json")).map(runTime).filter((
|
|
5347
|
+
return readdirSync3(runs).filter((file) => file.endsWith(".report.json")).map(runTime).filter((at2) => !Number.isNaN(at2)).sort((a, b) => a - b);
|
|
4958
5348
|
}, "digestReportTimes");
|
|
4959
|
-
var digestRunBefore = /* @__PURE__ */ __name((env, until) => new Date(digestReportTimes(env).findLast((
|
|
5349
|
+
var digestRunBefore = /* @__PURE__ */ __name((env, until) => new Date(digestReportTimes(env).findLast((at2) => at2 < until) ?? until - DAY4).toISOString(), "digestRunBefore");
|
|
4960
5350
|
var previousDigestAt = /* @__PURE__ */ __name((env, now) => {
|
|
4961
5351
|
const last = digestSchedule(env).schedule?.last;
|
|
4962
5352
|
if (!last)
|
|
@@ -5053,8 +5443,8 @@ var gatherTasks = /* @__PURE__ */ __name(async (store, keys, { now, newSince, un
|
|
|
5053
5443
|
// dist/digest/backfill.js
|
|
5054
5444
|
var DAY5 = 864e5;
|
|
5055
5445
|
var DATE = /^(\d{4})-(\d{2})-(\d{2})$/;
|
|
5056
|
-
var localDate = /* @__PURE__ */ __name((
|
|
5057
|
-
const day2 = new Date(
|
|
5446
|
+
var localDate = /* @__PURE__ */ __name((at2) => {
|
|
5447
|
+
const day2 = new Date(at2);
|
|
5058
5448
|
return `${day2.getFullYear()}-${String(day2.getMonth() + 1).padStart(2, "0")}-${String(day2.getDate()).padStart(2, "0")}`;
|
|
5059
5449
|
}, "localDate");
|
|
5060
5450
|
var dateOf = /* @__PURE__ */ __name((value, flag) => {
|
|
@@ -5074,14 +5464,15 @@ var daysOf = /* @__PURE__ */ __name((from, to, time) => {
|
|
|
5074
5464
|
});
|
|
5075
5465
|
return days2;
|
|
5076
5466
|
}, "daysOf");
|
|
5077
|
-
var inputOf = /* @__PURE__ */ __name((date,
|
|
5078
|
-
window: --since-time ${new Date(
|
|
5467
|
+
var inputOf = /* @__PURE__ */ __name((date, at2) => `backfill: ${date}
|
|
5468
|
+
window: --since-time ${new Date(at2 - DAY5).toISOString()} --before-time ${new Date(at2).toISOString()}
|
|
5079
5469
|
`, "inputOf");
|
|
5080
5470
|
var usd = /* @__PURE__ */ __name((value) => `$${value.toFixed(2)}`, "usd");
|
|
5081
5471
|
var cents = /* @__PURE__ */ __name((value) => Math.round(value * 100) / 100, "cents");
|
|
5082
5472
|
var digestCommand = /* @__PURE__ */ __name((program, streams, env) => {
|
|
5083
5473
|
const { print } = answers(program, streams, env);
|
|
5084
|
-
const digest = program.command("digest").description("the morning digest
|
|
5474
|
+
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");
|
|
5475
|
+
briefCommand(digest, print, env);
|
|
5085
5476
|
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
5477
|
const from = dateOf(given2.from, "--from");
|
|
5087
5478
|
const to = dateOf(given2.to, "--to");
|
|
@@ -5102,8 +5493,8 @@ var digestCommand = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
5102
5493
|
throw new CliError("validation_error", `the ${given2.to} digest's time has not come yet; --to an earlier day`, {
|
|
5103
5494
|
param: "--to"
|
|
5104
5495
|
});
|
|
5105
|
-
const runs =
|
|
5106
|
-
const done = new Set((
|
|
5496
|
+
const runs = join7(file, "..", "runs");
|
|
5497
|
+
const done = new Set((existsSync7(runs) ? readdirSync4(runs) : []).filter((name2) => name2.endsWith(".report.json")).map((name2) => localDate(runTime(name2))));
|
|
5107
5498
|
const days2 = all.filter((day2) => !done.has(day2.date));
|
|
5108
5499
|
const skipped = all.filter((day2) => done.has(day2.date)).map((day2) => day2.date);
|
|
5109
5500
|
const lastCost = schedule.last?.costUsd;
|
|
@@ -5208,6 +5599,7 @@ var SECTIONS = [
|
|
|
5208
5599
|
["deals", "organise"],
|
|
5209
5600
|
["leads", "organise"],
|
|
5210
5601
|
["pipelines", "organise"],
|
|
5602
|
+
["stages", "organise"],
|
|
5211
5603
|
["payments", "organise"],
|
|
5212
5604
|
["products", "organise"],
|
|
5213
5605
|
["contracts", "organise"],
|
|
@@ -5224,6 +5616,7 @@ var SECTIONS = [
|
|
|
5224
5616
|
["jobs", "automate"],
|
|
5225
5617
|
["digest", "automate"],
|
|
5226
5618
|
["folders", "setup"],
|
|
5619
|
+
["groups", "setup"],
|
|
5227
5620
|
["config", "setup"]
|
|
5228
5621
|
];
|
|
5229
5622
|
var placeInSections = /* @__PURE__ */ __name((program) => {
|
|
@@ -5248,9 +5641,9 @@ var commandsCommand = /* @__PURE__ */ __name((program, streams) => {
|
|
|
5248
5641
|
}, "commandsCommand");
|
|
5249
5642
|
|
|
5250
5643
|
// dist/doctor/command.js
|
|
5251
|
-
import { existsSync as
|
|
5644
|
+
import { existsSync as existsSync8, readdirSync as readdirSync5, readFileSync as readFileSync7 } from "node:fs";
|
|
5252
5645
|
import { homedir } from "node:os";
|
|
5253
|
-
import { dirname, join as
|
|
5646
|
+
import { dirname, join as join8 } from "node:path";
|
|
5254
5647
|
var retiredMailAddresses = /* @__PURE__ */ __name((mail) => {
|
|
5255
5648
|
const accounts = mail?.accounts;
|
|
5256
5649
|
if (!Array.isArray(accounts))
|
|
@@ -5276,7 +5669,7 @@ var diagnose = /* @__PURE__ */ __name(async (env, program, { deep = false } = {}
|
|
|
5276
5669
|
problems.push({ what: "the store is from a newer version than this memo", fix: "memo upgrade" });
|
|
5277
5670
|
const folders = noteFolders(config.notes).map(({ path, id }) => ({
|
|
5278
5671
|
path,
|
|
5279
|
-
exists:
|
|
5672
|
+
exists: existsSync8(path),
|
|
5280
5673
|
bound: id !== null
|
|
5281
5674
|
}));
|
|
5282
5675
|
for (const folder of folders) {
|
|
@@ -5307,13 +5700,13 @@ var diagnose = /* @__PURE__ */ __name(async (env, program, { deep = false } = {}
|
|
|
5307
5700
|
fix: `fix text_models in ${textModelsFile(env)}, or remove it to go back to ${DEFAULT_TEXT_MODEL}`
|
|
5308
5701
|
});
|
|
5309
5702
|
}
|
|
5310
|
-
const modelDir =
|
|
5311
|
-
const model =
|
|
5703
|
+
const modelDir = join8(sharedModelsDirectory("text", env), textModel);
|
|
5704
|
+
const model = existsSync8(modelDir) && readdirSync5(modelDir).length > 0;
|
|
5312
5705
|
const state = autoState(config);
|
|
5313
|
-
const unitFile =
|
|
5314
|
-
const unit =
|
|
5706
|
+
const unitFile = join8(env.XDG_CONFIG_HOME ?? join8(env.HOME ?? homedir(), ".config"), "systemd", "user", "memo-import.service");
|
|
5707
|
+
const unit = existsSync8(unitFile) ? readFileSync7(unitFile, "utf8") : void 0;
|
|
5315
5708
|
const runs = unit ? unitPaths(unit) : [];
|
|
5316
|
-
const missing = runs.filter((path) => !
|
|
5709
|
+
const missing = runs.filter((path) => !existsSync8(path));
|
|
5317
5710
|
const last = lastAutoRun(env);
|
|
5318
5711
|
const failing = last && last.exitCode !== 0 ? { since: last.failingSince ?? last.at, runs: last.failures ?? 1, reason: last.reason ?? null } : null;
|
|
5319
5712
|
if (state.enabled && !unit)
|
|
@@ -5324,7 +5717,7 @@ var diagnose = /* @__PURE__ */ __name(async (env, program, { deep = false } = {}
|
|
|
5324
5717
|
problems.push({ what: `the timer has failed ${failing.runs} runs since ${failing.since}`, fix: "memo jobs status" });
|
|
5325
5718
|
const skills = SKILL_TARGETS.map((target) => {
|
|
5326
5719
|
const path = skillPath(target, APP.appName, env);
|
|
5327
|
-
const version =
|
|
5720
|
+
const version = existsSync8(path) ? skillVersion(readFileSync7(path, "utf8")) ?? "unknown" : null;
|
|
5328
5721
|
return { target, path, version };
|
|
5329
5722
|
});
|
|
5330
5723
|
if (skills.some(({ version }) => version !== null && version !== VERSION))
|
|
@@ -5345,7 +5738,7 @@ var diagnose = /* @__PURE__ */ __name(async (env, program, { deep = false } = {}
|
|
|
5345
5738
|
};
|
|
5346
5739
|
}, "diagnose");
|
|
5347
5740
|
var yes = /* @__PURE__ */ __name((value) => value ? "yes" : "no", "yes");
|
|
5348
|
-
var fileLines = /* @__PURE__ */ __name((d, fixes) => d.files.checked ? d.files.problems.map(({ path, mode, want },
|
|
5741
|
+
var fileLines = /* @__PURE__ */ __name((d, fixes) => d.files.checked ? d.files.problems.map(({ path, mode, want }, at2) => `! ${path} is ${mode}, so others can read it; it should be ${want} \u2014 ${fixes[at2]}`) : [], "fileLines");
|
|
5349
5742
|
var onlineLine = /* @__PURE__ */ __name(({ version }) => version.latest === null ? "online npm could not be reached" : version.newer ? `online memo ${version.latest} is published (this is ${version.current}) \u2014 memo upgrade` : `online memo ${version.current} is the newest published`, "onlineLine");
|
|
5350
5743
|
var doctorText = /* @__PURE__ */ __name((d, fixes = [], online) => [
|
|
5351
5744
|
`memo ${d.memo.version} on Node ${d.memo.node}, installed by ${d.memo.installed_by}`,
|
|
@@ -5403,7 +5796,7 @@ var doctorCommand = /* @__PURE__ */ __name((...args) => {
|
|
|
5403
5796
|
}, SHELL_OVERRIDES.doctor);
|
|
5404
5797
|
}, "doctorCommand");
|
|
5405
5798
|
|
|
5406
|
-
// node_modules/.pnpm/@wirecat+cli-core@0.
|
|
5799
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.619.0_@wirecat+cli-base@0.91.0_commander@15.0.0_esbuild@0.28.2_type_25b690dd810be59ade44e4d26e61c9f5/node_modules/@wirecat/cli-core/dist/calendar/sync.js
|
|
5407
5800
|
var DAY6 = 864e5;
|
|
5408
5801
|
var SLOTS_EVERY = 7 * DAY6;
|
|
5409
5802
|
var isWindow = /* @__PURE__ */ __name((value) => typeof value?.from === "number" && typeof value.to === "number", "isWindow");
|
|
@@ -5483,10 +5876,10 @@ var calendarStatus = /* @__PURE__ */ __name(async (store, accountId, { profile,
|
|
|
5483
5876
|
return { items, page: 1, limit: Math.max(1, items.length), hasMore: false };
|
|
5484
5877
|
}, "calendarStatus");
|
|
5485
5878
|
|
|
5486
|
-
// node_modules/.pnpm/@wirecat+cli-core@0.
|
|
5879
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.619.0_@wirecat+cli-base@0.91.0_commander@15.0.0_esbuild@0.28.2_type_25b690dd810be59ade44e4d26e61c9f5/node_modules/@wirecat/cli-core/dist/calendar/feeds.js
|
|
5487
5880
|
var FEED_LIMITS = { maxBytes: 10 * 1024 * 1024, timeoutMs: 3e4, redirects: 5 };
|
|
5488
5881
|
|
|
5489
|
-
// node_modules/.pnpm/@wirecat+cli-core@0.
|
|
5882
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.619.0_@wirecat+cli-base@0.91.0_commander@15.0.0_esbuild@0.28.2_type_25b690dd810be59ade44e4d26e61c9f5/node_modules/@wirecat/cli-core/dist/calendar/reads.js
|
|
5490
5883
|
var LIST = "events list";
|
|
5491
5884
|
var EVENT_TYPES = [
|
|
5492
5885
|
"default",
|
|
@@ -5563,7 +5956,7 @@ var accountsMeta = /* @__PURE__ */ __name(async (store, accounts, skipped, now)
|
|
|
5563
5956
|
};
|
|
5564
5957
|
}, "accountsMeta");
|
|
5565
5958
|
|
|
5566
|
-
// node_modules/.pnpm/@wirecat+cli-core@0.
|
|
5959
|
+
// node_modules/.pnpm/@wirecat+cli-core@0.619.0_@wirecat+cli-base@0.91.0_commander@15.0.0_esbuild@0.28.2_type_25b690dd810be59ade44e4d26e61c9f5/node_modules/@wirecat/cli-core/dist/calendar/writer.js
|
|
5567
5960
|
var EVENTS_NOTIFY_KEY = "events.notify";
|
|
5568
5961
|
var EVENTS_DELETE_SERIES_KEY = "events.delete.series";
|
|
5569
5962
|
var EVENTS_REMIND_HOOK_KEY = "events.remind.hook";
|
|
@@ -5644,7 +6037,7 @@ var calendarOf = /* @__PURE__ */ __name((accounts, value) => {
|
|
|
5644
6037
|
throw new CliError("not_found", `calendar:${value} names no calendar in the accounts read`);
|
|
5645
6038
|
throw new CliError("validation_error", `calendar:${value} names ${found.length} calendars; give one by its id: ` + found.map(({ account: account2, calendar }) => `calendar:${calendar.id} (${accountName(account2.key)})`).join(", "));
|
|
5646
6039
|
}, "calendarOf");
|
|
5647
|
-
var localDate2 = /* @__PURE__ */ __name((
|
|
6040
|
+
var localDate2 = /* @__PURE__ */ __name((at2, zone) => new Intl.DateTimeFormat("en-CA", { timeZone: zone, year: "numeric", month: "2-digit", day: "2-digit" }).format(at2), "localDate");
|
|
5648
6041
|
var plusDays = /* @__PURE__ */ __name((date, days2) => {
|
|
5649
6042
|
const [year, month, day2] = date.split("-").map(Number);
|
|
5650
6043
|
return new Date(Date.UTC(year, month - 1, day2 + days2)).toISOString().slice(0, 10);
|
|
@@ -5778,7 +6171,11 @@ ${plainText(body, command)}`);
|
|
|
5778
6171
|
|
|
5779
6172
|
// dist/examples.js
|
|
5780
6173
|
var EXAMPLES = {
|
|
5781
|
-
context: [
|
|
6174
|
+
context: [
|
|
6175
|
+
"memo context telegram:'Kai Sample'",
|
|
6176
|
+
"memo context person:7 --json",
|
|
6177
|
+
"memo context email:kai@example.com --limit 5 --json"
|
|
6178
|
+
],
|
|
5782
6179
|
show: [
|
|
5783
6180
|
"memo show chat:max/500/-1001 document:413",
|
|
5784
6181
|
"memo show note:12 msg:telegram/1/77/42 --json",
|
|
@@ -5809,6 +6206,10 @@ var EXAMPLES = {
|
|
|
5809
6206
|
"folders update": ["memo folders update 1 ~/notes"],
|
|
5810
6207
|
"folders remove": ["memo folders remove 1", "memo folders remove 1 --allow-delete --yes"],
|
|
5811
6208
|
"folders list": ["memo folders list --json"],
|
|
6209
|
+
"groups list": ["memo groups list", "memo groups list --json"],
|
|
6210
|
+
"groups add": ["memo groups add work bitrix24:acme", "memo groups add personal telegram:102"],
|
|
6211
|
+
"groups remove": ["memo groups remove work telegram:102"],
|
|
6212
|
+
"groups move": ["memo groups move telegram:102 personal work"],
|
|
5812
6213
|
"config show": ["memo config show", "memo config show --json"],
|
|
5813
6214
|
"config migrate": ["memo config migrate"],
|
|
5814
6215
|
"config unset": ["memo config unset permissions.notes.edit"],
|
|
@@ -5868,7 +6269,7 @@ var EXAMPLES = {
|
|
|
5868
6269
|
],
|
|
5869
6270
|
"models list": ["memo models list kind:text --json"],
|
|
5870
6271
|
"commands info": ["memo commands info --json"],
|
|
5871
|
-
"models download": ["memo models download
|
|
6272
|
+
"models download": ["memo models download embeddinggemma", "memo models download e5-small"],
|
|
5872
6273
|
"models set": ["memo models set e5-large"],
|
|
5873
6274
|
"models consents show": ["memo models consents show --json"],
|
|
5874
6275
|
"models consents set": [
|
|
@@ -5876,6 +6277,8 @@ var EXAMPLES = {
|
|
|
5876
6277
|
"memo models consents set openai --model gpt-4o-mini --yes"
|
|
5877
6278
|
],
|
|
5878
6279
|
"models consents revoke": ["memo models consents revoke"],
|
|
6280
|
+
"models keys set": ["memo models keys set openai", "memo models keys set anthropic"],
|
|
6281
|
+
"models keys remove": ["memo models keys remove openai"],
|
|
5879
6282
|
"models add": [
|
|
5880
6283
|
`memo models add e5-base --payload '{"repository":"Xenova/multilingual-e5-base","onnx":"onnx/model_quantized.onnx","dims":768,"pooling":"mean","prefix":{"query":"query: ","passage":"passage: "}}'`
|
|
5881
6284
|
],
|
|
@@ -5932,8 +6335,12 @@ var EXAMPLES = {
|
|
|
5932
6335
|
"memo organizations rename 1 'Harbour Studio Ltd' --json"
|
|
5933
6336
|
],
|
|
5934
6337
|
"organizations show": ["memo organizations show organization:1"],
|
|
5935
|
-
"organizations list": [
|
|
5936
|
-
|
|
6338
|
+
"organizations list": [
|
|
6339
|
+
"memo organizations list name:*harbour*",
|
|
6340
|
+
"memo organizations list category:client",
|
|
6341
|
+
"memo organizations list --json"
|
|
6342
|
+
],
|
|
6343
|
+
"organizations context": ["memo organizations context organization:1", "memo organizations context 1 --json"],
|
|
5937
6344
|
"projects meetings list": ["memo projects meetings list HRB --source zoom:me@example.com"],
|
|
5938
6345
|
"projects meetings link": ["memo projects meetings link HRB 31 --account zoom:me@example.com"],
|
|
5939
6346
|
"projects add": ["memo projects add 'Harbour' --key HRB --type client --organization 1"],
|
|
@@ -5957,12 +6364,20 @@ var EXAMPLES = {
|
|
|
5957
6364
|
"memo relationships update 12 --role approver --role-note 'signs the acts'"
|
|
5958
6365
|
],
|
|
5959
6366
|
"relationships add": [
|
|
5960
|
-
"memo relationships add person:3 organization:1 --role employee",
|
|
5961
|
-
"memo relationships add person:3
|
|
5962
|
-
"memo relationships add
|
|
6367
|
+
"memo relationships add person:3 organization:1 --role employee --position CTO --start-date 2026-01-01",
|
|
6368
|
+
"memo relationships add person:3 person:5 --kind reports-to",
|
|
6369
|
+
"memo relationships add organization:1 organization:2 --kind customer-of --reason 'signed in October'"
|
|
6370
|
+
],
|
|
6371
|
+
"relationships list": [
|
|
6372
|
+
'memo relationships list about:"person:3"',
|
|
6373
|
+
'memo relationships list kind:reports-to to:"person:5"',
|
|
6374
|
+
"memo relationships list standing:reported include:ended --limit 50"
|
|
5963
6375
|
],
|
|
5964
|
-
"relationships list": ['memo relationships list about:"person:3"', "memo relationships list confirmed:false"],
|
|
5965
6376
|
"relationships remove": ["memo relationships remove 4"],
|
|
6377
|
+
"relationships roles list": ["memo relationships roles list", "memo relationships roles list list:deal --json"],
|
|
6378
|
+
"relationships roles add": ["memo relationships roles add organization board-member --label 'Board member'"],
|
|
6379
|
+
"relationships roles remove": ["memo relationships roles remove organization board-member"],
|
|
6380
|
+
"relationships end": ["memo relationships end 4 --end-date 2026-09-30"],
|
|
5966
6381
|
"relationships confirm": ["memo relationships confirm 4"],
|
|
5967
6382
|
"relationships scan": [
|
|
5968
6383
|
"memo relationships scan HRB --source all",
|
|
@@ -6012,16 +6427,28 @@ var EXAMPLES = {
|
|
|
6012
6427
|
],
|
|
6013
6428
|
"deals list": ["memo deals list status:open project:HRB", "memo deals list stage:Quote --json"],
|
|
6014
6429
|
"deals show": ["memo deals show deal:5"],
|
|
6430
|
+
"deals context": ["memo deals context deal:5", "memo deals context deal:5 --brief --json"],
|
|
6431
|
+
"deals update": ["memo deals update deal:5 --project HRB"],
|
|
6015
6432
|
"deals add": [
|
|
6016
6433
|
"memo deals add 'Site for the clinic' Call 500000.00 RUB --organization organization:3 --project HRB",
|
|
6017
6434
|
"memo deals add 'Support contract' Sales/Quote --person person:7 --role decision-maker --due 2026-12-01"
|
|
6018
6435
|
],
|
|
6019
|
-
"deals move": ["memo deals move deal:5 Quote"],
|
|
6436
|
+
"deals move": ["memo deals move deal:5 Quote", "memo deals move deal:5 stage:5"],
|
|
6020
6437
|
"deals close": ["memo deals close deal:5 won", "memo deals close deal:6 lost --reason 'chose a cheaper studio'"],
|
|
6021
6438
|
"leads list": ["memo leads list status:open"],
|
|
6022
6439
|
"leads show": ["memo leads show lead:3"],
|
|
6440
|
+
"leads context": ["memo leads context lead:3 --brief"],
|
|
6441
|
+
"leads update": ["memo leads update lead:3 --project HRB"],
|
|
6023
6442
|
"leads add": ["memo leads add 'Call from the site'", "memo leads add 'Clinic in Kazan' contacted --person person:9"],
|
|
6024
|
-
"leads move": ["memo leads move lead:3 qualified"],
|
|
6443
|
+
"leads move": ["memo leads move lead:3 qualified", "memo leads move lead:3 stage:5"],
|
|
6444
|
+
"stages show": ["memo stages show deal", "memo stages show lead --json"],
|
|
6445
|
+
"stages create": ["memo stages create deal Demo", "memo stages create lead Spam lost"],
|
|
6446
|
+
"stages rename": ["memo stages rename deal Proposal 'Quote sent'"],
|
|
6447
|
+
"stages move": ["memo stages move deal Negotiation 2"],
|
|
6448
|
+
"stages remove": ["memo stages remove deal Negotiation"],
|
|
6449
|
+
"stages list": ["memo stages list confirmed:false", "memo stages list kind:deal pipeline:pipeline:3 --json"],
|
|
6450
|
+
"stages set": ["memo stages set stage:41 Proposal"],
|
|
6451
|
+
"stages confirm": ["memo stages confirm --pipeline pipeline:3", "memo stages confirm --all"],
|
|
6025
6452
|
"leads close": ["memo leads close lead:3 lost --reason 'no budget'"],
|
|
6026
6453
|
"orders add": [
|
|
6027
6454
|
"memo orders add 'Shop One' 2499.00 RUB --kind personal --title A-1042",
|
|
@@ -6194,6 +6621,13 @@ var EXAMPLES = {
|
|
|
6194
6621
|
"memo digest backfill --from 2026-11-01 --to 2026-11-07",
|
|
6195
6622
|
"memo digest backfill --from 2026-11-01 --to 2026-11-07 --yes --json"
|
|
6196
6623
|
],
|
|
6624
|
+
"digest brief show": ["memo digest brief show", "memo digest brief show --json"],
|
|
6625
|
+
"digest brief edit": [
|
|
6626
|
+
"memo digest brief edit",
|
|
6627
|
+
"memo digest brief edit --file brief.md",
|
|
6628
|
+
"memo digest brief edit --undo"
|
|
6629
|
+
],
|
|
6630
|
+
"digest brief reset": ["memo digest brief reset"],
|
|
6197
6631
|
"schedule remove": ["memo schedule remove digest"],
|
|
6198
6632
|
"schedule exec": ["memo schedule exec ~/.local/state/cli-memo/schedules/digest/schedule.json"],
|
|
6199
6633
|
"templates list": ["memo templates list", "memo templates list channel:telegram source:stored --json"],
|
|
@@ -6251,8 +6685,8 @@ var EXAMPLES = {
|
|
|
6251
6685
|
help: ["memo help options", "memo help tasks agenda"]
|
|
6252
6686
|
};
|
|
6253
6687
|
var leaves = /* @__PURE__ */ __name((command, path = []) => command.commands.flatMap((child) => {
|
|
6254
|
-
const
|
|
6255
|
-
return child.commands.length ? leaves(child,
|
|
6688
|
+
const at2 = [...path, child.name()];
|
|
6689
|
+
return child.commands.length ? leaves(child, at2) : [[at2.join(" "), child]];
|
|
6256
6690
|
}), "leaves");
|
|
6257
6691
|
var addExamples = /* @__PURE__ */ __name((program) => {
|
|
6258
6692
|
for (const [path, command] of leaves(program)) {
|
|
@@ -6469,11 +6903,11 @@ var statusLine = /* @__PURE__ */ __name((data) => {
|
|
|
6469
6903
|
var personal = /* @__PURE__ */ __name((newest) => !newest.bulk && !newest.list && !newest.envelope && !newest.demoted, "personal");
|
|
6470
6904
|
var gatherDigest = /* @__PURE__ */ __name(async (store, env, { since, now: clock = Date.now(), until, limit, excerpt: excerpt2, owedWithin, newSince }) => {
|
|
6471
6905
|
const now = until ?? clock;
|
|
6472
|
-
const by = /* @__PURE__ */ __name((
|
|
6906
|
+
const by = /* @__PURE__ */ __name((at2) => until === void 0 || at2 <= until, "by");
|
|
6473
6907
|
const upTo = /* @__PURE__ */ __name((found) => found.filter((one2) => by(Date.parse(one2.item.at))), "upTo");
|
|
6474
6908
|
const window = (now - since) / DAY7;
|
|
6475
6909
|
const days2 = `${Math.max(1, Math.ceil(window))}d`;
|
|
6476
|
-
const accounts = await store
|
|
6910
|
+
const accounts = await scopedAccounts(store, env);
|
|
6477
6911
|
const messengers2 = accounts.filter((key) => MESSENGERS2.has(key.provider));
|
|
6478
6912
|
const mailboxes = accounts.filter((key) => key.provider === "email");
|
|
6479
6913
|
const owedSince = Math.min(since, now - owedWithin);
|
|
@@ -6610,7 +7044,7 @@ var gatherDigest = /* @__PURE__ */ __name(async (store, env, { since, now: clock
|
|
|
6610
7044
|
bulk++;
|
|
6611
7045
|
continue;
|
|
6612
7046
|
}
|
|
6613
|
-
const
|
|
7047
|
+
const pending = /* @__PURE__ */ __name((why) => ({
|
|
6614
7048
|
item: {
|
|
6615
7049
|
ref: ref(thread.threadId),
|
|
6616
7050
|
who: null,
|
|
@@ -6622,15 +7056,15 @@ var gatherDigest = /* @__PURE__ */ __name(async (store, env, { since, now: clock
|
|
|
6622
7056
|
}), "pending");
|
|
6623
7057
|
if (isWatchedChat(key, thread.threadId)) {
|
|
6624
7058
|
if (inWindow)
|
|
6625
|
-
watch.push(
|
|
7059
|
+
watch.push(pending("watched thread"));
|
|
6626
7060
|
} else if (mailTurn(last) === "owed") {
|
|
6627
7061
|
if (inWindow)
|
|
6628
|
-
owedMail.push({ pending:
|
|
7062
|
+
owedMail.push({ pending: pending("owed reply"), externalId: last.externalId });
|
|
6629
7063
|
else if (thread.lastEmailAt >= owedSince)
|
|
6630
7064
|
olderMail++;
|
|
6631
7065
|
owedHere++;
|
|
6632
7066
|
} else if (inWindow && !last.outgoing) {
|
|
6633
|
-
mail.push(
|
|
7067
|
+
mail.push(pending("new mail"));
|
|
6634
7068
|
newHere++;
|
|
6635
7069
|
}
|
|
6636
7070
|
}
|
|
@@ -6879,16 +7313,16 @@ var sinceOf = /* @__PURE__ */ __name((value, now = Date.now()) => {
|
|
|
6879
7313
|
return since;
|
|
6880
7314
|
}, "sinceOf");
|
|
6881
7315
|
var beforeOf = /* @__PURE__ */ __name((value, now = Date.now()) => {
|
|
6882
|
-
const
|
|
6883
|
-
if (!/^\d{4}-\d{2}-\d{2}/.test(value) || Number.isNaN(
|
|
7316
|
+
const at2 = /^\d{4}-\d{2}-\d{2}$/.test(value) ? (/* @__PURE__ */ new Date(`${value}T00:00:00`)).getTime() : Date.parse(value);
|
|
7317
|
+
if (!/^\d{4}-\d{2}-\d{2}/.test(value) || Number.isNaN(at2))
|
|
6884
7318
|
throw new CliError("validation_error", `--before-time takes an ISO time or a date, not "${value}"`, {
|
|
6885
7319
|
param: "before-time"
|
|
6886
7320
|
});
|
|
6887
|
-
if (
|
|
7321
|
+
if (at2 > now)
|
|
6888
7322
|
throw new CliError("validation_error", "--before-time is in the future; leave it out for now", {
|
|
6889
7323
|
param: "before-time"
|
|
6890
7324
|
});
|
|
6891
|
-
return
|
|
7325
|
+
return at2;
|
|
6892
7326
|
}, "beforeOf");
|
|
6893
7327
|
var reviewAgendaCommand = /* @__PURE__ */ __name((review, print, streams, env) => {
|
|
6894
7328
|
annotate(review.command("agenda"), { effects: LOCAL_READ }).summary("the morning digest: watch list, owed replies, mail, meetings, tasks, projects").description(`the morning digest, from the store alone with no model call: everything new in what you tagged ${WATCH_TAG} (chats, mail threads, people, projects, a meeting's series), replies you owe to people in messengers and personal mail (not bots or service chats), new personal mail, meetings that ended, tasks, projects that moved, memories and facts whose sources changed (source reviews raised since), proposals waiting. Tasks are the open ones created since the last morning-digest run (a day back when none ran) and those overdue, due today or due tomorrow, each with who asked and who does it. Replies owed reach back 7 days; owed mail lists only senders you know (linked to a person with other identities, or written to before), and mail from new senders is one count with the command that lists it. Each item has its reference, who, when, one line of text and why it is there; a section cut by --limit or --max-output-bytes says how many it left out and the command that reads them. \`scope\` says what was read (the window, sources, counts), \`tasks\` counts each task group and, as \`undated\`, every open task with no due date, and \`health\` names each account whose sync failed, that nothing syncs, or that is quiet for longer than usual, so an unsynced account does not read as a quiet day; an account stored or synced within a day is never named`).option("--since-time <time>", "how far back: hours or days (12h, 7d) or a start date (2026-11-01)", "1d").option("--before-time <time>", "build it as of this past ISO time or date, for a past day's digest: --since-time counts back from it, and what came later is left out; a chat or thread answered since reads as answered").option("--limit <n>", "items per section before the size budget", positive, 25).option("--max-output-bytes <bytes>", "the text answer's size budget in bytes; 40000 with --compact, else 80000", positive).option("--compact", "one line per item, shorter excerpts, the smaller budget: for an agent").option("--json", "print JSON").action(async (given2) => {
|
|
@@ -6983,7 +7417,7 @@ var challengeCommand = /* @__PURE__ */ __name((parent, type, streams, env) => {
|
|
|
6983
7417
|
by,
|
|
6984
7418
|
...options.suggest === void 0 ? {} : { suggestion: options.suggest }
|
|
6985
7419
|
});
|
|
6986
|
-
return itemAnswer(await
|
|
7420
|
+
return itemAnswer(await reviewItemOf(store, proposal.id));
|
|
6987
7421
|
});
|
|
6988
7422
|
});
|
|
6989
7423
|
}, "challengeCommand");
|
|
@@ -7009,11 +7443,11 @@ var memoriesCommand = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
7009
7443
|
...options.supersedes === void 0 ? {} : { supersedes: options.supersedes }
|
|
7010
7444
|
}, await by).catch(explainQuote))));
|
|
7011
7445
|
});
|
|
7012
|
-
withQuery(annotate(memories.command("list"), { effects: LOCAL_READ }).description("memories, newest first"), MEMORY_QUERY).option("--limit <n>", "most memories, up to 500", positive, 100).option("--json", "print JSON; --json=id,title keeps only those fields").action((words, { json: json5, limit }) => run(json5, (store) => listMemories(store, words, limit)));
|
|
7013
|
-
annotate(memories.command("show"), { effects: LOCAL_READ, output: { entity: "memory" } }).description("one memory with its evidence").argument("<ref>", "memory:<id>").option("--sources", "read each piece of evidence back: who, when, a short excerpt, and whether it is gone").option("--json", "print JSON; --json=id,title keeps only those fields").action((ref, options) => run(options.json, async (store) => itemAnswer({
|
|
7446
|
+
withQuery(annotate(memories.command("list"), { effects: LOCAL_READ }).description("memories, newest first"), MEMORY_QUERY).option("--limit <n>", "most memories, up to 500", positive, 100).option("--json", "print JSON; --json=id,title keeps only those fields").action((words, { json: json5, limit }) => run(json5, async (store) => stripped(store, env, await listMemories(store, words, limit))));
|
|
7447
|
+
annotate(memories.command("show"), { effects: LOCAL_READ, output: { entity: "memory" } }).description("one memory with its evidence").argument("<ref>", "memory:<id>").option("--sources", "read each piece of evidence back: who, when, a short excerpt, and whether it is gone").option("--json", "print JSON; --json=id,title keeps only those fields").action((ref, options) => run(options.json, async (store) => itemAnswer(await stripped(store, env, {
|
|
7014
7448
|
...memoryItem(await store.memories.get(ref)),
|
|
7015
|
-
...options.sources ?
|
|
7016
|
-
})));
|
|
7449
|
+
...options.sources ? await sourcesIn(store, env, await store.memories.sources(ref)) : {}
|
|
7450
|
+
}))));
|
|
7017
7451
|
annotate(memories.command("update"), { effects: LOCAL_WRITE, output: { entity: "memory" } }).description("move a memory to another project, or to none").argument("<ref>", "memory:<id>").requiredOption("--project <project>", "the project's key or project:<id>; none takes it out of its project").option("--json", "print JSON; --json=id,title keeps only those fields").action((ref, options) => run(options.json, async (store) => itemAnswer(memoryItem(await store.memories.update(ref, {
|
|
7018
7452
|
project: options.project === "none" ? null : await canonicalProject(store, options.project)
|
|
7019
7453
|
})))));
|
|
@@ -7031,7 +7465,7 @@ var memoriesCommand = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
7031
7465
|
const decided = /* @__PURE__ */ __name(async (store, ref, by, confirm) => {
|
|
7032
7466
|
if ((await store.memories.get(ref)).status !== "proposed")
|
|
7033
7467
|
return confirm ? store.memories.confirm(ref, by) : store.memories.markStale(ref, by);
|
|
7034
|
-
await decideOne(store, ref, { confirm, by });
|
|
7468
|
+
await decideOne(store, env, ref, { confirm, by });
|
|
7035
7469
|
return store.memories.get(ref);
|
|
7036
7470
|
}, "decided");
|
|
7037
7471
|
decide2("confirm", "stand behind a memory: its evidence was checked now", (store, ref, by) => decided(store, ref, by, true));
|
|
@@ -7131,11 +7565,11 @@ var factsCommand = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
7131
7565
|
...options.supersedes === void 0 ? {} : { supersedes: options.supersedes }
|
|
7132
7566
|
}).catch(explainQuote))));
|
|
7133
7567
|
});
|
|
7134
|
-
withQuery(annotate(facts.command("list"), { effects: LOCAL_READ }).description("facts, latest first"), FACT_QUERY).option("--limit <n>", "most facts, up to 500", positive, 100).option("--json", "print JSON; --json=id,title keeps only those fields").action((words, { json: json5, limit }) => run(json5, (store) => listFacts(store, words, limit)));
|
|
7135
|
-
annotate(facts.command("show"), { effects: LOCAL_READ, output: { entity: "fact" } }).description("one fact with its evidence").argument("<ref>", "fact:<id>").option("--sources", "read each piece of evidence back: who, when, a short excerpt, and whether it is gone").option("--json", "print JSON; --json=id,title keeps only those fields").action((ref, options) => run(options.json, async (store) => itemAnswer({
|
|
7568
|
+
withQuery(annotate(facts.command("list"), { effects: LOCAL_READ }).description("facts, latest first"), FACT_QUERY).option("--limit <n>", "most facts, up to 500", positive, 100).option("--json", "print JSON; --json=id,title keeps only those fields").action((words, { json: json5, limit }) => run(json5, async (store) => stripped(store, env, await listFacts(store, words, limit))));
|
|
7569
|
+
annotate(facts.command("show"), { effects: LOCAL_READ, output: { entity: "fact" } }).description("one fact with its evidence").argument("<ref>", "fact:<id>").option("--sources", "read each piece of evidence back: who, when, a short excerpt, and whether it is gone").option("--json", "print JSON; --json=id,title keeps only those fields").action((ref, options) => run(options.json, async (store) => itemAnswer(await stripped(store, env, {
|
|
7136
7570
|
...factItem(await store.facts.get(ref)),
|
|
7137
|
-
...options.sources ?
|
|
7138
|
-
})));
|
|
7571
|
+
...options.sources ? await sourcesIn(store, env, await store.facts.sources(ref)) : {}
|
|
7572
|
+
}))));
|
|
7139
7573
|
const decide2 = /* @__PURE__ */ __name((name2, description, act) => reasonOption(byOption(annotate(facts.command(name2), {
|
|
7140
7574
|
effects: LOCAL_WRITE,
|
|
7141
7575
|
...name2 === "remove" ? {} : { output: { entity: "fact" } }
|
|
@@ -7148,13 +7582,13 @@ var factsCommand = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
7148
7582
|
});
|
|
7149
7583
|
}), "decide");
|
|
7150
7584
|
decide2("confirm", "stand behind a fact an agent proposed; a fact it supersedes stops holding. memo review confirm decides many", async (store, ref, by, why) => {
|
|
7151
|
-
await decideOne(store, ref, decisionOf(true, by, why));
|
|
7585
|
+
await decideOne(store, env, ref, decisionOf(true, by, why));
|
|
7152
7586
|
return store.facts.get(ref);
|
|
7153
7587
|
}).summary("stand behind a fact an agent proposed");
|
|
7154
7588
|
decide2("revoke", "take back your approval of an agent's fact; it waits as proposed again. Not for a correction or your own fact", (store, ref, by, why) => store.facts.revoke(ref, by, why)).summary("take back your approval of a fact an agent proposed");
|
|
7155
7589
|
decide2("reverse", "an accepted decision no longer holds, and nothing replaced it", (store, ref, by) => store.facts.reverse(ref, by));
|
|
7156
7590
|
decide2("reject", "turn down a fact an agent proposed; it stays, marked rejected", async (store, ref, by, why) => {
|
|
7157
|
-
await decideOne(store, ref, decisionOf(false, by, why));
|
|
7591
|
+
await decideOne(store, env, ref, decisionOf(false, by, why));
|
|
7158
7592
|
return store.facts.get(ref);
|
|
7159
7593
|
});
|
|
7160
7594
|
decide2("remove", "forget a fact: erase its text, its links to sources and its tags", (store, ref, by) => store.facts.remove(ref, by)).addHelpText("after", `
|
|
@@ -7181,7 +7615,7 @@ var SOURCED = new Set(Object.keys(READS));
|
|
|
7181
7615
|
var readSourced = /* @__PURE__ */ __name((store, kind, ref) => READS[kind]?.(store, ref), "readSourced");
|
|
7182
7616
|
var IMPORT = "import:";
|
|
7183
7617
|
var imported = /* @__PURE__ */ __name(({ source, account: account2 }) => (account2 ?? null) !== null || !!source?.startsWith(IMPORT), "imported");
|
|
7184
|
-
var
|
|
7618
|
+
var sourceAccounts2 = /* @__PURE__ */ __name(async (store, { source, account: account2 }) => {
|
|
7185
7619
|
if (account2)
|
|
7186
7620
|
return [account2];
|
|
7187
7621
|
if (!source?.startsWith(IMPORT))
|
|
@@ -7196,7 +7630,7 @@ var named2 = /* @__PURE__ */ __name((key) => ({
|
|
|
7196
7630
|
var sourcesOf = /* @__PURE__ */ __name(async (store, entity) => {
|
|
7197
7631
|
const { ref } = entity;
|
|
7198
7632
|
const records = [];
|
|
7199
|
-
for (const { provider, account: account2 } of await
|
|
7633
|
+
for (const { provider, account: account2 } of await sourceAccounts2(store, entity)) {
|
|
7200
7634
|
if (records.length > MOST)
|
|
7201
7635
|
break;
|
|
7202
7636
|
for (const one2 of await store.records.list({ provider, account: account2, entity: ref, limit: MOST + 1 }))
|
|
@@ -7541,6 +7975,46 @@ var contractCommands = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
7541
7975
|
});
|
|
7542
7976
|
}, "contractCommands");
|
|
7543
7977
|
|
|
7978
|
+
// dist/knowledge/money-text.js
|
|
7979
|
+
var totalLine = /* @__PURE__ */ __name(({ status, currency, rows, total, open: open2 }) => ` ${status} ${total} ${currency}${open2 === void 0 ? "" : `, ${open2} open`} (${rows})`, "totalLine");
|
|
7980
|
+
var moneyLines = /* @__PURE__ */ __name((money) => [
|
|
7981
|
+
...sectionLines("Invoices", money.invoices, (one2) => ` ${one2.title} ${one2.ref} ${one2.status} ${one2.total} ${one2.currency}, ${one2.open} open ${one2.review} via ${one2.linkedBy.join(", ")}`),
|
|
7982
|
+
...sectionLines("Payments", money.payments, (one2) => ` ${one2.title} ${one2.ref} ${one2.amount} ${one2.currency} ${one2.date} ${one2.review}`),
|
|
7983
|
+
...money.orders ? sectionLines("Orders", money.orders, (one2) => ` ${one2.title} ${one2.ref} ${one2.status} ${[one2.total, one2.currency].filter(Boolean).join(" ")}`) : [],
|
|
7984
|
+
...money.totals.invoices.length ? ["Invoiced, confirmed", ...money.totals.invoices.map(totalLine)] : [],
|
|
7985
|
+
...money.totals.payments.length ? ["Paid, confirmed", ...money.totals.payments.map(totalLine)] : [],
|
|
7986
|
+
...money.unconfirmed ? [` ${money.unconfirmed} not confirmed yet \u2014 not in the totals`] : [],
|
|
7987
|
+
...money.complete ? [] : [" more rows than one read: the totals may leave some out"]
|
|
7988
|
+
], "moneyLines");
|
|
7989
|
+
|
|
7990
|
+
// dist/finance/deal-text.js
|
|
7991
|
+
var amountOf = /* @__PURE__ */ __name((amount2, currency) => [amount2, currency].filter(Boolean).join(" "), "amountOf");
|
|
7992
|
+
var dealText = /* @__PURE__ */ __name((context) => {
|
|
7993
|
+
const { deal, organization, owner, project, window, communications } = context;
|
|
7994
|
+
return [
|
|
7995
|
+
`${deal.title} ${deal.ref} ${deal.stage} ${deal.status} ${amountOf(deal.amount, deal.currency)}`,
|
|
7996
|
+
`Client ${organization ? `${organization.name ?? organization.ref} ${organization.ref}` : "none"}`,
|
|
7997
|
+
`Owner ${owner ? relatedLine(owner).trim() : "none"}`,
|
|
7998
|
+
`Project ${project ? `${project.name ?? project.ref} ${project.ref}` : "none"}`,
|
|
7999
|
+
...sectionLines("Stages", context.stages, (one2) => ` ${one2.at.slice(0, 10)} ${one2.from ?? "\u2014"} \u2192 ${one2.to}`),
|
|
8000
|
+
...sectionLines("People", context.participants),
|
|
8001
|
+
...moneyLines(context.money),
|
|
8002
|
+
`Between ${window.since.slice(0, 10)} and ${window.until.slice(0, 10)}, proposed: they share people, nothing links them`,
|
|
8003
|
+
...sectionLines("Messages, mail and meetings", communications, (one2) => ` ${one2.at?.slice(0, 16).replace("T", " ") ?? "\u2014"} ${one2.kind} ${one2.title ?? ""} ${one2.ref}`),
|
|
8004
|
+
...sectionLines("Open tasks", context.tasks, (one2) => ` ${one2.key} ${one2.title} ${one2.status}`),
|
|
8005
|
+
...coverageLines(context.coverage)
|
|
8006
|
+
].map((line3) => line3.trimEnd()).join("\n");
|
|
8007
|
+
}, "dealText");
|
|
8008
|
+
var dealBriefText = /* @__PURE__ */ __name((brief) => [
|
|
8009
|
+
`${brief.title} ${brief.ref} ${brief.pipeline}/${brief.stage} ${brief.status} ${amountOf(brief.amount, brief.currency)}`,
|
|
8010
|
+
`client ${brief.organization ?? "none"}; owner ${brief.owner ?? "none"}; project ${brief.project ?? "none"}`,
|
|
8011
|
+
...brief.people.map((one2) => ` ${one2.name ?? one2.ref} ${one2.ref} ${one2.roles.join(", ")} ${one2.standing}`),
|
|
8012
|
+
...brief.stages.length ? [`stages ${brief.stages.join("; ")}`] : [],
|
|
8013
|
+
`invoiced ${brief.money.invoices.map((one2) => `${one2.status} ${one2.total} ${one2.currency}`).join(", ") || "none"}; paid ${brief.money.payments.map((one2) => `${one2.total} ${one2.currency}`).join(", ") || "none"}`,
|
|
8014
|
+
`${brief.communications.messages} messages, ${brief.communications.mail} emails, ${brief.communications.meetings} meetings (proposed); ${brief.openTasks} open tasks`,
|
|
8015
|
+
...brief.notRead.map(({ source, reason }) => `not read: ${source} \u2014 ${reason}`)
|
|
8016
|
+
].map((line3) => line3.trimEnd()).join("\n"), "dealBriefText");
|
|
8017
|
+
|
|
7544
8018
|
// dist/finance/deals-command.js
|
|
7545
8019
|
var queryOf = /* @__PURE__ */ __name((entity) => ({
|
|
7546
8020
|
entity,
|
|
@@ -7559,7 +8033,14 @@ var PIPELINE_QUERY = {
|
|
|
7559
8033
|
backend: "native",
|
|
7560
8034
|
fields: [termField("kind", "enum", "kind:lead", { values: DEAL_KINDS }), termField("name", "kw", "name:Sales")]
|
|
7561
8035
|
};
|
|
7562
|
-
var
|
|
8036
|
+
var withWriter = /* @__PURE__ */ __name(async (store) => {
|
|
8037
|
+
const profilesFor2 = storedProfilesFor(await store.accounts.profiles());
|
|
8038
|
+
return (item) => ({
|
|
8039
|
+
...item,
|
|
8040
|
+
writesWith: writesWithOf(item.account, profilesFor2)
|
|
8041
|
+
});
|
|
8042
|
+
}, "withWriter");
|
|
8043
|
+
var listDeals = /* @__PURE__ */ __name(async (store, env, kind, words, limit) => {
|
|
7563
8044
|
const command = `${kind}s list`;
|
|
7564
8045
|
const terms2 = queryTerms(words, QUERIES[kind], command);
|
|
7565
8046
|
const filter = {
|
|
@@ -7570,8 +8051,21 @@ var listDeals = /* @__PURE__ */ __name(async (store, kind, words, limit) => {
|
|
|
7570
8051
|
...terms2.has("pipeline") ? { pipeline: terms2.get("pipeline") } : {},
|
|
7571
8052
|
...terms2.has("organization") ? { organization: terms2.get("organization") } : {}
|
|
7572
8053
|
};
|
|
7573
|
-
|
|
8054
|
+
const scope = await groupScopeOf(store, env);
|
|
8055
|
+
const writer = await withWriter(store);
|
|
8056
|
+
return pageOf(command, limit, async (most) => (await store.deals.list({ ...filter, ...scope === void 0 ? {} : { accounts: scope.accounts }, limit: most })).map(writer));
|
|
7574
8057
|
}, "listDeals");
|
|
8058
|
+
var BASE_STAGE = /^stage:\d+$/;
|
|
8059
|
+
var stageToMove = /* @__PURE__ */ __name(async (store, ref, stage) => {
|
|
8060
|
+
if (!BASE_STAGE.test(stage.trim()))
|
|
8061
|
+
return stage;
|
|
8062
|
+
const row = await store.deals.get(ref);
|
|
8063
|
+
if (row.account !== null) {
|
|
8064
|
+
const writesWith = writesWithOf(row.account, storedProfilesFor(await store.accounts.profiles()));
|
|
8065
|
+
throw new CliError("validation_error", `${ref} is a copy from ${row.account.provider}:${row.account.account}; move it there with ${writesWith?.tool ?? "its CRM's CLI"} ${row.kind}s move ${ref} ${stage.trim()}`, { reason: "stage.crm-copy", writes_with: writesWith });
|
|
8066
|
+
}
|
|
8067
|
+
return (await store.baseStages.resolve(ref, stage.trim())).stage.name;
|
|
8068
|
+
}, "stageToMove");
|
|
7575
8069
|
var roleOf = /* @__PURE__ */ __name((role) => {
|
|
7576
8070
|
const value = role ?? "contact";
|
|
7577
8071
|
if (!DEAL_ROLES.includes(value))
|
|
@@ -7582,18 +8076,38 @@ var referenceOf = /* @__PURE__ */ __name((kind, value) => /^\d+$/.test(value.tri
|
|
|
7582
8076
|
var stageOf = /* @__PURE__ */ __name((stage) => {
|
|
7583
8077
|
if (stage === void 0)
|
|
7584
8078
|
return {};
|
|
7585
|
-
const
|
|
7586
|
-
return
|
|
8079
|
+
const at2 = stage.lastIndexOf("/");
|
|
8080
|
+
return at2 <= 0 ? { stage } : { pipeline: stage.slice(0, at2), stage: stage.slice(at2 + 1) };
|
|
7587
8081
|
}, "stageOf");
|
|
7588
8082
|
var WHAT = {
|
|
7589
8083
|
deal: { one: "deal", hope: "what you hope to sell, such as 'Site for the clinic'" },
|
|
7590
8084
|
lead: { one: "lead", hope: "who or what came in, such as 'Call from the site'" }
|
|
7591
8085
|
};
|
|
7592
|
-
var itemCommands = /* @__PURE__ */ __name((program, kind, run, env) => {
|
|
8086
|
+
var itemCommands = /* @__PURE__ */ __name((program, kind, { run, print }, env) => {
|
|
7593
8087
|
const { one: one2, hope } = WHAT[kind];
|
|
7594
8088
|
const group = program.command(`${kind}s`).description(kind === "deal" ? "deals you hope to win: the client, the expected amount, the stage and whether it was won or lost" : "leads: first contacts in a lead pipeline, before they are deals").summary(kind === "deal" ? "deals in your pipelines, open, won or lost" : "leads in your lead pipelines");
|
|
7595
|
-
withQuery(json(annotate(group.command("list"), { effects: LOCAL_READ })).description(`${one2}s, newest first; status:open is what is still in play`), QUERIES[kind]).summary(`${one2}s, newest first`).option("--limit <n>", `most ${one2}s, up to 500`, positive, 100).action((words, { json: json5, limit }) => run(json5, (store) => listDeals(store, kind, words, limit)));
|
|
8089
|
+
withQuery(json(annotate(group.command("list"), { effects: LOCAL_READ })).description(`${one2}s, newest first; status:open is what is still in play`), QUERIES[kind]).summary(`${one2}s, newest first`).option("--limit <n>", `most ${one2}s, up to 500`, positive, 100).action((words, { json: json5, limit }) => run(json5, (store) => listDeals(store, env, kind, words, limit)));
|
|
7596
8090
|
json(annotate(group.command("show"), { effects: LOCAL_READ, output: { entity: kind } })).description(`one ${one2} with its pipeline, stage, status, amount, the people on it and what it was read from`).summary(`one ${one2} with its stage, status, amount and people`).argument("<ref>", `${kind}:<id>`).action((ref, options, command) => run(options.json, async (store) => itemAnswer(await withSources(command, store, await store.deals.get(ref)))));
|
|
8091
|
+
json(annotate(group.command("context"), { effects: LOCAL_READ, output: { entity: "deal_context" } })).description(`one ${one2} whole: its stages, client, people with their roles and standing, owner, project, invoices and payments as stored, its people's messages, mail and meetings in its lifetime (\`proposed\`: they share people, nothing links them), open tasks and \`coverage\`. A stage named Won is not a payment`).summary(`one ${one2}: stages, people, project, money, messages and tasks`).argument("<ref>", `${kind}:<id>`).option("--brief", "the compact form for a model's context: names, roles, totals and counts").option("--limit <n>", "most items in each section", positive, 20).action(async (ref, options, command) => {
|
|
8092
|
+
const answer = await withStore(env, async (store) => {
|
|
8093
|
+
const scope = await groupScopeOf(store, env);
|
|
8094
|
+
return lockedCoverage(store, env, await dealContext(store, ref, {
|
|
8095
|
+
limit: options.limit,
|
|
8096
|
+
...scope === void 0 ? {} : { accounts: scope.accounts },
|
|
8097
|
+
deniedKinds: deniedCrmKinds(command, env)
|
|
8098
|
+
}));
|
|
8099
|
+
});
|
|
8100
|
+
if (answer.deal.kind !== kind)
|
|
8101
|
+
throw new CliError("validation_error", `${ref} is a ${answer.deal.kind} \u2014 memo ${answer.deal.kind}s context`);
|
|
8102
|
+
print(options.json, itemAnswer(options.brief ? dealBrief(answer) : answer), options.brief ? dealBriefText(dealBrief(answer)) : dealText(answer));
|
|
8103
|
+
});
|
|
8104
|
+
json(annotate(group.command("update"), { effects: LOCAL_WRITE, output: { entity: kind } })).description(`set the project a ${one2} belongs to; a CRM's copy takes it too, and the next sync keeps it. An empty value clears it`).summary(`set the project a ${one2} belongs to`).argument("<ref>", `${kind}:<id>`).requiredOption("--project <project>", "the project: its key or project:<id>").action(async (ref, options) => {
|
|
8105
|
+
const by = authorOf(env);
|
|
8106
|
+
await run(options.json, async (store) => itemAnswer(await store.deals.setProject(ref, {
|
|
8107
|
+
project: options.project === "" ? null : await canonicalProject(store, options.project),
|
|
8108
|
+
by
|
|
8109
|
+
})));
|
|
8110
|
+
});
|
|
7597
8111
|
json(annotate(group.command("add"), { effects: LOCAL_WRITE, output: { entity: kind }, literal_after_dashes: true }).option("--organization <organization>", "the client: organization:<id>").option("--person <uid>", `a person on the ${one2}: person:<id>; repeat for another, up to 20`, collect).option("--role <role>", `what those people are on it: ${DEAL_ROLES.join(", ")}; contact by default`).option("--due <time>", "the day you expect it to close, such as 2026-12-01").option("--project <project>", "the project it belongs to: its key or project:<id>").option("--reason <text>", "why an agent records it, kept with it").option("--evidence <ref...>", "what shows it, up to 8: msg:, note:, document: or another reference")).description(`record a ${one2} in a stage; it is written at once, whoever runs it`).summary(`record a ${one2} in a stage`).argument("<title>", hope).argument(kind === "deal" ? "<stage>" : "[stage]", kind === "deal" ? "the stage it is in; Sales/Quote or pipeline:3/Quote names the pipeline when two have that stage" : "the stage it is in; the first stage of the only lead pipeline when left out").argument("[amount]", "the expected amount, a decimal such as 500000.00").argument("[currency]", "ISO 4217, such as RUB; given with the amount").action(async (title, stage, amount2, currency, options) => {
|
|
7598
8112
|
const by = authorOf(env);
|
|
7599
8113
|
const role = roleOf(options.role);
|
|
@@ -7615,9 +8129,9 @@ var itemCommands = /* @__PURE__ */ __name((program, kind, run, env) => {
|
|
|
7615
8129
|
}));
|
|
7616
8130
|
});
|
|
7617
8131
|
});
|
|
7618
|
-
json(annotate(group.command("move"), { effects: LOCAL_WRITE, output: { entity: kind } })).description(`move a ${one2} to another stage of its pipeline; a won or lost stage closes it, an open one reopens it`).summary(`move a ${one2} to another stage`).argument("<ref>", `${kind}:<id>`).argument("<stage>", `a stage of the ${one2}'s pipeline`).action(async (ref, stage, options) => {
|
|
8132
|
+
json(annotate(group.command("move"), { effects: LOCAL_WRITE, output: { entity: kind } })).description(`move a ${one2} to another stage of its pipeline; a won or lost stage closes it, an open one reopens it`).summary(`move a ${one2} to another stage`).argument("<ref>", `${kind}:<id>`).argument("<stage>", `a stage of the ${one2}'s pipeline by its name or stage:<id>; or a base stage's stage:<id>, which moves it to the one stage of its pipeline mapped there, and refuses several (with the candidates) or none`).action(async (ref, stage, options) => {
|
|
7619
8133
|
const by = authorOf(env);
|
|
7620
|
-
await run(options.json, async (store) => itemAnswer(await store.deals.move(ref, { stage, by })));
|
|
8134
|
+
await run(options.json, async (store) => itemAnswer(await store.deals.move(ref, { stage: await stageToMove(store, ref, stage), by })));
|
|
7621
8135
|
});
|
|
7622
8136
|
json(annotate(group.command("close"), { effects: LOCAL_WRITE, output: { entity: kind } }).option("--occurred-time <time>", "the day it closed, such as 2026-11-20; today when left out").option("--reason <text>", "why it was won or lost, kept with it")).description(`close a ${one2} as won or lost; it moves to its pipeline's won or lost stage when there is one`).summary(`close a ${one2} as won or lost`).argument("<ref>", `${kind}:<id>`).argument("<outcome>", "won or lost").action(async (ref, outcome, options) => {
|
|
7623
8137
|
if (outcome !== "won" && outcome !== "lost")
|
|
@@ -7638,6 +8152,21 @@ var funnelText = /* @__PURE__ */ __name((report) => [
|
|
|
7638
8152
|
...report.stages.map((stage) => ` ${stage.position}. ${stage.name}${stage.outcome === "open" ? "" : ` [${stage.outcome}]`}: ${stage.open} open, ${stage.reached} reached${percent(stage.conversion)}`),
|
|
7639
8153
|
` ${report.totals.items} in all: ${report.totals.open} open, ${report.totals.won} won, ${report.totals.lost} lost` + (report.totals.winRate === null ? "" : `, win rate ${Math.round(report.totals.winRate * 100)}%`)
|
|
7640
8154
|
].join("\n"), "funnelText");
|
|
8155
|
+
var inScope = /* @__PURE__ */ __name((scope) => (pipeline) => scope === void 0 || pipeline.account === null || scope.has(pipeline.account), "inScope");
|
|
8156
|
+
var pipelineInGroup = /* @__PURE__ */ __name(async (store, env, reference2) => {
|
|
8157
|
+
const scope = await groupScopeOf(store, env);
|
|
8158
|
+
if (scope === void 0 || /^pipeline:\d+$/.test(reference2.trim()))
|
|
8159
|
+
return reference2;
|
|
8160
|
+
const name2 = reference2.trim().toLocaleLowerCase();
|
|
8161
|
+
const named5 = (await store.deals.pipelines()).filter((one2) => one2.name.toLocaleLowerCase() === name2 && inScope(scope)(one2));
|
|
8162
|
+
if (named5.length === 1)
|
|
8163
|
+
return named5[0].ref;
|
|
8164
|
+
if (named5.length === 0)
|
|
8165
|
+
throw new CliError("not_found", `no pipeline named ${reference2.trim()} in group:${scope.run.name}`, {
|
|
8166
|
+
reason: "pipeline.not-found"
|
|
8167
|
+
});
|
|
8168
|
+
throw new CliError("validation_error", `more than one pipeline in group:${scope.run.name} is named ${reference2.trim()}: ${named5.map((one2) => one2.ref).join(", ")}; name one by its reference`, { reason: "pipeline.ambiguous" });
|
|
8169
|
+
}, "pipelineInGroup");
|
|
7641
8170
|
var dealCommands = /* @__PURE__ */ __name((program, streams, env) => {
|
|
7642
8171
|
const { run, print } = answers(program, streams, env);
|
|
7643
8172
|
const pipelines = program.command("pipelines").description("sales pipelines: the stages a deal or a lead goes through, in order, and how many get through each").summary("sales pipelines, their stages and conversion");
|
|
@@ -7645,15 +8174,17 @@ var dealCommands = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
7645
8174
|
const terms2 = queryTerms(words, PIPELINE_QUERY, "pipelines list");
|
|
7646
8175
|
const name2 = terms2.get("name")?.toLocaleLowerCase();
|
|
7647
8176
|
const kind = terms2.get("kind");
|
|
7648
|
-
const
|
|
7649
|
-
|
|
8177
|
+
const scope = await groupScopeOf(store, env);
|
|
8178
|
+
const all = (await store.deals.pipelines(kind === void 0 ? {} : { kind })).filter(inScope(scope));
|
|
8179
|
+
const writer = await withWriter(store);
|
|
8180
|
+
return wholeList("pipelines list", (name2 === void 0 ? all : all.filter((one2) => one2.name.toLocaleLowerCase() === name2)).map(writer));
|
|
7650
8181
|
}));
|
|
7651
8182
|
json(annotate(pipelines.command("show"), { effects: LOCAL_READ, output: { entity: "pipeline" } }).option("--since-time <time>", "count only deals or leads made since this day, such as 2026-09-01")).description("one pipeline's funnel: per stage the open deals or leads in it, how many reached it, and the share that went on to the next stage; then won, lost and the win rate").summary("one pipeline's stages with counts and conversion").argument("<pipeline>", "pipeline:<id>, or a name only one pipeline has").action(async (pipeline, options, command) => {
|
|
7652
8183
|
const since = dayOf2(options.sinceTime);
|
|
7653
|
-
const report = await withStore(env, async (store) => withSources(command, store, await store.deals.pipeline(pipeline, since === void 0 ? {} : { since })));
|
|
8184
|
+
const report = await withStore(env, async (store) => withSources(command, store, await store.deals.pipeline(await pipelineInGroup(store, env, pipeline), since === void 0 ? {} : { since })));
|
|
7654
8185
|
print(options.json, itemAnswer(report), funnelText(report));
|
|
7655
8186
|
});
|
|
7656
|
-
json(annotate(pipelines.command("add"), { effects: LOCAL_WRITE, literal_after_dashes: true }).option("--kind <kind>", "what it holds: deal or lead; deal by default")).description("make a pipeline with its stages in order; a stage named won or lost (any letter case) ends a deal or lead as that").summary("make a pipeline with its stages").argument("<name>", "the pipeline's name, such as Sales").argument("<stage...>", "its stages in order, such as Call Quote Contract won lost").action(async (name2,
|
|
8187
|
+
json(annotate(pipelines.command("add"), { effects: LOCAL_WRITE, literal_after_dashes: true }).option("--kind <kind>", "what it holds: deal or lead; deal by default")).description("make a pipeline with its stages in order; a stage named won or lost (any letter case) ends a deal or lead as that").summary("make a pipeline with its stages").argument("<name>", "the pipeline's name, such as Sales").argument("<stage...>", "its stages in order, such as Call Quote Contract won lost").action(async (name2, stages2, options) => {
|
|
7657
8188
|
const kind = options.kind ?? "deal";
|
|
7658
8189
|
if (!DEAL_KINDS.includes(kind))
|
|
7659
8190
|
throw new CliError("validation_error", "--kind is deal or lead", { param: "--kind" });
|
|
@@ -7661,15 +8192,24 @@ var dealCommands = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
7661
8192
|
await run(options.json, async (store) => itemAnswer(await store.deals.addPipeline({
|
|
7662
8193
|
name: name2,
|
|
7663
8194
|
kind,
|
|
7664
|
-
stages:
|
|
8195
|
+
stages: stages2.map((stage) => {
|
|
7665
8196
|
const word = stage.trim().toLocaleLowerCase();
|
|
7666
8197
|
return word === "won" || word === "lost" ? { name: stage, outcome: word } : stage;
|
|
7667
8198
|
}),
|
|
7668
8199
|
by
|
|
7669
8200
|
})));
|
|
7670
8201
|
});
|
|
7671
|
-
itemCommands(program, "deal", run, env);
|
|
7672
|
-
itemCommands(program, "lead", run, env);
|
|
8202
|
+
itemCommands(program, "deal", { run, print }, env);
|
|
8203
|
+
itemCommands(program, "lead", { run, print }, env);
|
|
8204
|
+
const stages = baseStagesCommand(APP, {
|
|
8205
|
+
env: /* @__PURE__ */ __name(() => env, "env"),
|
|
8206
|
+
open: /* @__PURE__ */ __name(() => openMemoStore(env), "open"),
|
|
8207
|
+
output: /* @__PURE__ */ __name((body, command) => print(command.opts().json, body), "output"),
|
|
8208
|
+
accounts: /* @__PURE__ */ __name(async (store) => (await groupScopeOf(store, env))?.accounts, "accounts")
|
|
8209
|
+
});
|
|
8210
|
+
for (const leaf of stages.commands)
|
|
8211
|
+
json(leaf);
|
|
8212
|
+
program.addCommand(stages);
|
|
7673
8213
|
}, "dealCommands");
|
|
7674
8214
|
var STATUS_DEALS = 5;
|
|
7675
8215
|
var openDealsOf = /* @__PURE__ */ __name(async (store, projects) => {
|
|
@@ -8017,7 +8557,7 @@ var listWallets = /* @__PURE__ */ __name(async (store, words, limit) => {
|
|
|
8017
8557
|
var sourceSays = /* @__PURE__ */ __name(async (store, wallet) => {
|
|
8018
8558
|
if (wallet.openingBalance !== null)
|
|
8019
8559
|
return null;
|
|
8020
|
-
for (const { provider, account: account2 } of await
|
|
8560
|
+
for (const { provider, account: account2 } of await sourceAccounts2(store, wallet)) {
|
|
8021
8561
|
const [record2] = await store.records.list({ provider, account: account2, entity: wallet.ref, limit: 1 });
|
|
8022
8562
|
const { opening_balance: balance, opening_date: date } = record2?.fields ?? {};
|
|
8023
8563
|
if (record2 && typeof balance === "string")
|
|
@@ -8143,15 +8683,15 @@ var findingsCommand = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
8143
8683
|
|
|
8144
8684
|
// dist/json-fields.js
|
|
8145
8685
|
var commandIn = /* @__PURE__ */ __name((root, words) => {
|
|
8146
|
-
let
|
|
8686
|
+
let at2 = root;
|
|
8147
8687
|
for (const word of words) {
|
|
8148
8688
|
if (word.startsWith("-"))
|
|
8149
8689
|
continue;
|
|
8150
|
-
const child =
|
|
8690
|
+
const child = at2.commands.find((command) => command.name() === word || command.aliases().includes(word));
|
|
8151
8691
|
if (child)
|
|
8152
|
-
|
|
8692
|
+
at2 = child;
|
|
8153
8693
|
}
|
|
8154
|
-
return
|
|
8694
|
+
return at2 === root ? void 0 : at2;
|
|
8155
8695
|
}, "commandIn");
|
|
8156
8696
|
var keep = /* @__PURE__ */ __name((text3, paths) => {
|
|
8157
8697
|
let value;
|
|
@@ -8246,6 +8786,27 @@ var meetingProjectsCommand = /* @__PURE__ */ __name((projects, streams, env) =>
|
|
|
8246
8786
|
})), true));
|
|
8247
8787
|
}, "meetingProjectsCommand");
|
|
8248
8788
|
|
|
8789
|
+
// dist/knowledge/organization-text.js
|
|
8790
|
+
var organizationText = /* @__PURE__ */ __name((answer) => {
|
|
8791
|
+
const { organization, categories, communications } = answer;
|
|
8792
|
+
return [
|
|
8793
|
+
`${organization.name} ${organization.ref}${organization.own ? " (your own)" : ""}`,
|
|
8794
|
+
...categories.length ? [`Categories ${categories.join(", ")}`] : [],
|
|
8795
|
+
...answer.tags.length ? [`Tags ${answer.tags.join(", ")}`] : [],
|
|
8796
|
+
...sectionLines("People", answer.people),
|
|
8797
|
+
...sectionLines("Customers", answer.customers),
|
|
8798
|
+
...sectionLines("Suppliers", answer.suppliers),
|
|
8799
|
+
...sectionLines("Partners", answer.partners),
|
|
8800
|
+
...sectionLines("Projects", answer.projects, (one2) => ` ${one2.name} ${one2.ref} via ${one2.via.join(", ")}`),
|
|
8801
|
+
...sectionLines("Open deals and leads", answer.deals, (one2) => ` ${one2.title} ${one2.ref} ${one2.stage} ${[one2.amount, one2.currency].filter(Boolean).join(" ")}`),
|
|
8802
|
+
...moneyLines(answer.money),
|
|
8803
|
+
`Written by its people ${communications.messages} messages, ${communications.mail} emails, ${communications.meetings} meetings`,
|
|
8804
|
+
...sectionLines("Open tasks", answer.tasks, (one2) => ` ${one2.key} ${one2.title} ${one2.status}`),
|
|
8805
|
+
...answer.notes.about.length ? ["Notes about it", ...answer.notes.about.map((note) => ` ${note.ref}`)] : [],
|
|
8806
|
+
...coverageLines(answer.coverage)
|
|
8807
|
+
].map((line3) => line3.trimEnd()).join("\n");
|
|
8808
|
+
}, "organizationText");
|
|
8809
|
+
|
|
8249
8810
|
// dist/knowledge/project-actions.js
|
|
8250
8811
|
var evidenceContext = /* @__PURE__ */ __name(async (store, ref, fingerprint, words, window) => {
|
|
8251
8812
|
const record2 = await store.contextRecords?.read(ref);
|
|
@@ -8305,14 +8866,14 @@ var projectActions = /* @__PURE__ */ __name(async (store, project, options) => {
|
|
|
8305
8866
|
hasMore: found.hasMore
|
|
8306
8867
|
};
|
|
8307
8868
|
}, "projectActions");
|
|
8308
|
-
var decideAction = /* @__PURE__ */ __name(async (store, project, id, decision) => {
|
|
8869
|
+
var decideAction = /* @__PURE__ */ __name(async (store, env, project, id, decision) => {
|
|
8309
8870
|
if (!/^(key:)?[1-9]\d*$/.test(id))
|
|
8310
8871
|
throw new CliError("validation_error", "an action ID is a batch number or key:<id>");
|
|
8311
8872
|
const row = await proposalRegistry(store).get(id);
|
|
8312
8873
|
if (row.project !== project.ref || row.kind !== "key_document" && row.kind !== "findings")
|
|
8313
8874
|
throw new CliError("not_found", `no proposal ${id} in ${project.ref}; memo projects actions list shows them`);
|
|
8314
8875
|
if (row.kind === "key_document") {
|
|
8315
|
-
await decideOne(store, id, decisionOf(decision.confirm, decision.by, decision.reason));
|
|
8876
|
+
await decideOne(store, env, id, decisionOf(decision.confirm, decision.by, decision.reason));
|
|
8316
8877
|
return { id, kind: "key_document", ref: row.subject, confirmed: decision.confirm, decided_by: decision.by };
|
|
8317
8878
|
}
|
|
8318
8879
|
if (decision.fingerprint === void 0)
|
|
@@ -8391,7 +8952,7 @@ var projectActionsCommand = /* @__PURE__ */ __name((projects, streams, env) => {
|
|
|
8391
8952
|
const by = await deciderOf(command, env, { ...given2, question: `${name2} ${id} as you, the owner?` });
|
|
8392
8953
|
await run(given2.json, async (store) => {
|
|
8393
8954
|
const project = await projectOf(store, reference2);
|
|
8394
|
-
return itemAnswer(await decideAction(store, project, id, {
|
|
8955
|
+
return itemAnswer(await decideAction(store, env, project, id, {
|
|
8395
8956
|
confirm: name2 === "confirm",
|
|
8396
8957
|
...given2.fingerprint === void 0 ? {} : { fingerprint: given2.fingerprint },
|
|
8397
8958
|
...given2.reason === void 0 ? {} : { reason: given2.reason },
|
|
@@ -8445,15 +9006,17 @@ var projectFindings = /* @__PURE__ */ __name(async (store, project, links) => {
|
|
|
8445
9006
|
// dist/knowledge/project-context.js
|
|
8446
9007
|
var projectContext = /* @__PURE__ */ __name(async (store, env, reference2) => {
|
|
8447
9008
|
const project = await projectOf(store, reference2);
|
|
8448
|
-
const
|
|
9009
|
+
const linked2 = 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")).map((link2) => ({ ...link2, standing: standingOf(link2, Date.now()) }));
|
|
9010
|
+
const relationships = await keepInGroup(store, env, linked2, (link2) => link2.from === project.ref ? String(link2.to) : link2.from);
|
|
8449
9011
|
const documents = await keyDocuments(store, project);
|
|
8450
|
-
const
|
|
9012
|
+
const proposals = await proposalsOf(store, env);
|
|
9013
|
+
const pending = /* @__PURE__ */ __name((kind) => proposals.list({ project: project.ref, kinds: [kind], status: "proposed", limit: 50, offset: 0 }), "pending");
|
|
8451
9014
|
const [facts, tasks, findings, keys, links, waiting2] = await Promise.all([
|
|
8452
9015
|
store.facts.list({ project: project.ref, status: "proposed", limit: 21 }),
|
|
8453
9016
|
store.tasks.find({ project: project.ref, status: "open", limit: 21 }),
|
|
8454
9017
|
projectFindings(store, project.ref, relationships),
|
|
8455
|
-
|
|
8456
|
-
|
|
9018
|
+
pending("key_document"),
|
|
9019
|
+
pending("relationship"),
|
|
8457
9020
|
waitingAbout(store, env, [project.ref])
|
|
8458
9021
|
]);
|
|
8459
9022
|
const label = await labelsFor(store, [...keys.items, ...links.items].flatMap((row) => [row.subject, row.object]));
|
|
@@ -8648,7 +9211,7 @@ var projectGatherCommand = /* @__PURE__ */ __name((projects, print, env, warn) =
|
|
|
8648
9211
|
...found,
|
|
8649
9212
|
linkedChats: found.linkedChats.map((one2, i) => ({ ...one2, syncCommand: syncs[i]?.command ?? null }))
|
|
8650
9213
|
}, { ...parts2, ...missing.length ? { missing } : {}, ...next.length ? { next } : {} }), projectEvidenceText(found, {
|
|
8651
|
-
sync: /* @__PURE__ */ __name((chat,
|
|
9214
|
+
sync: /* @__PURE__ */ __name((chat, at2) => syncHint(chat, at2, env, chosen), "sync"),
|
|
8652
9215
|
showDocument: "memo notes show"
|
|
8653
9216
|
}));
|
|
8654
9217
|
})
|
|
@@ -8688,7 +9251,7 @@ var outside = /* @__PURE__ */ __name((blocked) => (step, found) => {
|
|
|
8688
9251
|
};
|
|
8689
9252
|
}, "outside");
|
|
8690
9253
|
var asAction = /* @__PURE__ */ __name((step) => step.kind === "command" ? { kind: "user_action", step: step.step, why: `${step.why}: ${step.line}`, safe_to_auto_execute: false } : step, "asAction");
|
|
8691
|
-
var projectStatusCommand = /* @__PURE__ */ __name((projects, print, env) => answerEntity(annotate(projects.command("status"), { effects: LOCAL_READ, partial: true }), "project_status", projectStatusSchema, { row: withFinance(projectStatusRow(STATUS_SIGNALS)) }).description("where a project stands, from the stored messages of every chat confirmed as the project's or its child projects', in every account those links name (meta.accounts lists them): the last message, who replies next, open questions both ways, promises, amounts found by words with their direction (only when the project has no confirmed invoice or payment), payments recorded, billed, paid and owed per currency from confirmed invoices and payments (finance), up to five open
|
|
9254
|
+
var projectStatusCommand = /* @__PURE__ */ __name((projects, print, env) => answerEntity(annotate(projects.command("status"), { effects: LOCAL_READ, partial: true }), "project_status", projectStatusSchema, { row: withFinance(projectStatusRow(STATUS_SIGNALS)) }).description("where a project stands, from the stored messages of every chat confirmed as the project's or its child projects', in every account those links name (meta.accounts lists them): the last message, who replies next, open questions both ways, promises, amounts found by words with their direction (only when the project has no confirmed invoice or payment), payments recorded, billed, paid and owed per currency from confirmed invoices and payments (finance), up to five open deals (deals), how long each --context-query has been quiet on their side, and how much of each chat is held. Amounts, directions and promises found by words are marked pattern: read the cited message before trusting one. Others' questions in a group with no role, and others' word-found promises in a group, are counted on the chat's row as unlisted, not listed. next names at most two chats to read, with the messenger command that reads them. No model call; nothing leaves this machine").summary("where a project stands: whose move, open asks, money, chats to read next").argument("<project>", "an existing project's id, project:<id>, key, exact name or alias").option("--since-time <time>", "how far back: days (60d, at most 730d) or a start date (2026-09-01)", "60d").option("--before-time <time>", "fixed exclusive end: ISO 8601 timestamp with UTC offset; days back count from it").option("--context-query <words>", "words that all appear in one text; reports their last mention per side. Repeat for another", collect, []).option("--sync-profile <tool=profile>", "the messenger profile the next steps name when several are signed in to a chat's account, such as max=default; repeat for another tool", syncProfileOf).option("--purpose <purpose>", "the linked chats' purposes to read, comma-separated: work, sales, support, other, or all; default work", purposeList).addOption(annotateOption(new Option("--compact", "one line per signal, chat and next step, for an agent"), { mcp: false })).option("--json", "print JSON; --json=id,title keeps only those fields").action(async (project, options) => {
|
|
8692
9255
|
if (options.compact && options.json)
|
|
8693
9256
|
throw new CliError("validation_error", "--compact and --json ask for different output \u2014 pick one", {
|
|
8694
9257
|
reason: "output.conflict",
|
|
@@ -8696,8 +9259,10 @@ var projectStatusCommand = /* @__PURE__ */ __name((projects, print, env) => answ
|
|
|
8696
9259
|
});
|
|
8697
9260
|
const chosen = options.syncProfile ?? {};
|
|
8698
9261
|
const { found, finance, open: open2 } = await withStore(env, async (store) => {
|
|
9262
|
+
const scope = await groupScopeOf(store, env);
|
|
8699
9263
|
const status = await projectStatus(store, {
|
|
8700
9264
|
project,
|
|
9265
|
+
...scope === void 0 ? {} : { accounts: scope.accounts },
|
|
8701
9266
|
...projectWindowOf(options.sinceTime),
|
|
8702
9267
|
...options.beforeTime === void 0 ? {} : { asOf: projectCutoffTime(options.beforeTime) },
|
|
8703
9268
|
contextQueries: options.contextQuery,
|
|
@@ -8714,8 +9279,15 @@ var projectStatusCommand = /* @__PURE__ */ __name((projects, print, env) => answ
|
|
|
8714
9279
|
read: /* @__PURE__ */ __name((chat, since) => step("messages.list", chatRead(linked(chat), since, env, chosen)), "read"),
|
|
8715
9280
|
line: /* @__PURE__ */ __name((one2) => one2.kind === "command" ? one2.line ?? one2.command : one2.why, "line")
|
|
8716
9281
|
};
|
|
8717
|
-
const
|
|
8718
|
-
const
|
|
9282
|
+
const lock = groupLockOf(APP, env);
|
|
9283
|
+
const hidden = lock === void 0 ? [] : found.outOfScope.filter(({ reason }) => reason === "other-account");
|
|
9284
|
+
const shown3 = hidden.length ? { ...found, outOfScope: found.outOfScope.filter((one2) => !hidden.includes(one2)) } : found;
|
|
9285
|
+
const { item, next, missing, meta } = projectStatusAnswer(shown3, hints);
|
|
9286
|
+
const gaps = [
|
|
9287
|
+
...missing,
|
|
9288
|
+
...hidden.length ? [{ field: "out_of_scope", why: `${hidden.length} of the project's chats are outside group ${lock}` }] : [],
|
|
9289
|
+
...blocked.size ? [{ field: "next_command", why: [...blocked].join("; ") }] : []
|
|
9290
|
+
];
|
|
8719
9291
|
print(options.json, itemOf({
|
|
8720
9292
|
...item,
|
|
8721
9293
|
...finance.length ? { finance } : {},
|
|
@@ -8725,7 +9297,7 @@ var projectStatusCommand = /* @__PURE__ */ __name((projects, print, env) => answ
|
|
|
8725
9297
|
...next.length ? { next: next.map(asAction) } : {},
|
|
8726
9298
|
...gaps.length ? { missing: gaps } : {},
|
|
8727
9299
|
meta
|
|
8728
|
-
}), [projectStatusText(
|
|
9300
|
+
}), [projectStatusText(shown3, hints), ...financeText(finance), ...dealsText(open2)].join("\n"), options.compact === true);
|
|
8729
9301
|
}), "projectStatusCommand");
|
|
8730
9302
|
|
|
8731
9303
|
// dist/knowledge/project-transfer.js
|
|
@@ -8858,73 +9430,142 @@ var RELATIONSHIP_QUERY = {
|
|
|
8858
9430
|
entity: "relationship",
|
|
8859
9431
|
backend: "native",
|
|
8860
9432
|
fields: [
|
|
8861
|
-
termField("about", "ref", 'about:"
|
|
8862
|
-
relation: "the person, organization or
|
|
9433
|
+
termField("about", "ref", 'about:"person:5"', {
|
|
9434
|
+
relation: "the person, organization, project, deal or lead at either end; each row says its direction"
|
|
8863
9435
|
}),
|
|
8864
|
-
termField("
|
|
9436
|
+
termField("from", "ref", 'from:"person:5"', { relation: "the end that belongs, reports or relates" }),
|
|
9437
|
+
termField("to", "ref", 'to:"person:5"', { relation: "the end it belongs, reports or relates to" }),
|
|
9438
|
+
termField("kind", "enum", "kind:reports-to", { values: RELATION_KINDS }),
|
|
9439
|
+
termField("role", "kw", "role:decision-maker"),
|
|
9440
|
+
termField("standing", "enum", "standing:reported", { values: STANDINGS }),
|
|
9441
|
+
termField("confirmed", "enum", "confirmed:false", { values: ["true", "false"] }),
|
|
9442
|
+
termField("at", "kw", "at:2026-10-01", { relation: "held at the start of that UTC day" }),
|
|
9443
|
+
termField("include", "enum", "include:ended", { values: ["ended"] })
|
|
8865
9444
|
]
|
|
8866
9445
|
};
|
|
8867
|
-
var
|
|
8868
|
-
var
|
|
8869
|
-
const
|
|
8870
|
-
|
|
8871
|
-
|
|
8872
|
-
|
|
8873
|
-
|
|
8874
|
-
|
|
8875
|
-
|
|
8876
|
-
|
|
8877
|
-
one2.id,
|
|
8878
|
-
one2.payload ?? {}
|
|
8879
|
-
]));
|
|
8880
|
-
const rows = found.items.filter((row) => about === void 0 || row.subject === about || row.object === about);
|
|
8881
|
-
return {
|
|
8882
|
-
hasMore: found.hasMore,
|
|
8883
|
-
items: rows.map((row) => ({
|
|
8884
|
-
id: row.id,
|
|
8885
|
-
from: row.subject,
|
|
8886
|
-
to: row.object,
|
|
8887
|
-
kind: payloads.get(row.id)?.kind ?? null,
|
|
8888
|
-
role: row.summary,
|
|
8889
|
-
purpose: payloads.get(row.id)?.purpose ?? null,
|
|
8890
|
-
evidence: row.reason,
|
|
8891
|
-
confirmed: false,
|
|
8892
|
-
status: "proposed",
|
|
8893
|
-
proposer: proposerName(row.proposedBy),
|
|
8894
|
-
score: row.score,
|
|
8895
|
-
createdAt: row.createdAt
|
|
8896
|
-
}))
|
|
8897
|
-
};
|
|
8898
|
-
}, "pending");
|
|
8899
|
-
var listRelationships = /* @__PURE__ */ __name(async (store, words) => {
|
|
9446
|
+
var DAY9 = /^\d{4}-\d{2}-\d{2}$/;
|
|
9447
|
+
var atOf = /* @__PURE__ */ __name((day2) => {
|
|
9448
|
+
const at2 = Date.parse(`${day2}T00:00:00Z`);
|
|
9449
|
+
if (!DAY9.test(day2) || Number.isNaN(at2))
|
|
9450
|
+
throw new CliError("validation_error", `at: takes a day, such as at:2026-10-01 \u2014 not "${day2}"`, {
|
|
9451
|
+
reason: "input.invalid"
|
|
9452
|
+
});
|
|
9453
|
+
return at2;
|
|
9454
|
+
}, "atOf");
|
|
9455
|
+
var listRelationships = /* @__PURE__ */ __name(async (store, env, words, { limit, page, accounts, deniedKinds } = { limit: 100, page: 1 }) => {
|
|
8900
9456
|
const terms2 = queryTerms(words, RELATIONSHIP_QUERY, "relationships list");
|
|
8901
|
-
const about = terms2.get("about");
|
|
8902
9457
|
const confirmed = terms2.get("confirmed");
|
|
8903
|
-
const
|
|
8904
|
-
|
|
8905
|
-
|
|
8906
|
-
|
|
8907
|
-
|
|
9458
|
+
const standing = terms2.get("standing") ?? (confirmed === "false" ? "proposed" : confirmed === "true" ? "confirmed" : void 0);
|
|
9459
|
+
const at2 = terms2.get("at");
|
|
9460
|
+
const found = await store.knowledge.listRelations({
|
|
9461
|
+
...terms2.has("kind") ? { kind: terms2.get("kind") } : {},
|
|
9462
|
+
...terms2.has("role") ? { role: terms2.get("role") } : {},
|
|
9463
|
+
...terms2.has("from") ? { from: terms2.get("from") } : {},
|
|
9464
|
+
...terms2.has("to") ? { to: terms2.get("to") } : {},
|
|
9465
|
+
...terms2.has("about") ? { about: terms2.get("about") } : {},
|
|
9466
|
+
...standing === void 0 ? {} : { standing },
|
|
9467
|
+
...at2 === void 0 ? {} : { at: atOf(at2) },
|
|
9468
|
+
...terms2.get("include") === "ended" ? { includeEnded: true } : {},
|
|
9469
|
+
...accounts === void 0 ? {} : { accounts },
|
|
9470
|
+
...deniedKinds?.length ? { deniedKinds } : {},
|
|
9471
|
+
limit,
|
|
9472
|
+
page
|
|
9473
|
+
});
|
|
9474
|
+
const guard = await guardOf(store, env);
|
|
9475
|
+
const rows = [];
|
|
9476
|
+
for (const one2 of found.items)
|
|
9477
|
+
if (guard === void 0 || await guard.visible(one2.from) && await guard.visible(one2.to))
|
|
9478
|
+
rows.push(one2);
|
|
9479
|
+
const label = await labelsFor(store, rows.flatMap((one2) => [one2.from, one2.to]));
|
|
8908
9480
|
return {
|
|
8909
9481
|
hasMore: found.hasMore,
|
|
8910
|
-
limit
|
|
8911
|
-
|
|
9482
|
+
limit,
|
|
9483
|
+
page,
|
|
9484
|
+
items: await Promise.all(byEngagement(rows).map(async (one2) => ({
|
|
9485
|
+
...one2,
|
|
9486
|
+
status: one2.standing,
|
|
9487
|
+
// Who proposed it is the review's to name; the list says it beside the proposal.
|
|
9488
|
+
...one2.source === "proposal" ? { proposer: proposerName((await store.proposedActions.get(one2.id)).proposedBy) } : {},
|
|
9489
|
+
fromTitle: label(one2.from),
|
|
9490
|
+
toTitle: label(one2.to)
|
|
9491
|
+
})))
|
|
8912
9492
|
};
|
|
8913
9493
|
}, "listRelationships");
|
|
8914
9494
|
var relationshipsText = /* @__PURE__ */ __name((items) => items.length ? items.map((one2) => [
|
|
8915
9495
|
one2.id,
|
|
8916
9496
|
`${one2.fromTitle} \u2192 ${one2.toTitle}`,
|
|
8917
9497
|
[
|
|
8918
|
-
one2.kind,
|
|
8919
|
-
one2.role && `as ${one2.role}`,
|
|
9498
|
+
one2.direction === "incoming" ? one2.inverse ?? one2.kind : one2.kind,
|
|
9499
|
+
one2.role && `as ${one2.role}${one2.custom ? " (custom)" : ""}`,
|
|
8920
9500
|
"roleNote" in one2 && one2.roleNote && `(${one2.roleNote})`,
|
|
9501
|
+
one2.position && `(${one2.position})`,
|
|
8921
9502
|
one2.purpose && `for ${one2.purpose}`,
|
|
8922
9503
|
"engagement" in one2 && one2.engagement && `engagement ${one2.engagement}`
|
|
8923
9504
|
].filter(Boolean).join(" "),
|
|
8924
|
-
"proposer" in one2 ? `proposed by ${one2.proposer}` : one2.
|
|
9505
|
+
"proposer" in one2 ? `proposed by ${one2.proposer}` : [one2.standing, one2.account && `by ${one2.account}`].filter(Boolean).join(" ")
|
|
8925
9506
|
].filter(Boolean).join(" ")).join("\n") : "no relationships", "relationshipsText");
|
|
8926
9507
|
|
|
9508
|
+
// dist/knowledge/roles-command.js
|
|
9509
|
+
var LISTS = ["organization", "project", "deal"];
|
|
9510
|
+
var ROLES_QUERY = {
|
|
9511
|
+
entity: "relationship_role",
|
|
9512
|
+
backend: "native",
|
|
9513
|
+
fields: [termField("list", "enum", "list:organization", { values: LISTS })]
|
|
9514
|
+
};
|
|
9515
|
+
var LIST_HELP = "organization (roles in an organization), project or deal (a deal's or a lead's)";
|
|
9516
|
+
var ownerOnly = /* @__PURE__ */ __name(async (command, env, asOwner, question) => {
|
|
9517
|
+
if (await whoRuns(command, env, { asOwner, question }) !== "owner")
|
|
9518
|
+
throw new CliError("permission_error", "only the owner changes the role lists; an agent uses the roles they hold", {
|
|
9519
|
+
reason: "roles.owner-only"
|
|
9520
|
+
});
|
|
9521
|
+
}, "ownerOnly");
|
|
9522
|
+
var relationshipRolesCommand = /* @__PURE__ */ __name((relations, { print }, env) => {
|
|
9523
|
+
const roles = relations.command("roles").description("the roles a relationship may take: built in and your own");
|
|
9524
|
+
const rows = /* @__PURE__ */ __name(async (lists) => withStore(env, async (store) => (await Promise.all(lists.map(async (list) => (await store.knowledge.roles(list)).map((one2) => ({ list, ...one2 }))))).flat()), "rows");
|
|
9525
|
+
const show = /* @__PURE__ */ __name(async (json5, command, lists) => {
|
|
9526
|
+
const items = await rows(lists);
|
|
9527
|
+
print(json5, listAnswer(command, { items, limit: Math.max(1, items.length), has_more: false }), items.map(({ list, id, label, builtIn }) => `${list} ${id}${label ? ` ${label}` : ""}${builtIn ? "" : " (yours)"}`).join("\n"));
|
|
9528
|
+
}, "show");
|
|
9529
|
+
withQuery(annotate(roles.command("list"), { effects: LOCAL_READ, output: { entity: "relationship_role" } }), ROLES_QUERY).description("the roles of every list, or of one with list:organization, list:project or list:deal; each built in or yours").summary("the roles a relationship may take").option("--json", "print JSON; --json=id,title keeps only those fields").action((words, options) => {
|
|
9530
|
+
const list = queryTerms(words, ROLES_QUERY, "relationships roles list").get("list");
|
|
9531
|
+
return show(options.json, "relationships roles list", list === void 0 ? LISTS : [list]);
|
|
9532
|
+
});
|
|
9533
|
+
byOption(annotate(roles.command("add"), { effects: LOCAL_WRITE, output: { entity: "relationship_role" } }).description("add a role of your own to a list; relationships may then take it. Only you change the lists").summary("add a role of your own").argument("<list>", LIST_HELP, oneOf(LISTS)).argument("<role>", "the role's id: lowercase letters, digits and -, such as board-member").option("--label <label>", "how it reads, such as 'Board member'").option("--json", "print JSON; --json=id,title keeps only those fields")).action(async (list, role, options, command) => {
|
|
9534
|
+
await ownerOnly(command, env, options.asOwner, `add the ${list} role ${role} as you?`);
|
|
9535
|
+
await withStore(env, (store) => store.knowledge.addRole(list, role, options.label));
|
|
9536
|
+
await show(options.json, "relationships roles add", [list]);
|
|
9537
|
+
});
|
|
9538
|
+
byOption(annotate(roles.command("remove"), { effects: LOCAL_WRITE, output: { entity: "relationship_role" } }).description("remove a role of your own; a built-in one stays, and one a relationship still holds is refused").summary("remove a role of your own").argument("<list>", LIST_HELP, oneOf(LISTS)).argument("<role>", "the role's id").option("--json", "print JSON; --json=id,title keeps only those fields")).action(async (list, role, options, command) => {
|
|
9539
|
+
await ownerOnly(command, env, options.asOwner, `remove the ${list} role ${role} as you?`);
|
|
9540
|
+
await withStore(env, (store) => store.knowledge.removeRole(list, role));
|
|
9541
|
+
await show(options.json, "relationships roles remove", [list]);
|
|
9542
|
+
});
|
|
9543
|
+
}, "relationshipRolesCommand");
|
|
9544
|
+
|
|
8927
9545
|
// dist/knowledge/command.js
|
|
9546
|
+
var ROLE_HELP = `its role: in an organization ${ORGANIZATION_ROLES.join(", ")}; in a project ${PROJECT_ROLES.join(", ")}; on a deal or lead ${DEAL_ROLES.join(", ")}. A job title is not a role`;
|
|
9547
|
+
var ORGANIZATIONS_LIST_QUERY = {
|
|
9548
|
+
...ORGANIZATIONS_QUERY,
|
|
9549
|
+
fields: [
|
|
9550
|
+
...ORGANIZATIONS_QUERY.fields,
|
|
9551
|
+
termField("category", "enum", "category:client", {
|
|
9552
|
+
values: CATEGORIES,
|
|
9553
|
+
relation: "what its relationships with your own organizations, or yours with it, make it"
|
|
9554
|
+
})
|
|
9555
|
+
]
|
|
9556
|
+
};
|
|
9557
|
+
var categoryOf = /* @__PURE__ */ __name((words) => {
|
|
9558
|
+
const named5 = words.map((word) => /^category:(.+)$/.exec(word)?.[1]);
|
|
9559
|
+
const category = named5.find((one2) => one2 !== void 0);
|
|
9560
|
+
return { ...category === void 0 ? {} : { category }, rest: words.filter((_, at2) => named5[at2] === void 0) };
|
|
9561
|
+
}, "categoryOf");
|
|
9562
|
+
var dayOption = /* @__PURE__ */ __name((value) => {
|
|
9563
|
+
const at2 = Date.parse(`${value}T00:00:00Z`);
|
|
9564
|
+
if (!/^\d{4}-\d{2}-\d{2}$/.test(value) || Number.isNaN(at2))
|
|
9565
|
+
throw new InvalidArgumentError("a day, such as 2026-01-01");
|
|
9566
|
+
return at2;
|
|
9567
|
+
}, "dayOption");
|
|
9568
|
+
var lastDayOption = /* @__PURE__ */ __name((value) => dayOption(value) + 864e5, "lastDayOption");
|
|
8928
9569
|
var pendingLink = /* @__PURE__ */ __name(async (store, id) => {
|
|
8929
9570
|
try {
|
|
8930
9571
|
return await proposalRegistry(store).get(`link:${id}`);
|
|
@@ -8941,17 +9582,6 @@ var knowledgeCommands = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
8941
9582
|
const act = /* @__PURE__ */ __name((options, work) => run(options.json, async (store) => work(store, await writeAccount(store, env, options, warn))), "act");
|
|
8942
9583
|
const owned = /* @__PURE__ */ __name((options, work) => run(options.json, async (store) => itemAnswer(await work(store))), "owned");
|
|
8943
9584
|
const ownedList = /* @__PURE__ */ __name((command, options, work) => run(options.json, async (store) => wholeList(command, await work(store))), "ownedList");
|
|
8944
|
-
const contextOf = /* @__PURE__ */ __name(async (store, thing, type, reference2) => {
|
|
8945
|
-
if (thing === void 0)
|
|
8946
|
-
throw new CliError("not_found", `no ${type} ${reference2}; memo ${type}s list shows them`);
|
|
8947
|
-
const { id } = thing;
|
|
8948
|
-
return {
|
|
8949
|
-
[type]: thing,
|
|
8950
|
-
relationships: (await store.notes.links({ to: `${type}:${id}` })).concat(await store.notes.links({ from: `${type}:${id}` })).filter((link2) => link2.kind !== "about" && link2.kind !== "links-to" && link2.role !== "key"),
|
|
8951
|
-
notes: await notesAbout(store, { ref: `${type}:${id}` }),
|
|
8952
|
-
tags: await store.knowledge.tags(null, { type, id })
|
|
8953
|
-
};
|
|
8954
|
-
}, "contextOf");
|
|
8955
9585
|
const organizations = program.command("organizations").description("companies, teams, families and communities of yours");
|
|
8956
9586
|
annotate(organizations.command("add"), { effects: LOCAL_WRITE, literal_after_dashes: true }).description("add an organization of yours: a company, team, family or community; it is written at once, whoever runs it").summary("add an organization").argument("<name>", "the organization's name").requiredOption("--kind <kind>", ORGANIZATION_KINDS.join(", "), oneOf(ORGANIZATION_KINDS)).option("--scope <scope>", SCOPES.join(", "), oneOf(SCOPES)).option("--json", "print JSON; --json=id,title keeps only those fields").action((name2, options) => owned(options, (store) => store.knowledge.addOrganization({
|
|
8957
9587
|
kind: options.kind,
|
|
@@ -8966,14 +9596,38 @@ var knowledgeCommands = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
8966
9596
|
throw new CliError("not_found", `no organization ${reference2}; memo organizations list shows them`);
|
|
8967
9597
|
return found;
|
|
8968
9598
|
}));
|
|
8969
|
-
withQuery(annotate(organizations.command("list"), { effects: LOCAL_READ }),
|
|
8970
|
-
const
|
|
8971
|
-
|
|
9599
|
+
withQuery(annotate(organizations.command("list"), { effects: LOCAL_READ }), ORGANIZATIONS_LIST_QUERY).description("your organizations; category:client, supplier, partner or employer keeps those its relationships make so").summary("your organizations").option("--json", "print JSON; --json=id,title keeps only those fields").action((words, options) => {
|
|
9600
|
+
const { category, rest } = categoryOf(words);
|
|
9601
|
+
const query = listQuery(typedQuery(rest), ORGANIZATIONS_QUERY, "organizations list");
|
|
9602
|
+
return ownedList("organizations list", options, async (store) => {
|
|
9603
|
+
const scope = await groupScopeOf(store, env);
|
|
9604
|
+
const found = await store.knowledge.organizations(query, {
|
|
9605
|
+
...category === void 0 ? {} : { category },
|
|
9606
|
+
...scope === void 0 ? {} : { accounts: scope.accounts }
|
|
9607
|
+
});
|
|
9608
|
+
return keepInGroup(store, env, found, ({ ref }) => ref);
|
|
9609
|
+
});
|
|
9610
|
+
});
|
|
9611
|
+
annotate(organizations.command("context"), {
|
|
9612
|
+
effects: LOCAL_READ,
|
|
9613
|
+
output: { entity: "organization_context_memo" }
|
|
9614
|
+
}).description("one organization by its id or organization:<id>: its people by role, customers, suppliers and partners, projects, open deals and leads, invoices, payments and orders, how much its people wrote, open tasks and categories, each relationship with its standing; then the notes about it and its tags. `coverage` names what was not read").summary("one organization: people, customers, deals, money, tasks, notes").argument("<organization>", "its id or organization:<id>").option("--limit <n>", "most items in each section", positive, 20).option("--json", "print JSON; --json=id,title keeps only those fields").action(async (reference2, options, command) => {
|
|
9615
|
+
const answer = await withStore(env, async (store) => {
|
|
9616
|
+
const scope = await groupScopeOf(store, env);
|
|
9617
|
+
const found = await organizationContext(store, reference2, {
|
|
9618
|
+
limit: options.limit,
|
|
9619
|
+
...scope === void 0 ? {} : { accounts: scope.accounts },
|
|
9620
|
+
deniedKinds: deniedCrmKinds(command, env)
|
|
9621
|
+
});
|
|
9622
|
+
const ref = found.organization.ref;
|
|
9623
|
+
return lockedCoverage(store, env, {
|
|
9624
|
+
...found,
|
|
9625
|
+
notes: await notesAbout(store, { ref }),
|
|
9626
|
+
tags: await store.knowledge.tags(null, { type: "organization", id: ref.slice("organization:".length) })
|
|
9627
|
+
});
|
|
9628
|
+
});
|
|
9629
|
+
print(options.json, itemAnswer(answer), organizationText(answer));
|
|
8972
9630
|
});
|
|
8973
|
-
annotate(organizations.command("context"), { effects: LOCAL_READ }).description("one organization by its id or organization:<id>: its relationships, the notes about or linking it, and its tags").summary("one organization: its relationships, notes and tags").argument("<organization>", "its id or organization:<id>").option("--json", "print JSON; --json=id,title keeps only those fields").action((reference2, options) => owned(options, async (store) => {
|
|
8974
|
-
const wanted = reference2.replace(/^organization:/, "");
|
|
8975
|
-
return contextOf(store, (await store.knowledge.organizations()).find((organization) => organization.id === wanted), "organization", reference2);
|
|
8976
|
-
}));
|
|
8977
9631
|
const projects = program.command("projects").description("projects of yours, each with a short key");
|
|
8978
9632
|
meetingProjectsCommand(projects, streams, env);
|
|
8979
9633
|
annotate(projects.command("add"), { effects: LOCAL_WRITE, literal_after_dashes: true }).description("add a project of yours, with a short key its tasks use").argument("<name>", "the project's name").option("--key <key>", "3\u20134 letters and digits; made from the name when left out").option("--type <type>", PROJECT_TYPES.join(", "), oneOf(PROJECT_TYPES)).option("--organization <organization>", "the organization it belongs to: its id or organization:<id>").option("--scope <scope>", SCOPES.join(", "), oneOf(SCOPES)).option("--json", "print JSON; --json=id,title keeps only those fields").action((name2, options) => owned(options, (store) => store.knowledge.addProject({
|
|
@@ -8989,7 +9643,7 @@ var knowledgeCommands = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
8989
9643
|
});
|
|
8990
9644
|
annotate(projects.command("context"), { effects: LOCAL_READ }).description("one project by its id, project:<id>, key, exact name or alias: its key documents first, then its relationships, notes, tags, pending findings and open tasks. Review proposals together; nothing is confirmed. `review.waiting` counts what waits for you, by kind, and `next` names the command that lists them").summary("one project: key documents, pending findings and open tasks; start work here").argument("<project>", "its id, project:<id>, key, exact name or alias").option("--json", "print JSON; --json=id,title keeps only those fields").action(async (reference2, options) => {
|
|
8991
9645
|
const { context, next } = await withStore(env, async (store) => {
|
|
8992
|
-
const context2 = await projectContext(store, env, reference2);
|
|
9646
|
+
const context2 = await stripped(store, env, await projectContext(store, env, reference2));
|
|
8993
9647
|
return { context: context2, next: await scanStep(store, context2.project, "all") };
|
|
8994
9648
|
});
|
|
8995
9649
|
print(options.json, itemAnswer(context, next.length ? { next } : {}), projectContextText(context));
|
|
@@ -9012,7 +9666,7 @@ var knowledgeCommands = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
9012
9666
|
return ownedList("projects key-documents list", options, async (store) => keyDocuments(store, await projectOf(store, project), id === void 0 ? {} : { id }));
|
|
9013
9667
|
});
|
|
9014
9668
|
const relations = program.command("relationships").description("relations between people, organizations and projects; never between identities");
|
|
9015
|
-
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>", "
|
|
9669
|
+
byOption(annotate(relations.command("add"), { effects: LOCAL_WRITE }).description("state that a person, organization or project belongs to, reports to, is a customer or partner of, 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>", RELATION_KINDS.join(", "), oneOf(RELATION_KINDS), "member-of").option("--role <role>", ROLE_HELP).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("--position <title>", "the job title, such as 'Procurement manager'; kept apart from the role").option("--start-date <date>", "the first day it held, such as 2026-01-01", dayOption).option("--end-date <date>", "the last day it held, included; it ends at the start of the day after", lastDayOption).option("--reason <text>", "why you think so, in a sentence").action(async (from, to, options, command) => {
|
|
9016
9670
|
const by = await whoRuns(command, env, { asOwner: options.asOwner, question: "state it as yours?" });
|
|
9017
9671
|
return owned(options, async (store) => {
|
|
9018
9672
|
const input = {
|
|
@@ -9022,27 +9676,46 @@ var knowledgeCommands = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
9022
9676
|
...options.role === void 0 ? {} : { role: options.role },
|
|
9023
9677
|
...options.roleNote === void 0 ? {} : { roleNote: options.roleNote },
|
|
9024
9678
|
...options.engagement === void 0 ? {} : { engagement: options.engagement },
|
|
9679
|
+
...options.position === void 0 ? {} : { position: options.position },
|
|
9680
|
+
...options.startDate === void 0 ? {} : { startsAt: options.startDate },
|
|
9681
|
+
...options.endDate === void 0 ? {} : { endsAt: options.endDate },
|
|
9025
9682
|
...options.reason === void 0 ? {} : { evidence: options.reason }
|
|
9026
9683
|
};
|
|
9027
9684
|
return by === "owner" ? store.knowledge.relate(null, { ...input, by }) : store.knowledge.relate(null, { ...input, by });
|
|
9028
9685
|
});
|
|
9029
9686
|
});
|
|
9030
|
-
withQuery(annotate(relations.command("list"), { effects: LOCAL_READ }).description("relationships, all or those of one reference, with titles; confirmed:false lists the proposals waiting for you, as memo review kind:relationship does").summary("relationships with titles; confirmed:false lists those waiting for you"), RELATIONSHIP_QUERY).option("--json", "print JSON; --json=id,title keeps only those fields").action(async (words, options) => {
|
|
9031
|
-
const found = await withStore(env, (store) =>
|
|
9032
|
-
|
|
9687
|
+
withQuery(annotate(relations.command("list"), { effects: LOCAL_READ }).description("relationships, all or those of one reference, with titles; confirmed:false lists the proposals waiting for you, as memo review kind:relationship does").summary("relationships with titles; confirmed:false lists those waiting for you"), RELATIONSHIP_QUERY).option("--limit <n>", "most relationships, up to 500", (value) => Math.min(positive(value), 500), 100).option("--page <n>", "which page, from 1", positive, 1).option("--json", "print JSON; --json=id,title keeps only those fields").action(async (words, options, command) => {
|
|
9688
|
+
const found = await withStore(env, async (store) => {
|
|
9689
|
+
const scope = await groupScopeOf(store, env);
|
|
9690
|
+
return listRelationships(store, env, words, {
|
|
9691
|
+
limit: options.limit,
|
|
9692
|
+
page: options.page,
|
|
9693
|
+
...scope === void 0 ? {} : { accounts: scope.accounts },
|
|
9694
|
+
deniedKinds: deniedCrmKinds(command, env)
|
|
9695
|
+
});
|
|
9696
|
+
});
|
|
9697
|
+
print(options.json, listAnswer("relationships list", {
|
|
9698
|
+
items: found.items,
|
|
9699
|
+
limit: found.limit,
|
|
9700
|
+
has_more: found.hasMore,
|
|
9701
|
+
page: found.page,
|
|
9702
|
+
args: { query: words.join(" ") }
|
|
9703
|
+
}), relationshipsText(found.items));
|
|
9033
9704
|
});
|
|
9034
|
-
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>",
|
|
9705
|
+
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>", `${ROLE_HELP}; 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("--position <title>", "the job title; an empty value clears it").option("--start-date <date>", "the first day it held, such as 2026-01-01", dayOption).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) => {
|
|
9035
9706
|
const cleared = /* @__PURE__ */ __name((value) => value === "" ? null : value, "cleared");
|
|
9036
9707
|
const change = {
|
|
9037
9708
|
...options.role === void 0 ? {} : { role: cleared(options.role) },
|
|
9038
9709
|
...options.roleNote === void 0 ? {} : { roleNote: cleared(options.roleNote) },
|
|
9039
9710
|
...options.engagement === void 0 ? {} : { engagement: cleared(options.engagement) },
|
|
9711
|
+
...options.position === void 0 ? {} : { position: cleared(options.position) },
|
|
9712
|
+
...options.startDate === void 0 ? {} : { startsAt: options.startDate },
|
|
9040
9713
|
...options.purpose === void 0 ? {} : { purpose: options.purpose }
|
|
9041
9714
|
};
|
|
9042
9715
|
const by = await whoRuns(command, env, { asOwner: options.asOwner, question: `change relationship ${id}?` });
|
|
9043
|
-
return owned(options, (store) => {
|
|
9044
|
-
if (
|
|
9045
|
-
throw new CliError("validation_error", "say what to change: --role, --role-note, --engagement or --purpose", {
|
|
9716
|
+
return owned(options, async (store) => {
|
|
9717
|
+
if (Object.keys(change).length === 0)
|
|
9718
|
+
throw new CliError("validation_error", "say what to change: --role, --role-note, --engagement, --position, --start-date or --purpose", {
|
|
9046
9719
|
reason: "input.invalid",
|
|
9047
9720
|
param: "--purpose"
|
|
9048
9721
|
});
|
|
@@ -9068,12 +9741,20 @@ var knowledgeCommands = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
9068
9741
|
const suggestion = await pendingLink(store, id);
|
|
9069
9742
|
if (suggestion === void 0)
|
|
9070
9743
|
return name2 === "remove" ? store.knowledge.removeRelation(null, id, by) : store.knowledge.confirmRelation(null, id, by);
|
|
9071
|
-
await decideOne(store, suggestion.id, decisionOf(name2 === "confirm", by, options.reason));
|
|
9744
|
+
await decideOne(store, env, suggestion.id, decisionOf(name2 === "confirm", by, options.reason));
|
|
9072
9745
|
if (name2 === "remove")
|
|
9073
9746
|
return { id, removed: true };
|
|
9074
9747
|
return (await store.knowledge.relations(null, suggestion.subject)).find((one2) => one2.id === id);
|
|
9075
9748
|
});
|
|
9076
9749
|
});
|
|
9750
|
+
byOption(annotate(relations.command("end"), { effects: LOCAL_WRITE }).description("say that a relationship no longer holds, from a day on; it stays, as ended, and relationships list include:ended shows it. An agent's waits for you in memo review").summary("say that a relationship ended").argument("<id>", "the relationship's id, as relationships list gives it").option("--end-date <date>", "the last day it held, included; it ends at the start of the day after. Today when left out", lastDayOption).option("--json", "print JSON; --json=id,title keeps only those fields")).action(async (id, options, command) => {
|
|
9751
|
+
const by = await whoRuns(command, env, { asOwner: options.asOwner, question: `end relationship ${id}?` });
|
|
9752
|
+
const at2 = options.endDate ?? Date.now();
|
|
9753
|
+
return owned(options, async (store) => {
|
|
9754
|
+
return by === "owner" ? store.knowledge.endRelation(null, id, at2, by) : store.knowledge.endRelation(null, id, at2, by);
|
|
9755
|
+
});
|
|
9756
|
+
});
|
|
9757
|
+
relationshipRolesCommand(relations, { print }, env);
|
|
9077
9758
|
relationshipsScanCommand(relations, print, env, warn);
|
|
9078
9759
|
const reminders = program.command("reminders").description("durable local reminders; poll hands one out and ack confirms it was shown");
|
|
9079
9760
|
writeScope(annotate(reminders.command("add"), { effects: LOCAL_WRITE }).description("add a reminder for an open task").argument("<task>", "the task's id")).requiredOption("--at-time <time>", "when to remind: an ISO 8601 time with its UTC offset").option("--timezone <zone>", "IANA timezone; the computer's when not given").action((task, options) => act(options, async (store, key) => {
|
|
@@ -9506,9 +10187,9 @@ var messagesCommand = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
9506
10187
|
}, "messagesCommand");
|
|
9507
10188
|
|
|
9508
10189
|
// dist/mcp/command.js
|
|
9509
|
-
import { join as
|
|
10190
|
+
import { join as join9 } from "node:path";
|
|
9510
10191
|
var DEFAULT_PORT = 8767;
|
|
9511
|
-
var httpTokenFile = /* @__PURE__ */ __name((env) =>
|
|
10192
|
+
var httpTokenFile = /* @__PURE__ */ __name((env) => join9(resolvePaths({ appName: APP.appName, prefix: APP.envPrefix, env }).state, "mcp-http", "memo.json"), "httpTokenFile");
|
|
9512
10193
|
var mcpCommandDefinition = /* @__PURE__ */ __name((program, streams, env, createProgram2) => {
|
|
9513
10194
|
const out = answers(program, streams, env);
|
|
9514
10195
|
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,10 +10201,10 @@ var mcpCommandDefinition = /* @__PURE__ */ __name((program, streams, env, create
|
|
|
9520
10201
|
}).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
10202
|
if (!options.http && (options.port !== void 0 || options.publicUrl !== void 0))
|
|
9522
10203
|
throw new CliError("validation_error", "--port and --public-url require --http");
|
|
9523
|
-
const { createMemoServer } = await import("./server-
|
|
10204
|
+
const { createMemoServer } = await import("./server-LWQAHDBH.js");
|
|
9524
10205
|
const build = /* @__PURE__ */ __name(() => createMemoServer(env, createProgram2, options.permission), "build");
|
|
9525
10206
|
if (options.http) {
|
|
9526
|
-
const { httpLockFile, mcpUrlOf, portOf, publicUrlOf, serveOverHttp } = await import("./mcp-
|
|
10207
|
+
const { httpLockFile, mcpUrlOf, portOf, publicUrlOf, serveOverHttp } = await import("./mcp-FQPK2KAF.js");
|
|
9527
10208
|
const publicUrl = publicUrlOf(options.publicUrl, {
|
|
9528
10209
|
missing: "--http",
|
|
9529
10210
|
reaches: "the browser apps reach memo",
|
|
@@ -9575,7 +10256,7 @@ var mcpCommandDefinition = /* @__PURE__ */ __name((program, streams, env, create
|
|
|
9575
10256
|
});
|
|
9576
10257
|
});
|
|
9577
10258
|
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() {
|
|
9578
|
-
const { revokeAll } = await import("./mcp-
|
|
10259
|
+
const { revokeAll } = await import("./mcp-FQPK2KAF.js");
|
|
9579
10260
|
revokeAll(httpTokenFile(env));
|
|
9580
10261
|
out.print(this.opts().json, itemAnswer({ revoked: true }));
|
|
9581
10262
|
});
|
|
@@ -9850,7 +10531,7 @@ may be ${found.candidates.join(", ")}` : ""));
|
|
|
9850
10531
|
}, "mentionsCommand");
|
|
9851
10532
|
|
|
9852
10533
|
// dist/models/command.js
|
|
9853
|
-
var modelsCommand = /* @__PURE__ */ __name((program, streams, env, keyring) => {
|
|
10534
|
+
var modelsCommand = /* @__PURE__ */ __name((program, streams, env, keyring, stdin) => {
|
|
9854
10535
|
const { print } = answers(program, streams, env);
|
|
9855
10536
|
program.addCommand(modelCatalogueCommand(APP, {
|
|
9856
10537
|
kinds: ["text"],
|
|
@@ -9859,6 +10540,7 @@ var modelsCommand = /* @__PURE__ */ __name((program, streams, env, keyring) => {
|
|
|
9859
10540
|
jsonOption: true,
|
|
9860
10541
|
env: /* @__PURE__ */ __name(() => env, "env"),
|
|
9861
10542
|
...keyring ? { keyring } : {},
|
|
10543
|
+
...stdin ? { stdin: /* @__PURE__ */ __name(() => stdin, "stdin") } : {},
|
|
9862
10544
|
output: /* @__PURE__ */ __name((body, command) => print(command.optsWithGlobals().json, body), "output"),
|
|
9863
10545
|
diagnostic: /* @__PURE__ */ __name((line3) => streams.diagnostic(line3), "diagnostic"),
|
|
9864
10546
|
offline: /* @__PURE__ */ __name(() => program.opts().offline === true, "offline")
|
|
@@ -9866,7 +10548,7 @@ var modelsCommand = /* @__PURE__ */ __name((program, streams, env, keyring) => {
|
|
|
9866
10548
|
}, "modelsCommand");
|
|
9867
10549
|
|
|
9868
10550
|
// dist/notes/command.js
|
|
9869
|
-
import { readFileSync as
|
|
10551
|
+
import { readFileSync as readFileSync9 } from "node:fs";
|
|
9870
10552
|
|
|
9871
10553
|
// dist/people/identity.js
|
|
9872
10554
|
var identityOf = /* @__PURE__ */ __name(async (store, reference2) => {
|
|
@@ -9904,8 +10586,8 @@ import { resolve as resolve3 } from "node:path";
|
|
|
9904
10586
|
|
|
9905
10587
|
// dist/notes/export.js
|
|
9906
10588
|
import { createHash as createHash3 } from "node:crypto";
|
|
9907
|
-
import { existsSync as
|
|
9908
|
-
import { join as
|
|
10589
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync3, readdirSync as readdirSync6, readFileSync as readFileSync8, renameSync as renameSync2, writeFileSync as writeFileSync4 } from "node:fs";
|
|
10590
|
+
import { join as join10 } from "node:path";
|
|
9909
10591
|
var HASH_LINE = /^memo-hash: .*\r?\n/m;
|
|
9910
10592
|
var PLACEHOLDER = "f".repeat(64);
|
|
9911
10593
|
var UNSAFE = /[\\/:*?"<>|#^[\]\p{Cc}]/gu;
|
|
@@ -9929,7 +10611,7 @@ var exportedIn = /* @__PURE__ */ __name((dir) => {
|
|
|
9929
10611
|
for (const entry of readdirSync6(dir, { withFileTypes: true })) {
|
|
9930
10612
|
if (!entry.isFile() || !/\.(md|markdown)$/i.test(entry.name))
|
|
9931
10613
|
continue;
|
|
9932
|
-
const id = readMemoId(
|
|
10614
|
+
const id = readMemoId(join10(dir, entry.name));
|
|
9933
10615
|
if (id !== null)
|
|
9934
10616
|
found.set(id, entry.name);
|
|
9935
10617
|
}
|
|
@@ -9946,11 +10628,11 @@ var exportNotes = /* @__PURE__ */ __name(({ dir, dialect, notes: notes2 }) => {
|
|
|
9946
10628
|
frontMatter["memo-hash"] = PLACEHOLDER;
|
|
9947
10629
|
const content = withHash(dialect.render({ ...note, frontMatter }));
|
|
9948
10630
|
const known2 = existing.get(id);
|
|
9949
|
-
const name2 = known2 ?? fileName(note.title, id, (candidate) => claimed.has(candidate) ||
|
|
10631
|
+
const name2 = known2 ?? fileName(note.title, id, (candidate) => claimed.has(candidate) || existsSync9(join10(dir, candidate)));
|
|
9950
10632
|
claimed.add(name2);
|
|
9951
|
-
const path =
|
|
10633
|
+
const path = join10(dir, name2);
|
|
9952
10634
|
if (known2 !== void 0) {
|
|
9953
|
-
const current =
|
|
10635
|
+
const current = readFileSync8(path, "utf8");
|
|
9954
10636
|
if (editedSinceExport(current)) {
|
|
9955
10637
|
result.edited.push({ path, id });
|
|
9956
10638
|
continue;
|
|
@@ -9960,8 +10642,8 @@ var exportNotes = /* @__PURE__ */ __name(({ dir, dialect, notes: notes2 }) => {
|
|
|
9960
10642
|
continue;
|
|
9961
10643
|
}
|
|
9962
10644
|
}
|
|
9963
|
-
const partial =
|
|
9964
|
-
|
|
10645
|
+
const partial = join10(dir, `.${name2}.memo-tmp`);
|
|
10646
|
+
writeFileSync4(partial, content);
|
|
9965
10647
|
renameSync2(partial, path);
|
|
9966
10648
|
result.written.push(path);
|
|
9967
10649
|
}
|
|
@@ -10061,7 +10743,7 @@ var textOf = /* @__PURE__ */ __name((options, given2) => {
|
|
|
10061
10743
|
if (sources.length !== 1)
|
|
10062
10744
|
throw new CliError("validation_error", "give the text once: as an argument, --text or --text-file");
|
|
10063
10745
|
if (options.textFile !== void 0)
|
|
10064
|
-
return
|
|
10746
|
+
return readFileSync9(options.textFile === "-" ? 0 : options.textFile, "utf8");
|
|
10065
10747
|
return sources[0];
|
|
10066
10748
|
}, "textOf");
|
|
10067
10749
|
var noteOf = /* @__PURE__ */ __name(async (store, env, reference2) => {
|
|
@@ -10129,11 +10811,14 @@ var notesCommandDefinition = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
10129
10811
|
if (about !== void 0 && terms2.size > 1)
|
|
10130
10812
|
throw new CliError("validation_error", "about: stands alone in notes list: its notes are found through links");
|
|
10131
10813
|
const options = { ...paging, json: json5 };
|
|
10132
|
-
const page = await withNotes(async (store) =>
|
|
10133
|
-
|
|
10134
|
-
|
|
10135
|
-
|
|
10136
|
-
|
|
10814
|
+
const page = await withNotes(async (store) => {
|
|
10815
|
+
const found = await listNotes(store, {
|
|
10816
|
+
limit: options.limit,
|
|
10817
|
+
offset: (options.page - 1) * options.limit,
|
|
10818
|
+
...about === void 0 ? { ...source === void 0 ? {} : { source }, ...search2 === void 0 ? {} : { search: search2 } } : { about: await subjectOf(store, about) }
|
|
10819
|
+
});
|
|
10820
|
+
return { ...found, items: await keepInGroup(store, env, found.items, ({ ref }) => ref) };
|
|
10821
|
+
});
|
|
10137
10822
|
print(options.json, listAnswer("notes list", {
|
|
10138
10823
|
items: page.items,
|
|
10139
10824
|
limit: options.limit,
|
|
@@ -10156,7 +10841,7 @@ var notesCommandDefinition = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
10156
10841
|
const answer = await withNotes(async (store) => {
|
|
10157
10842
|
const about = await Promise.all((options.subject ?? []).map(async (subject) => (await subjectOf(store, subject)).ref));
|
|
10158
10843
|
if (options.meeting !== void 0)
|
|
10159
|
-
about.push(await meetingReference(store, options.meeting, value === void 0 ? {} : await oneAccountOf(store, env, value, "--account")));
|
|
10844
|
+
about.push(await meetingReference(store, env, options.meeting, value === void 0 ? {} : await oneAccountOf(store, env, value, "--account")));
|
|
10160
10845
|
const note = await store.notes.addNote({
|
|
10161
10846
|
text: body,
|
|
10162
10847
|
about,
|
|
@@ -10217,9 +10902,9 @@ import { statSync as statSync4 } from "node:fs";
|
|
|
10217
10902
|
import { basename as basename2, resolve as resolve4 } from "node:path";
|
|
10218
10903
|
|
|
10219
10904
|
// dist/run/lock.js
|
|
10220
|
-
import { join as
|
|
10905
|
+
import { join as join11 } from "node:path";
|
|
10221
10906
|
var withImportLock = /* @__PURE__ */ __name(async (env, work) => {
|
|
10222
|
-
const lock =
|
|
10907
|
+
const lock = join11(resolvePaths({ appName: "cli-memo", prefix: "MEMO", env }).state, "import.lock");
|
|
10223
10908
|
const holder = takeLock(lock, { pid: process.pid, startedAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
10224
10909
|
if (holder !== void 0)
|
|
10225
10910
|
throw new CliError("rate_limited", `another memo sync is running (process ${holder.pid}); try again when it ends`, {
|
|
@@ -10240,15 +10925,15 @@ var formatOf2 = /* @__PURE__ */ __name((value) => {
|
|
|
10240
10925
|
return value;
|
|
10241
10926
|
}, "formatOf");
|
|
10242
10927
|
var directory = /* @__PURE__ */ __name((path) => {
|
|
10243
|
-
const
|
|
10928
|
+
const at2 = resolve4(path);
|
|
10244
10929
|
let isDirectory = false;
|
|
10245
10930
|
try {
|
|
10246
|
-
isDirectory = statSync4(
|
|
10931
|
+
isDirectory = statSync4(at2).isDirectory();
|
|
10247
10932
|
} catch {
|
|
10248
10933
|
}
|
|
10249
10934
|
if (!isDirectory)
|
|
10250
|
-
throw new CliError("not_found", `${
|
|
10251
|
-
return
|
|
10935
|
+
throw new CliError("not_found", `${at2} is not a folder`);
|
|
10936
|
+
return at2;
|
|
10252
10937
|
}, "directory");
|
|
10253
10938
|
var FOLDERS_QUERY = { entity: "notes_folder", backend: "native", fields: [] };
|
|
10254
10939
|
var keptByDrive = /* @__PURE__ */ __name((name2) => name2.startsWith("google-drive:"), "keptByDrive");
|
|
@@ -10261,10 +10946,10 @@ var foldersCommand = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
10261
10946
|
const { print } = answers(program, streams, env);
|
|
10262
10947
|
const folders = program.command("folders").description("folders of notes: the id links and the store use, and the path on this computer");
|
|
10263
10948
|
grantsAuthority(annotate(folders.command("add"), { effects: LOCAL_WRITE })).description("give a folder of notes an id, or show the one it has").argument("<path>", "the folder on this computer").option("--format <format>", `how its notes are written: ${DIALECTS.join(", ")} (default: obsidian)`, formatOf2).option("--json", "print JSON; --json=id,title keeps only those fields").action(async (path, options) => {
|
|
10264
|
-
const
|
|
10949
|
+
const at2 = directory(path);
|
|
10265
10950
|
const answer = await withStore(env, async (store) => {
|
|
10266
10951
|
const known2 = new Set((await store.notes.folders()).map(({ id }) => id));
|
|
10267
|
-
const current = noteFolders(loadConfig(env).notes).find((folder2) => folder2.path ===
|
|
10952
|
+
const current = noteFolders(loadConfig(env).notes).find((folder2) => folder2.path === at2);
|
|
10268
10953
|
if (current?.id && known2.has(current.id)) {
|
|
10269
10954
|
const folder2 = { ...current, id: current.id, format: options.format ?? current.format };
|
|
10270
10955
|
if (folder2.format !== current.format)
|
|
@@ -10272,15 +10957,15 @@ var foldersCommand = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
10272
10957
|
return { ...folder2, created: false };
|
|
10273
10958
|
}
|
|
10274
10959
|
const format = options.format ?? current?.format ?? "obsidian";
|
|
10275
|
-
const made = await store.notes.addFolder({ name: basename2(
|
|
10276
|
-
const folder = { id: made.id, path:
|
|
10960
|
+
const made = await store.notes.addFolder({ name: basename2(at2) || at2, format });
|
|
10961
|
+
const folder = { id: made.id, path: at2, format };
|
|
10277
10962
|
updateConfig((config) => bindFolder(config, folder), env);
|
|
10278
10963
|
return { ...folder, created: true };
|
|
10279
10964
|
});
|
|
10280
10965
|
print(options.json, itemAnswer(answer), answer.id);
|
|
10281
10966
|
});
|
|
10282
10967
|
grantsAuthority(annotate(folders.command("update"), { effects: LOCAL_WRITE })).description("bind a folder id from another computer to the folder's path on this one").argument("<id>", "the folder's id, as memo folders add printed it").argument("<path>", "the same folder on this computer").option("--format <format>", `how its notes are written: ${DIALECTS.join(", ")}`, formatOf2).option("--json", "print JSON; --json=id,title keeps only those fields").action(async (id, path, options) => {
|
|
10283
|
-
const
|
|
10968
|
+
const at2 = directory(path);
|
|
10284
10969
|
const folder = await withStore(env, async (store) => {
|
|
10285
10970
|
const stored = (await storedFolders(store)).find((candidate) => candidate.id === id);
|
|
10286
10971
|
if (!stored)
|
|
@@ -10291,7 +10976,7 @@ var foldersCommand = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
10291
10976
|
throw new CliError("validation_error", `folder ${id} is Google Drive's (${stored.name}) \u2014 drive keeps it, and memo search already reads it`);
|
|
10292
10977
|
let bound;
|
|
10293
10978
|
updateConfig((config) => {
|
|
10294
|
-
const result = attachFolder(config, id,
|
|
10979
|
+
const result = attachFolder(config, id, at2, options.format ?? stored.format);
|
|
10295
10980
|
bound = result.folder;
|
|
10296
10981
|
return result.config;
|
|
10297
10982
|
}, env);
|
|
@@ -10350,7 +11035,7 @@ var foldersCommand = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
10350
11035
|
}, "foldersCommand");
|
|
10351
11036
|
|
|
10352
11037
|
// dist/people/command.js
|
|
10353
|
-
import { join as
|
|
11038
|
+
import { join as join12 } from "node:path";
|
|
10354
11039
|
var noteCommand = /* @__PURE__ */ __name((program, streams, env) => {
|
|
10355
11040
|
const notes2 = program.commands.find((command) => command.name() === "notes") ?? program.command("notes");
|
|
10356
11041
|
const links = notes2.command("links").description("imported note files linked to the person behind an identity");
|
|
@@ -10403,7 +11088,7 @@ var noteCommand = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
10403
11088
|
}
|
|
10404
11089
|
const paths = (await files()).map(({ note }) => {
|
|
10405
11090
|
const folder = folders.find((candidate) => candidate.id === note.folderId);
|
|
10406
|
-
return folder ?
|
|
11091
|
+
return folder ? join12(folder.path, note.path) : note.ref;
|
|
10407
11092
|
});
|
|
10408
11093
|
return { person: to, name: person.name ?? person.uid, files: paths };
|
|
10409
11094
|
});
|
|
@@ -10424,7 +11109,7 @@ var peopleCommand = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
10424
11109
|
withQuery(annotate(people.command("list"), { effects: LOCAL_READ }).summary("everyone memo knows, the owner first").description("everyone memo knows, by name: the owner first, then by how many tasks name them"), query).option("--limit <n>", "most people, up to 5000", positive, 500).option("--json", "print JSON; --json=id,title keeps only those fields").action(async (words, options) => {
|
|
10425
11110
|
listQuery(typedQuery(words), query, "people list");
|
|
10426
11111
|
await withStore(env, async (store) => {
|
|
10427
|
-
const found = await store.tasks.taskPeople({ limit: options.limit });
|
|
11112
|
+
const found = await keepInGroup(store, env, await store.tasks.taskPeople({ limit: options.limit }), ({ person }) => person);
|
|
10428
11113
|
print(options.json, wholeList("people list", found.map(({ person, ...rest }) => ({ ref: person, ...rest }))));
|
|
10429
11114
|
});
|
|
10430
11115
|
});
|
|
@@ -10467,19 +11152,19 @@ var headerOf2 = /* @__PURE__ */ __name((line3) => {
|
|
|
10467
11152
|
return void 0;
|
|
10468
11153
|
}
|
|
10469
11154
|
}, "headerOf");
|
|
10470
|
-
var
|
|
11155
|
+
var accountIn2 = /* @__PURE__ */ __name((envelope, given2) => {
|
|
10471
11156
|
const provider = envelope?.source?.provider;
|
|
10472
11157
|
return typeof provider === "string" && given2.startsWith(`${provider}:`) ? given2.slice(provider.length + 1) : given2;
|
|
10473
11158
|
}, "accountIn");
|
|
10474
11159
|
var deviceOf = /* @__PURE__ */ __name((given2) => {
|
|
10475
|
-
const
|
|
10476
|
-
if (
|
|
11160
|
+
const at2 = given2.indexOf(":");
|
|
11161
|
+
if (at2 < 0)
|
|
10477
11162
|
return given2;
|
|
10478
|
-
if (given2.slice(0,
|
|
11163
|
+
if (given2.slice(0, at2) !== PHONE)
|
|
10479
11164
|
throw new CliError("validation_error", "a vCard file holds a phone's contacts: --account phone:<device>", {
|
|
10480
11165
|
param: "--account"
|
|
10481
11166
|
});
|
|
10482
|
-
return given2.slice(
|
|
11167
|
+
return given2.slice(at2 + 1);
|
|
10483
11168
|
}, "deviceOf");
|
|
10484
11169
|
var importRecords = /* @__PURE__ */ __name(async (store, { file, stdin, account: account2, dryRun, onIssue, region }) => {
|
|
10485
11170
|
const iterator = (await linesOf(file, stdin))[Symbol.asyncIterator]();
|
|
@@ -10536,10 +11221,10 @@ var importRecords = /* @__PURE__ */ __name(async (store, { file, stdin, account:
|
|
|
10536
11221
|
}
|
|
10537
11222
|
}
|
|
10538
11223
|
__name(all, "all");
|
|
10539
|
-
return ingestLines(store, all(), { account:
|
|
11224
|
+
return ingestLines(store, all(), { account: accountIn2(header, account2), dryRun, onIssue });
|
|
10540
11225
|
}
|
|
10541
11226
|
const envelope = envelopeOfText(await whole2([first]));
|
|
10542
|
-
return ingest(store, envelope, { account:
|
|
11227
|
+
return ingest(store, envelope, { account: accountIn2(envelope, account2), dryRun, onIssue });
|
|
10543
11228
|
}, "importRecords");
|
|
10544
11229
|
|
|
10545
11230
|
// dist/records/mapping.js
|
|
@@ -10567,10 +11252,10 @@ var sourceOf4 = /* @__PURE__ */ __name((account2) => {
|
|
|
10567
11252
|
}, "sourceOf");
|
|
10568
11253
|
var recordOf = /* @__PURE__ */ __name((record2) => {
|
|
10569
11254
|
const from = record2.startsWith("custom:") ? "custom:".length : 0;
|
|
10570
|
-
const
|
|
10571
|
-
if (
|
|
11255
|
+
const at2 = record2.indexOf(":", from);
|
|
11256
|
+
if (at2 <= from || at2 === record2.length - 1)
|
|
10572
11257
|
throw new CliError("validation_error", `${record2} is not <type>:<external_id>, such as organization:client or custom:quote:Q-7`, { param: "record" });
|
|
10573
|
-
return { type: record2.slice(0,
|
|
11258
|
+
return { type: record2.slice(0, at2), externalId: record2.slice(at2 + 1) };
|
|
10574
11259
|
}, "recordOf");
|
|
10575
11260
|
var RECORD_HELP = "<type>:<external_id> as the source names it, such as organization:client or custom:quote:Q-7";
|
|
10576
11261
|
var ACCOUNT_HELP = "the source, <provider>:<account> as the envelope's source names it, such as sheet:rentals";
|
|
@@ -10828,7 +11513,7 @@ ${SOURCE_REVIEW_HELP}`);
|
|
|
10828
11513
|
...given2,
|
|
10829
11514
|
question: `${name2} ${ids.length} proposal${ids.length === 1 ? "" : "s"} as you, the owner?`
|
|
10830
11515
|
});
|
|
10831
|
-
const result = await withStore(env, (store) =>
|
|
11516
|
+
const result = await withStore(env, async (store) => (await reviewOf(store, env)).decide(ids, decisionOf(name2 === "confirm", by, given2.reason)));
|
|
10832
11517
|
const issues = result.refused.map((one2) => ({
|
|
10833
11518
|
code: one2.code,
|
|
10834
11519
|
source: one2.id,
|
|
@@ -10846,26 +11531,26 @@ ${SOURCE_REVIEW_HELP}`);
|
|
|
10846
11531
|
}, "reviewCommand");
|
|
10847
11532
|
|
|
10848
11533
|
// dist/notes/embed.js
|
|
10849
|
-
import { existsSync as
|
|
10850
|
-
import { join as
|
|
11534
|
+
import { existsSync as existsSync10, readdirSync as readdirSync7 } from "node:fs";
|
|
11535
|
+
import { join as join13 } from "node:path";
|
|
10851
11536
|
var EMBED_PER_RUN = 600;
|
|
11537
|
+
var MEASURED_WITH = "e5-small";
|
|
10852
11538
|
var SLOWEST_KNOWN = 2;
|
|
10853
11539
|
var embedPerRun = /* @__PURE__ */ __name((env = process.env) => {
|
|
10854
11540
|
const models = textModels(env);
|
|
10855
11541
|
const speed = /* @__PURE__ */ __name((id) => models.find((model) => model.id === id)?.chunksPerSecond ?? SLOWEST_KNOWN, "speed");
|
|
10856
|
-
const ratio = speed(chosenTextModel(env).id) / speed(
|
|
11542
|
+
const ratio = speed(chosenTextModel(env).id) / speed(MEASURED_WITH);
|
|
10857
11543
|
return Math.max(8, Math.min(EMBED_PER_RUN, Math.round(EMBED_PER_RUN * ratio)));
|
|
10858
11544
|
}, "embedPerRun");
|
|
10859
11545
|
var missingModel = /* @__PURE__ */ __name((error, env) => {
|
|
10860
11546
|
const named5 = isCliError(error) ? error.details.model : void 0;
|
|
10861
11547
|
const id = typeof named5 === "string" ? named5 : chosenTextModel(env).id;
|
|
10862
|
-
|
|
10863
|
-
return `the ${id} model is not downloaded \u2014 memo models download ${id}${terms2 ? " --accept-terms" : ""}`;
|
|
11548
|
+
return `the ${id} model is not downloaded \u2014 memo models download ${id}`;
|
|
10864
11549
|
}, "missingModel");
|
|
10865
11550
|
var searchModelPresent = /* @__PURE__ */ __name((env) => {
|
|
10866
11551
|
try {
|
|
10867
|
-
const path =
|
|
10868
|
-
return
|
|
11552
|
+
const path = join13(sharedModelsDirectory("text", env), chosenTextModel(env).id);
|
|
11553
|
+
return existsSync10(path) && readdirSync7(path).length > 0;
|
|
10869
11554
|
} catch {
|
|
10870
11555
|
return false;
|
|
10871
11556
|
}
|
|
@@ -10874,7 +11559,7 @@ var isMissingModel = /* @__PURE__ */ __name((error) => isCliError(error) && erro
|
|
|
10874
11559
|
var reportOf = /* @__PURE__ */ __name((run) => {
|
|
10875
11560
|
if (run === void 0)
|
|
10876
11561
|
return void 0;
|
|
10877
|
-
if (
|
|
11562
|
+
if (!("provider" in run))
|
|
10878
11563
|
return {
|
|
10879
11564
|
status: "failed",
|
|
10880
11565
|
sent: 0,
|
|
@@ -10884,7 +11569,8 @@ var reportOf = /* @__PURE__ */ __name((run) => {
|
|
|
10884
11569
|
inputTokens: 0,
|
|
10885
11570
|
outputTokens: 0,
|
|
10886
11571
|
costUsd: 0,
|
|
10887
|
-
reason: run.reason
|
|
11572
|
+
reason: run.reason,
|
|
11573
|
+
reasonId: run.reason_id
|
|
10888
11574
|
};
|
|
10889
11575
|
return {
|
|
10890
11576
|
status: run.status,
|
|
@@ -10897,7 +11583,8 @@ var reportOf = /* @__PURE__ */ __name((run) => {
|
|
|
10897
11583
|
inputTokens: run.usage.input,
|
|
10898
11584
|
outputTokens: run.usage.output,
|
|
10899
11585
|
costUsd: run.cost_usd,
|
|
10900
|
-
...run.reason === void 0 ? {} : { reason: run.reason }
|
|
11586
|
+
...run.reason === void 0 ? {} : { reason: run.reason },
|
|
11587
|
+
...run.reason_id === void 0 ? {} : { reasonId: run.reason_id }
|
|
10901
11588
|
};
|
|
10902
11589
|
}, "reportOf");
|
|
10903
11590
|
var combinedEnrichment = /* @__PURE__ */ __name((...parts2) => {
|
|
@@ -10906,20 +11593,23 @@ var combinedEnrichment = /* @__PURE__ */ __name((...parts2) => {
|
|
|
10906
11593
|
return void 0;
|
|
10907
11594
|
const rank = { done: 0, stopped: 1, failed: 2 };
|
|
10908
11595
|
const worst = present2.reduce((a, b) => rank[b.status] > rank[a.status] ? b : a);
|
|
11596
|
+
const enriched = present2.reduce((sum, part) => sum + part.enriched, 0);
|
|
11597
|
+
const status = worst.status === "failed" && enriched > 0 ? "stopped" : worst.status;
|
|
10909
11598
|
const named5 = present2.find((part) => part.provider !== void 0);
|
|
10910
11599
|
const costs = present2.map((part) => part.costUsd);
|
|
10911
11600
|
return {
|
|
10912
|
-
status
|
|
11601
|
+
status,
|
|
10913
11602
|
...named5?.provider === void 0 ? {} : { provider: named5.provider },
|
|
10914
11603
|
...named5?.model === void 0 ? {} : { model: named5.model },
|
|
10915
11604
|
sent: present2.reduce((sum, part) => sum + part.sent, 0),
|
|
10916
|
-
enriched
|
|
11605
|
+
enriched,
|
|
10917
11606
|
failed: present2.reduce((sum, part) => sum + part.failed, 0),
|
|
10918
11607
|
left: present2.reduce((sum, part) => sum + part.left, 0),
|
|
10919
11608
|
inputTokens: present2.reduce((sum, part) => sum + part.inputTokens, 0),
|
|
10920
11609
|
outputTokens: present2.reduce((sum, part) => sum + part.outputTokens, 0),
|
|
10921
11610
|
costUsd: costs.includes(null) ? null : Math.round(costs.reduce((sum, cost) => sum + (cost ?? 0), 0) * 1e6) / 1e6,
|
|
10922
|
-
...worst.reason === void 0 ? {} : { reason: worst.reason }
|
|
11611
|
+
...worst.reason === void 0 ? {} : { reason: worst.reason },
|
|
11612
|
+
...worst.reasonId === void 0 ? {} : { reasonId: worst.reasonId }
|
|
10923
11613
|
};
|
|
10924
11614
|
}, "combinedEnrichment");
|
|
10925
11615
|
var embedNoteChunks = /* @__PURE__ */ __name(async (store, { embed = true, env, maxChunks = embedPerRun(env), keyring } = {}) => {
|
|
@@ -11080,6 +11770,7 @@ var syncCommand = /* @__PURE__ */ __name((program, streams, env, signal, keyring
|
|
|
11080
11770
|
}), "answer");
|
|
11081
11771
|
const work = withImportLock(env, async () => {
|
|
11082
11772
|
const store = await openStore({ env, ...STORE_CLIENT, decisions: decisionPolicy(env) });
|
|
11773
|
+
const enriched = [];
|
|
11083
11774
|
const attempt = /* @__PURE__ */ __name(async (source, work2) => {
|
|
11084
11775
|
halt();
|
|
11085
11776
|
try {
|
|
@@ -11118,11 +11809,13 @@ var syncCommand = /* @__PURE__ */ __name((program, streams, env, signal, keyring
|
|
|
11118
11809
|
});
|
|
11119
11810
|
if (folders.length > 0)
|
|
11120
11811
|
await attempt("notes by meaning", async () => {
|
|
11121
|
-
|
|
11812
|
+
const { enrichment: enrichment2, ...embedded } = await embedNoteChunks(store, {
|
|
11122
11813
|
embed: options.embed && config.notes?.embed !== false,
|
|
11123
11814
|
env,
|
|
11124
11815
|
...keyring ? { keyring } : {}
|
|
11125
11816
|
});
|
|
11817
|
+
run.notesEmbedded = embedded;
|
|
11818
|
+
enriched.push(enrichment2);
|
|
11126
11819
|
});
|
|
11127
11820
|
await attempt("people-notes.json", async () => {
|
|
11128
11821
|
await importNotesMap(store, env, folders);
|
|
@@ -11130,13 +11823,15 @@ var syncCommand = /* @__PURE__ */ __name((program, streams, env, signal, keyring
|
|
|
11130
11823
|
}
|
|
11131
11824
|
if (synced.has("mail"))
|
|
11132
11825
|
await attempt("mail by meaning", async () => {
|
|
11133
|
-
|
|
11826
|
+
const { enrichment: enrichment2, ...embedded } = await embedMailChunks(store, {
|
|
11134
11827
|
embed: options.embed,
|
|
11135
11828
|
env,
|
|
11136
11829
|
...keyring ? { keyring } : {}
|
|
11137
11830
|
});
|
|
11831
|
+
run.mailEmbedded = embedded;
|
|
11832
|
+
enriched.push(enrichment2);
|
|
11138
11833
|
});
|
|
11139
|
-
const enrichment = combinedEnrichment(
|
|
11834
|
+
const enrichment = combinedEnrichment(...enriched);
|
|
11140
11835
|
if (enrichment)
|
|
11141
11836
|
run.enrichment = enrichment;
|
|
11142
11837
|
halt();
|
|
@@ -11255,10 +11950,10 @@ var mailboxBlock = /* @__PURE__ */ __name((source, review, room = Number.POSITIV
|
|
|
11255
11950
|
let fit;
|
|
11256
11951
|
for (let end = 1; end < cuts.length; end++) {
|
|
11257
11952
|
const kept = new Set(cuts.slice(0, end).flatMap((cut2) => cut2.items));
|
|
11258
|
-
const
|
|
11953
|
+
const at2 = cuts[end - 1];
|
|
11259
11954
|
const block = lines(source, review, {
|
|
11260
|
-
key:
|
|
11261
|
-
cursor:
|
|
11955
|
+
key: at2?.key,
|
|
11956
|
+
cursor: at2?.cursor,
|
|
11262
11957
|
items: items.filter((item) => kept.has(item)),
|
|
11263
11958
|
waiting: items.length - kept.size
|
|
11264
11959
|
});
|
|
@@ -11346,8 +12041,8 @@ var searchText = /* @__PURE__ */ __name((result, offset = 0) => [
|
|
|
11346
12041
|
].join("\n"), "searchText");
|
|
11347
12042
|
|
|
11348
12043
|
// dist/search/hits.js
|
|
11349
|
-
var
|
|
11350
|
-
var briefHit = /* @__PURE__ */ __name((hit) => Object.fromEntries(
|
|
12044
|
+
var BRIEF2 = ["ref", "chat_title", "timestamp", "sender_name", "excerpt", "score"];
|
|
12045
|
+
var briefHit = /* @__PURE__ */ __name((hit) => Object.fromEntries(BRIEF2.flatMap((key) => hit[key] === void 0 || hit[key] === null ? [] : [[key, hit[key]]])), "briefHit");
|
|
11351
12046
|
|
|
11352
12047
|
// dist/search/answers.js
|
|
11353
12048
|
var named4 = /* @__PURE__ */ __name((accounts) => [
|
|
@@ -11443,7 +12138,7 @@ var notesAnswer = /* @__PURE__ */ __name((found, limit, page, args = {}) => list
|
|
|
11443
12138
|
var holdsNoPeople = /* @__PURE__ */ __name((provider) => provider === "notes" || isFolderProvider(provider), "holdsNoPeople");
|
|
11444
12139
|
var fold4 = /* @__PURE__ */ __name((text3) => text3.normalize("NFKD").replace(new RegExp("\\p{M}", "gu"), "").toLowerCase(), "fold");
|
|
11445
12140
|
var scopeOf2 = /* @__PURE__ */ __name(async (store, env, source) => {
|
|
11446
|
-
const keys = source === void 0 ? await store
|
|
12141
|
+
const keys = source === void 0 ? await scopedAccounts(store, env) : await accountsOf(store, env, source);
|
|
11447
12142
|
const held = keys.filter((key) => !holdsNoPeople(key.provider));
|
|
11448
12143
|
if (source !== void 0 && held.length === 0)
|
|
11449
12144
|
throw new CliError("validation_error", `${source} names no messenger, mail or meeting account that holds people`, {
|
|
@@ -11483,6 +12178,13 @@ var searchPeople = /* @__PURE__ */ __name(async (store, env, words, { limit, sou
|
|
|
11483
12178
|
hits.set(ref, hit);
|
|
11484
12179
|
}
|
|
11485
12180
|
}
|
|
12181
|
+
for (const { person, name: name2 } of source === void 0 ? await store.tasks.taskPeople({ limit: 5e3 }) : []) {
|
|
12182
|
+
if (hits.has(person) || name2 === null || !wanted.every((word) => fold4(name2).includes(word)))
|
|
12183
|
+
continue;
|
|
12184
|
+
const known2 = await store.people.personByUid(person.slice("person:".length));
|
|
12185
|
+
if (known2 && known2.identities.length === 0)
|
|
12186
|
+
hits.set(person, { ref: person, name: name2, identities: [], aliases: [] });
|
|
12187
|
+
}
|
|
11486
12188
|
const first = wanted.join(" ");
|
|
11487
12189
|
const rank = /* @__PURE__ */ __name((hit) => fold4(hit.name ?? "").startsWith(first) ? 0 : 1, "rank");
|
|
11488
12190
|
const sorted = [...hits.values()].sort((a, b) => rank(a) - rank(b) || (a.name ?? "").localeCompare(b.name ?? "") || a.ref.localeCompare(b.ref));
|
|
@@ -11500,6 +12202,17 @@ var peopleText = /* @__PURE__ */ __name((found) => found.items.map((hit) => [
|
|
|
11500
12202
|
].join("\n")).join("\n") || "nobody found", "peopleText");
|
|
11501
12203
|
|
|
11502
12204
|
// dist/search/command.js
|
|
12205
|
+
var groupMessengers = /* @__PURE__ */ __name(async (store, env, text3) => {
|
|
12206
|
+
const scope = await groupScopeOf(store, env);
|
|
12207
|
+
if (scope === void 0)
|
|
12208
|
+
return void 0;
|
|
12209
|
+
if (hasSource(parseLucene(text3).root))
|
|
12210
|
+
throw new CliError("validation_error", `in group ${scope.run.name} search messages reads the group's accounts \u2014 leave in: out of the query`);
|
|
12211
|
+
const { messages } = accountsByKind(scope);
|
|
12212
|
+
if (messages.length === 0)
|
|
12213
|
+
throw new CliError("not_found", `group ${scope.run.name} holds no messenger account`);
|
|
12214
|
+
return messages;
|
|
12215
|
+
}, "groupMessengers");
|
|
11503
12216
|
var ONLY = ["messages", "mail", "notes", "events", "crm", "business"];
|
|
11504
12217
|
var onlyOf2 = /* @__PURE__ */ __name((value) => {
|
|
11505
12218
|
const selected = value.split(",").map((part) => part.trim());
|
|
@@ -11523,7 +12236,7 @@ var searchCommandDefinition = /* @__PURE__ */ __name((program, streams, env) =>
|
|
|
11523
12236
|
throw new InvalidArgumentError("at most 100");
|
|
11524
12237
|
return limit;
|
|
11525
12238
|
}, 20).option("--exact", "words as written; skip meaning search").option("--timezone <zone>", "IANA timezone for calendar date boundaries").option("--json", "print JSON; --json=id,title keeps only those fields"), "queryOptions");
|
|
11526
|
-
queryOptions(annotate(group.command("all"), { effects: LOCAL_READ, output: { entity: "hit" } }).description("messages, mail, notes, calendar events, deals, leads and business data ranked together; not people, memories, projects or decisions. A kind you know reads better with its own search, with all its fields").summary("messages, mail, notes and
|
|
12239
|
+
queryOptions(annotate(group.command("all"), { effects: LOCAL_READ, output: { entity: "hit" } }).description("messages, mail, notes, calendar events, deals, leads and business data ranked together; not people, memories, projects or decisions. A kind you know reads better with its own search, with all its fields").summary("messages, mail, notes, events and deals ranked together")).option("--only <resources>", `${ONLY.join(",")}, separated by commas`, onlyOf2).option("--plain-order", "best first by the words alone, without moving mail from suspicious senders down").option("--project <project>", PROJECT_ORDER_HELP).addHelpText("after", `
|
|
11527
12240
|
content: narrows a search to the text of files, transcript: to voice transcripts, filename: to file names \u2014 memo search all 'content:invoice'.
|
|
11528
12241
|
Calendar events come from every calendar gcal stored; an event's title, description and place are written by whoever sent the invitation.
|
|
11529
12242
|
crm finds deals and leads by the words of their title only.
|
|
@@ -11591,7 +12304,7 @@ For an agent: read with --compact, one line per hit with its reference. Never wr
|
|
|
11591
12304
|
const level = levelOf(options);
|
|
11592
12305
|
const text3 = words.join(" ");
|
|
11593
12306
|
const answer = await withStore(env, async (store) => {
|
|
11594
|
-
const mailboxes = options.source
|
|
12307
|
+
const mailboxes = options.source !== void 0 ? await mailboxesOf(store, env, options.source) : kind === "messages" ? await groupMessengers(store, env, text3) : void 0;
|
|
11595
12308
|
return searchKind(store, kind, {
|
|
11596
12309
|
text: text3,
|
|
11597
12310
|
limit: options.limit,
|
|
@@ -11745,7 +12458,7 @@ var showReferences = /* @__PURE__ */ __name(async (store, env, texts, command) =
|
|
|
11745
12458
|
}
|
|
11746
12459
|
return shown3;
|
|
11747
12460
|
}, "showReferences");
|
|
11748
|
-
var minute2 = /* @__PURE__ */ __name((
|
|
12461
|
+
var minute2 = /* @__PURE__ */ __name((at2) => at2 === null ? null : at2.slice(0, 16).replace("T", " "), "minute");
|
|
11749
12462
|
var blockOf = /* @__PURE__ */ __name((one2) => [
|
|
11750
12463
|
`${one2.ref} ${one2.title ?? ""}`.trimEnd(),
|
|
11751
12464
|
` ${[one2.kind, one2.in, one2.state, minute2(one2.at)].filter((part) => part !== null).join(" \xB7 ")}`,
|
|
@@ -11768,29 +12481,29 @@ var showCommand = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
11768
12481
|
}, "showCommand");
|
|
11769
12482
|
|
|
11770
12483
|
// dist/sources/command.js
|
|
11771
|
-
import { existsSync as
|
|
12484
|
+
import { existsSync as existsSync12 } from "node:fs";
|
|
11772
12485
|
|
|
11773
12486
|
// dist/sources/copy.js
|
|
11774
12487
|
import { randomUUID } from "node:crypto";
|
|
11775
|
-
import { existsSync as
|
|
11776
|
-
import { isAbsolute, join as
|
|
11777
|
-
var copiesDir = /* @__PURE__ */ __name((env) =>
|
|
11778
|
-
var copyPath = /* @__PURE__ */ __name((env, hash) =>
|
|
12488
|
+
import { existsSync as existsSync11, mkdirSync as mkdirSync4, renameSync as renameSync3, rmSync as rmSync3, writeFileSync as writeFileSync5 } from "node:fs";
|
|
12489
|
+
import { isAbsolute, join as join14, relative as relative2, resolve as resolve5, sep as sep2 } from "node:path";
|
|
12490
|
+
var copiesDir = /* @__PURE__ */ __name((env) => join14(resolvePaths({ appName: APP.appName, prefix: APP.envPrefix, env }).state, "sources"), "copiesDir");
|
|
12491
|
+
var copyPath = /* @__PURE__ */ __name((env, hash) => join14(copiesDir(env), hash), "copyPath");
|
|
11779
12492
|
var keepCopy = /* @__PURE__ */ __name((env, hash, bytes) => {
|
|
11780
12493
|
const path = copyPath(env, hash);
|
|
11781
|
-
if (
|
|
12494
|
+
if (existsSync11(path))
|
|
11782
12495
|
return { path, wrote: false };
|
|
11783
12496
|
mkdirSync4(copiesDir(env), { recursive: true, mode: 448 });
|
|
11784
12497
|
const partial = `${path}.${randomUUID()}.part`;
|
|
11785
|
-
|
|
12498
|
+
writeFileSync5(partial, bytes, { mode: 384 });
|
|
11786
12499
|
renameSync3(partial, path);
|
|
11787
12500
|
return { path, wrote: true };
|
|
11788
12501
|
}, "keepCopy");
|
|
11789
12502
|
var dropCopy = /* @__PURE__ */ __name((env, path) => {
|
|
11790
12503
|
const inside2 = relative2(resolve5(copiesDir(env)), resolve5(path));
|
|
11791
|
-
if (!inside2 || isAbsolute(inside2) || inside2.startsWith("..") || inside2.includes(sep2) || !
|
|
12504
|
+
if (!inside2 || isAbsolute(inside2) || inside2.startsWith("..") || inside2.includes(sep2) || !existsSync11(path))
|
|
11792
12505
|
return false;
|
|
11793
|
-
|
|
12506
|
+
rmSync3(path);
|
|
11794
12507
|
return true;
|
|
11795
12508
|
}, "dropCopy");
|
|
11796
12509
|
|
|
@@ -11801,7 +12514,7 @@ var escaped = /* @__PURE__ */ __name((text3) => text3.replace(/[.*+?^${}()|[\]\\
|
|
|
11801
12514
|
var folded = /* @__PURE__ */ __name((text3) => text3.normalize("NFC").toLocaleLowerCase(), "folded");
|
|
11802
12515
|
var mentionsOf = /* @__PURE__ */ __name(async (store, note) => {
|
|
11803
12516
|
const id = Number(note.id);
|
|
11804
|
-
const
|
|
12517
|
+
const at2 = note.modifiedAt ?? note.updatedAt;
|
|
11805
12518
|
const found = [];
|
|
11806
12519
|
for (let offset = 0; ; offset += PAGE6) {
|
|
11807
12520
|
const page = await store.sourceMentions.list("document", void 0, { limit: PAGE6, offset }, []);
|
|
@@ -11809,7 +12522,7 @@ var mentionsOf = /* @__PURE__ */ __name(async (store, note) => {
|
|
|
11809
12522
|
const when = mention.source.at ?? "";
|
|
11810
12523
|
if (mention.source.id === id)
|
|
11811
12524
|
found.push(mention);
|
|
11812
|
-
else if (found.length > 0 || when <
|
|
12525
|
+
else if (found.length > 0 || when < at2 || when === at2 && mention.source.id < id)
|
|
11813
12526
|
return found;
|
|
11814
12527
|
}
|
|
11815
12528
|
if (!page.hasMore)
|
|
@@ -11852,8 +12565,8 @@ ${note.text}`);
|
|
|
11852
12565
|
const name2 = organization.name.trim();
|
|
11853
12566
|
if (name2.length < 3)
|
|
11854
12567
|
continue;
|
|
11855
|
-
const
|
|
11856
|
-
if (
|
|
12568
|
+
const at2 = new RegExp(`(?<![\\p{L}\\p{N}])${escaped(folded(name2))}(?![\\p{L}\\p{N}])`, "u");
|
|
12569
|
+
if (at2.test(text3))
|
|
11857
12570
|
add(organization.ref, "organization", organization.name, name2);
|
|
11858
12571
|
}
|
|
11859
12572
|
return {
|
|
@@ -11864,7 +12577,7 @@ ${note.text}`);
|
|
|
11864
12577
|
}, "namedIn");
|
|
11865
12578
|
|
|
11866
12579
|
// dist/sources/read.js
|
|
11867
|
-
import { readFileSync as
|
|
12580
|
+
import { readFileSync as readFileSync10, statSync as statSync5 } from "node:fs";
|
|
11868
12581
|
import { basename as basename3, extname as extname2 } from "node:path";
|
|
11869
12582
|
var SOURCE_TEXT_CHARS = 2e5;
|
|
11870
12583
|
var URL_LIKE = /^[a-z][a-z0-9+.-]*:\/\//i;
|
|
@@ -11982,7 +12695,7 @@ var readFile = /* @__PURE__ */ __name(async (path, { maxChars, load = importEngi
|
|
|
11982
12695
|
throw new CliError("validation_error", `${path} is not a file`, { path });
|
|
11983
12696
|
if (stat.size > MAX_FILE_BYTES)
|
|
11984
12697
|
throw tooLarge2(name2);
|
|
11985
|
-
const bytes = new Uint8Array(
|
|
12698
|
+
const bytes = new Uint8Array(readFileSync10(path));
|
|
11986
12699
|
const extension = extname2(name2).toLowerCase();
|
|
11987
12700
|
const mime = MIMES[extension] ?? null;
|
|
11988
12701
|
const found = await extractText(bytes, { kind: "file", name: name2, mime, path }, load);
|
|
@@ -12184,7 +12897,7 @@ var sourcesCommand = /* @__PURE__ */ __name((program, streams, env, { fetch: fet
|
|
|
12184
12897
|
mime: source?.mime ?? null,
|
|
12185
12898
|
bytes: source?.size ?? null,
|
|
12186
12899
|
// The row says a copy was kept; only the file itself says it still is.
|
|
12187
|
-
kept: source === void 0 ? null : source.copy !== null &&
|
|
12900
|
+
kept: source === void 0 ? null : source.copy !== null && existsSync12(source.copy) ? "copy" : "text",
|
|
12188
12901
|
chars: note.text.length,
|
|
12189
12902
|
text: text3,
|
|
12190
12903
|
textTruncated: truncated,
|
|
@@ -12229,6 +12942,56 @@ var sourcesCommand = /* @__PURE__ */ __name((program, streams, env, { fetch: fet
|
|
|
12229
12942
|
});
|
|
12230
12943
|
}, "sourcesCommand");
|
|
12231
12944
|
|
|
12945
|
+
// dist/store/groups-command.js
|
|
12946
|
+
var MEMBER_HELP = "one account, as --source names it: telegram:102, tg:work, email:me@work.example, bitrix24:<portal>";
|
|
12947
|
+
var GROUPS_QUERY = { entity: "account_group", backend: "native", fields: [] };
|
|
12948
|
+
var at = /* @__PURE__ */ __name((store, env) => ({ store, account: MEMO_ACCOUNT, app: APP, env }), "at");
|
|
12949
|
+
var membershipText = /* @__PURE__ */ __name(({ groups, duplicates, suggested, unresolved }) => [
|
|
12950
|
+
...Object.entries(groups).flatMap(([name2, members]) => [
|
|
12951
|
+
`${name2}${members.length ? "" : " (empty)"}`,
|
|
12952
|
+
...members.map((member) => [
|
|
12953
|
+
` ${member.provider}:${member.account}`,
|
|
12954
|
+
member.profiles.length ? member.profiles.join(", ") : "",
|
|
12955
|
+
member.reason === "setting" ? "" : member.reason,
|
|
12956
|
+
member.also_in.length ? `also in ${member.also_in.join(", ")}` : ""
|
|
12957
|
+
].filter(Boolean).join(" "))
|
|
12958
|
+
]),
|
|
12959
|
+
...duplicates.map(({ member, groups: names }) => `duplicate: ${member} is in ${names.join(", ")}`),
|
|
12960
|
+
...suggested.map(({ group, member, because }) => `suggested: ${member} for ${group} \u2014 ${because}`),
|
|
12961
|
+
...unresolved.map((entry) => `unresolved: ${entry} names no account`)
|
|
12962
|
+
].join("\n"), "membershipText");
|
|
12963
|
+
var groupsCommand = /* @__PURE__ */ __name((program, streams, env) => {
|
|
12964
|
+
const { print } = answers(program, streams, env);
|
|
12965
|
+
const groups = program.command("groups").description("account groups: memo <group> \u2026 reads only the group's accounts");
|
|
12966
|
+
const show = /* @__PURE__ */ __name(async (command, json5, work) => {
|
|
12967
|
+
const membership = await withStore(env, work);
|
|
12968
|
+
const { groups: named5, duplicates, suggested, unresolved } = membership;
|
|
12969
|
+
const items = Object.entries(named5).map(([group, members]) => ({
|
|
12970
|
+
group,
|
|
12971
|
+
members,
|
|
12972
|
+
duplicates: duplicates.filter(({ groups: names }) => names.includes(group)),
|
|
12973
|
+
suggested: suggested.filter((one2) => one2.group === group)
|
|
12974
|
+
}));
|
|
12975
|
+
print(json5, listAnswer(command, {
|
|
12976
|
+
items,
|
|
12977
|
+
limit: Math.max(1, items.length),
|
|
12978
|
+
has_more: false,
|
|
12979
|
+
missing: unresolved.map((entry) => ({
|
|
12980
|
+
field: entry,
|
|
12981
|
+
why: "a saved group entry that names no account"
|
|
12982
|
+
}))
|
|
12983
|
+
}), membershipText(membership));
|
|
12984
|
+
}, "show");
|
|
12985
|
+
const reserved = /* @__PURE__ */ __name(() => commandWords(program), "reserved");
|
|
12986
|
+
withQuery(annotate(groups.command("list"), { effects: LOCAL_READ, output: { entity: "account_group" } }), GROUPS_QUERY).description("every saved group, then all, with its accounts, each with its profiles in every app and the other groups that hold it too; duplicates and profile-name suggestions last").summary("the saved groups, then all, with accounts, profiles and duplicates").option("--json", "print JSON; --json=id,title keeps only those fields").action(async (words, options) => {
|
|
12987
|
+
queryTerms(words, GROUPS_QUERY, "groups list");
|
|
12988
|
+
await show("groups list", options.json, (store) => listAccountGroups(at(store, env)));
|
|
12989
|
+
});
|
|
12990
|
+
grantsAuthority(annotate(groups.command("add"), { effects: LOCAL_WRITE, output: { entity: "account_group" } })).description("put an account in a group, which is made when it does not exist; it may stay in others too").summary("put an account in a group").argument("<group>", "the group: letters, digits, - and _, not a memo command word").argument("<source>", MEMBER_HELP).option("--json", "print JSON; --json=id,title keeps only those fields").action((group, member, options) => show("groups add", options.json, (store) => addGroupMember(at(store, env), { group, member, reserved: reserved() })));
|
|
12991
|
+
grantsAuthority(annotate(groups.command("remove"), { effects: LOCAL_WRITE, output: { entity: "account_group" } })).description("take an account out of a group; the account and its data stay, and `all` still reads it").summary("take an account out of a group").argument("<group>", "the group").argument("<source>", MEMBER_HELP).option("--json", "print JSON; --json=id,title keeps only those fields").action((group, member, options) => show("groups remove", options.json, (store) => removeGroupMember(at(store, env), { group, member })));
|
|
12992
|
+
grantsAuthority(annotate(groups.command("move"), { effects: LOCAL_WRITE, output: { entity: "account_group" } })).description("move an account from one group to another in one write; the other group is made when it is new").summary("move an account between groups").argument("<source>", MEMBER_HELP).argument("<from>", "the group it leaves").argument("<to>", "the group it joins").option("--json", "print JSON; --json=id,title keeps only those fields").action((member, from, to, options) => show("groups move", options.json, (store) => moveGroupMember(at(store, env), { member, from, to, reserved: reserved() })));
|
|
12993
|
+
}, "groupsCommand");
|
|
12994
|
+
|
|
12232
12995
|
// dist/store/info-command.js
|
|
12233
12996
|
var storeCommand = /* @__PURE__ */ __name((program, streams, env) => {
|
|
12234
12997
|
const { print } = answers(program, streams, env);
|
|
@@ -12330,7 +13093,7 @@ var tagsCommand = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
12330
13093
|
}
|
|
12331
13094
|
if (options.contact !== void 0 || options.meeting !== void 0) {
|
|
12332
13095
|
await withStore(env, async (store) => {
|
|
12333
|
-
const { key, target: target2 } = await selectTarget(store, { ...options, ...await scoped3(store) });
|
|
13096
|
+
const { key, target: target2 } = await selectTarget(store, env, { ...options, ...await scoped3(store) });
|
|
12334
13097
|
const changed = await (operation === "add" ? store.knowledge.addTags : store.knowledge.removeTags)(key, target2, given2);
|
|
12335
13098
|
print(options.json, itemAnswer({ ...key, target: target2, [operation === "add" ? "added" : "removed"]: changed }), `${operation}: ${changed.join(", ") || "no labels changed"}`);
|
|
12336
13099
|
});
|
|
@@ -12367,7 +13130,7 @@ var tagsCommand = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
12367
13130
|
...terms2.has("type") ? { type: terms2.get("type") } : {}
|
|
12368
13131
|
};
|
|
12369
13132
|
await withStore(env, async (store) => {
|
|
12370
|
-
const keys = value === void 0 ? await store
|
|
13133
|
+
const keys = value === void 0 ? await scopedAccounts(store, env) : await accountsOf(store, env, value);
|
|
12371
13134
|
const answer = await listTags(store, { ...options, keys });
|
|
12372
13135
|
const owned = options.type === void 0 || OWNED.includes(options.type) ? await store.knowledge.labelled(null, {
|
|
12373
13136
|
...options.tag === void 0 ? {} : { tag: options.tag },
|
|
@@ -12439,7 +13202,7 @@ var requireAccount = /* @__PURE__ */ __name((env, warn) => async (_, command) =>
|
|
|
12439
13202
|
return;
|
|
12440
13203
|
if (["show", "update", "claim", "release"].includes(command.name()) && first !== void 0 && await store.tasks.projectTask(first))
|
|
12441
13204
|
return;
|
|
12442
|
-
const listed2 = (await store
|
|
13205
|
+
const listed2 = (await scopedAccounts(store, env)).map((key) => `${option} ${key.provider}:${key.account}`).join("; ");
|
|
12443
13206
|
throw new CliError("validation_error", `give ${option} \u2014 the stored accounts: ${listed2 || "none yet"}`);
|
|
12444
13207
|
} finally {
|
|
12445
13208
|
await store.close();
|
|
@@ -12515,7 +13278,7 @@ var addFromSource = /* @__PURE__ */ __name(async (store, env, source, options) =
|
|
|
12515
13278
|
const parsed = native ? void 0 : parseLocator(source);
|
|
12516
13279
|
if (parsed && (options.provider && options.provider !== parsed.provider || options.account && options.account !== parsed.account))
|
|
12517
13280
|
throw new CliError("validation_error", "locator and selected account disagree");
|
|
12518
|
-
const key = parsed ? { provider: parsed.provider, account: parsed.account } : (options.provider === void 0 ? await folderOf(store, source) : void 0) ?? await selectAccount(store, options);
|
|
13281
|
+
const key = parsed ? { provider: parsed.provider, account: parsed.account } : (options.provider === void 0 ? await folderOf(store, source) : void 0) ?? await selectAccount(store, env, options);
|
|
12519
13282
|
if (parsed && parsed.provider !== "notes" && await heldMessage(store, key, parsed.message, parsed.chat) === void 0)
|
|
12520
13283
|
throw new CliError("not_found", "the task source is unavailable or deleted");
|
|
12521
13284
|
const author = authorOf(env);
|
|
@@ -12544,7 +13307,7 @@ var closeTask = /* @__PURE__ */ __name(async (store, env, id, options) => {
|
|
|
12544
13307
|
}
|
|
12545
13308
|
if (options.revision !== void 0)
|
|
12546
13309
|
throw new CliError("validation_error", "--revision checks a project task; a task from a message has none");
|
|
12547
|
-
const key = await selectAccount(store, options);
|
|
13310
|
+
const key = await selectAccount(store, env, options);
|
|
12548
13311
|
return tasksService(storeOnlyDeps(store, key, { app: APP, env })).close(id, {
|
|
12549
13312
|
as: options.as,
|
|
12550
13313
|
by: "owner",
|
|
@@ -12576,7 +13339,7 @@ var updateTask = /* @__PURE__ */ __name(async (store, env, id, options) => {
|
|
|
12576
13339
|
if (options.priority !== void 0 || options.parent !== void 0)
|
|
12577
13340
|
throw new CliError("validation_error", "--priority and --parent are for a task in a project");
|
|
12578
13341
|
const assignees = options.assignee?.map((one2) => one2 === "sender" || one2 === "none" ? one2 : personRef(one2));
|
|
12579
|
-
const key = await selectAccount(store, options);
|
|
13342
|
+
const key = await selectAccount(store, env, options);
|
|
12580
13343
|
return tasksService(storeOnlyDeps(store, key, { app: APP, env })).plan(id, {
|
|
12581
13344
|
...options.title === void 0 ? {} : { title: options.title },
|
|
12582
13345
|
...options.description === void 0 ? {} : { description: options.description },
|
|
@@ -12957,6 +13720,38 @@ var OWN_ENTITIES = entityFields({
|
|
|
12957
13720
|
agent_action: ["id", "actor", "tool", "tier", "target", "status", "error", "started_at", "finished_at"],
|
|
12958
13721
|
meeting_project: ["id", "meeting", "project", "confirmed", "provenance", "fingerprint"],
|
|
12959
13722
|
notes_folder: ["id", "name", "path", "format", "kept_by"],
|
|
13723
|
+
account_group: ["group", "members", "duplicates", "suggested"],
|
|
13724
|
+
relationship_role: ["list", "id", "label", "built_in"],
|
|
13725
|
+
person_context_memo: [
|
|
13726
|
+
"messages",
|
|
13727
|
+
"events",
|
|
13728
|
+
"notes",
|
|
13729
|
+
"your_notes",
|
|
13730
|
+
"not_read",
|
|
13731
|
+
"tasks",
|
|
13732
|
+
"relationships",
|
|
13733
|
+
"business",
|
|
13734
|
+
"coverage",
|
|
13735
|
+
"files",
|
|
13736
|
+
"untrusted",
|
|
13737
|
+
"proposals"
|
|
13738
|
+
],
|
|
13739
|
+
organization_context_memo: [
|
|
13740
|
+
"organization",
|
|
13741
|
+
"categories",
|
|
13742
|
+
"people",
|
|
13743
|
+
"customers",
|
|
13744
|
+
"suppliers",
|
|
13745
|
+
"partners",
|
|
13746
|
+
"projects",
|
|
13747
|
+
"deals",
|
|
13748
|
+
"money",
|
|
13749
|
+
"communications",
|
|
13750
|
+
"tasks",
|
|
13751
|
+
"coverage",
|
|
13752
|
+
"notes",
|
|
13753
|
+
"tags"
|
|
13754
|
+
],
|
|
12960
13755
|
order: [
|
|
12961
13756
|
"id",
|
|
12962
13757
|
"ref",
|
|
@@ -13233,6 +14028,89 @@ var OWN_ENTITIES = entityFields({
|
|
|
13233
14028
|
records_match: ["linked", "created", "unmatched", "proposed", "errors", "truncated"],
|
|
13234
14029
|
payment_allocation: ["payment", "invoice", "amount", "currency", "created_at"]
|
|
13235
14030
|
});
|
|
14031
|
+
var GROUP_AWARE = [
|
|
14032
|
+
"context",
|
|
14033
|
+
"show",
|
|
14034
|
+
"messages show",
|
|
14035
|
+
"search all",
|
|
14036
|
+
"search messages",
|
|
14037
|
+
"search mail",
|
|
14038
|
+
"search notes",
|
|
14039
|
+
"search people",
|
|
14040
|
+
"groups",
|
|
14041
|
+
"tags add",
|
|
14042
|
+
"tags remove",
|
|
14043
|
+
"deals",
|
|
14044
|
+
"leads",
|
|
14045
|
+
"pipelines list",
|
|
14046
|
+
"pipelines show",
|
|
14047
|
+
"stages",
|
|
14048
|
+
"organizations",
|
|
14049
|
+
"people list",
|
|
14050
|
+
"people add",
|
|
14051
|
+
"notes list",
|
|
14052
|
+
"notes show",
|
|
14053
|
+
"relationships list",
|
|
14054
|
+
"relationships add",
|
|
14055
|
+
"relationships update",
|
|
14056
|
+
"relationships end",
|
|
14057
|
+
"relationships remove",
|
|
14058
|
+
"relationships confirm",
|
|
14059
|
+
"relationships roles",
|
|
14060
|
+
"mcp serve",
|
|
14061
|
+
"memories",
|
|
14062
|
+
"facts",
|
|
14063
|
+
"actions",
|
|
14064
|
+
"review",
|
|
14065
|
+
"tasks",
|
|
14066
|
+
"projects list",
|
|
14067
|
+
"projects add",
|
|
14068
|
+
"projects context",
|
|
14069
|
+
"projects status",
|
|
14070
|
+
"projects key-documents"
|
|
14071
|
+
];
|
|
14072
|
+
var isSimpleKind = /* @__PURE__ */ __name((name2) => REF_KINDS.some(({ type }) => type === name2), "isSimpleKind");
|
|
14073
|
+
var REF_KINDS_OF = {
|
|
14074
|
+
deals: { ref: "deal" },
|
|
14075
|
+
leads: { ref: "lead" },
|
|
14076
|
+
memories: { ref: "memory" },
|
|
14077
|
+
facts: { ref: "fact" },
|
|
14078
|
+
tasks: { id: "task", "other-task": "task" },
|
|
14079
|
+
actions: { id: "action" },
|
|
14080
|
+
review: { id: "proposal", ids: "proposal" }
|
|
14081
|
+
};
|
|
14082
|
+
var UNMAPPED_IDS = /* @__PURE__ */ new Set(["id", "ids", "ref", "meeting-id"]);
|
|
14083
|
+
var leaves2 = /* @__PURE__ */ __name((command) => command.commands.length === 0 ? [command] : command.commands.flatMap(leaves2), "leaves");
|
|
14084
|
+
var topOf = /* @__PURE__ */ __name((command) => {
|
|
14085
|
+
let at2 = command;
|
|
14086
|
+
while (at2.parent?.parent)
|
|
14087
|
+
at2 = at2.parent;
|
|
14088
|
+
return at2.name();
|
|
14089
|
+
}, "topOf");
|
|
14090
|
+
var markGroupAware = /* @__PURE__ */ __name((program) => {
|
|
14091
|
+
for (const path of GROUP_AWARE) {
|
|
14092
|
+
let command = program;
|
|
14093
|
+
for (const name2 of path.split(" "))
|
|
14094
|
+
command = command?.commands.find((child) => child.name() === name2);
|
|
14095
|
+
if (!command)
|
|
14096
|
+
throw new Error(`no command to mark group-aware: ${path}`);
|
|
14097
|
+
groupAware(command);
|
|
14098
|
+
for (const leaf of leaves2(command)) {
|
|
14099
|
+
const top = topOf(leaf);
|
|
14100
|
+
const kinds2 = {};
|
|
14101
|
+
let mapped = true;
|
|
14102
|
+
for (const name2 of leaf.registeredArguments.map((argument) => argument.name())) {
|
|
14103
|
+
const kind = REF_KINDS_OF[top]?.[name2] ?? (isSimpleKind(name2) ? name2 : void 0);
|
|
14104
|
+
if (kind !== void 0)
|
|
14105
|
+
kinds2[name2] = kind;
|
|
14106
|
+
else if (UNMAPPED_IDS.has(name2))
|
|
14107
|
+
mapped = false;
|
|
14108
|
+
}
|
|
14109
|
+
if (mapped)
|
|
14110
|
+
refKinds(leaf, kinds2);
|
|
14111
|
+
}
|
|
14112
|
+
}
|
|
14113
|
+
}, "markGroupAware");
|
|
13236
14114
|
var SKILL_TOPICS = [
|
|
13237
14115
|
"search",
|
|
13238
14116
|
"projects",
|
|
@@ -13258,11 +14136,13 @@ var FIRST_SCREEN = {
|
|
|
13258
14136
|
profile: false,
|
|
13259
14137
|
start: "memo folders add <path>"
|
|
13260
14138
|
};
|
|
13261
|
-
var createProgram = /* @__PURE__ */ __name(({ streams: raw = processStreams, env = process.env, signal, terminal, keyring, fetchPage: fetchPage2 } = {}) => {
|
|
14139
|
+
var createProgram = /* @__PURE__ */ __name(({ streams: raw = processStreams, env: given2 = process.env, signal, terminal, keyring, fetchPage: fetchPage2, group, stdin } = {}) => {
|
|
14140
|
+
const env = group === void 0 ? given2 : { ...given2, MEMO_GROUP: group };
|
|
13262
14141
|
const fields = jsonFields(raw, OWN_ENTITIES);
|
|
13263
14142
|
const { streams } = fields;
|
|
13264
14143
|
const program = new Command("memo").description("context about people across messengers, notes and mail").version(VERSION).option("--debug", "on failure, show the full error record: cause and stack");
|
|
13265
14144
|
refuseWritesUnderLock(program, env);
|
|
14145
|
+
scopeRunsToGroup(program, env, group);
|
|
13266
14146
|
provideTerminal(program, terminal);
|
|
13267
14147
|
contextCommand(program, streams, env);
|
|
13268
14148
|
showCommand(program, streams, env);
|
|
@@ -13294,7 +14174,7 @@ var createProgram = /* @__PURE__ */ __name(({ streams: raw = processStreams, env
|
|
|
13294
14174
|
reviewCommand(program, streams, env);
|
|
13295
14175
|
agentsCommand(program, streams, env);
|
|
13296
14176
|
mcpCommand(program, streams, env, createProgram);
|
|
13297
|
-
modelsCommand(program, streams, env, keyring);
|
|
14177
|
+
modelsCommand(program, streams, env, keyring, stdin);
|
|
13298
14178
|
templatesCommand2(program, streams, env);
|
|
13299
14179
|
searchCommand(program, streams, env);
|
|
13300
14180
|
meetingReadCommands(program, streams, env);
|
|
@@ -13303,6 +14183,7 @@ var createProgram = /* @__PURE__ */ __name(({ streams: raw = processStreams, env
|
|
|
13303
14183
|
askCommand(program, streams, env);
|
|
13304
14184
|
syncCommand(program, streams, env, signal, keyring);
|
|
13305
14185
|
storeCommand(program, streams, env);
|
|
14186
|
+
groupsCommand(program, streams, env);
|
|
13306
14187
|
autoCommand(program, streams, env);
|
|
13307
14188
|
configCommand(program, streams, env);
|
|
13308
14189
|
doctorCommand(program, streams, env);
|
|
@@ -13310,14 +14191,19 @@ var createProgram = /* @__PURE__ */ __name(({ streams: raw = processStreams, env
|
|
|
13310
14191
|
program.addCommand(scheduleCommand(env));
|
|
13311
14192
|
digestCommand(program, streams, env);
|
|
13312
14193
|
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
|
|
14194
|
+
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
14195
|
const out = answers(program, streams, env);
|
|
14196
|
+
let brief;
|
|
13315
14197
|
const skill3 = skillCommand(APP, new URL("../skills/cli-memo/SKILL.md", new URL("../program.js", import.meta.url).href), (command) => {
|
|
13316
14198
|
const json5 = command.opts().json === true;
|
|
13317
14199
|
const renderer = createRenderer({ format: json5 ? "json" : "pretty", color: false, streams });
|
|
14200
|
+
const result = /* @__PURE__ */ __name((value) => {
|
|
14201
|
+
const shown3 = value;
|
|
14202
|
+
out.print(true, itemAnswer(shown3.content === void 0 ? value : { ...shown3, content: withBrief(shown3.content, brief) }));
|
|
14203
|
+
}, "result");
|
|
13318
14204
|
return {
|
|
13319
|
-
renderer: json5 ? { ...renderer, result
|
|
13320
|
-
streams,
|
|
14205
|
+
renderer: json5 ? { ...renderer, result } : renderer,
|
|
14206
|
+
streams: { ...streams, data: /* @__PURE__ */ __name((text3) => streams.data(withBrief(text3, brief)), "data") },
|
|
13321
14207
|
env
|
|
13322
14208
|
};
|
|
13323
14209
|
}, {
|
|
@@ -13328,8 +14214,10 @@ var createProgram = /* @__PURE__ */ __name(({ streams: raw = processStreams, env
|
|
|
13328
14214
|
for (const command of skill3.commands)
|
|
13329
14215
|
command.option("--json", "print JSON");
|
|
13330
14216
|
const show = skill3.commands.find((command) => command.name() === "show");
|
|
13331
|
-
|
|
13332
|
-
|
|
14217
|
+
show?.description(`${show.description()}; morning-digest ends with your brief from \`memo digest brief\` when you wrote one`);
|
|
14218
|
+
show?.hook("preAction", async (command) => {
|
|
14219
|
+
brief = command.args[0] === "morning-digest" ? await readBrief(env) : void 0;
|
|
14220
|
+
});
|
|
13333
14221
|
return skill3;
|
|
13334
14222
|
}, SHELL_OVERRIDES.skill);
|
|
13335
14223
|
program.addCommand(skill2);
|
|
@@ -13361,6 +14249,7 @@ var createProgram = /* @__PURE__ */ __name(({ streams: raw = processStreams, env
|
|
|
13361
14249
|
});
|
|
13362
14250
|
trackAnswers(program);
|
|
13363
14251
|
placeInSections(program);
|
|
14252
|
+
markGroupAware(program);
|
|
13364
14253
|
installHelp(program, FIRST_SCREEN);
|
|
13365
14254
|
provide(program, {
|
|
13366
14255
|
...environmentOf(program),
|
|
@@ -13379,6 +14268,18 @@ var createProgram = /* @__PURE__ */ __name(({ streams: raw = processStreams, env
|
|
|
13379
14268
|
assertSharedContracts(program);
|
|
13380
14269
|
return program;
|
|
13381
14270
|
}, "createProgram");
|
|
14271
|
+
var liftGroup = /* @__PURE__ */ __name(async (program, args, env) => {
|
|
14272
|
+
const words = commandWords(program);
|
|
14273
|
+
const { profile: group, rest } = liftProfile([...args], words);
|
|
14274
|
+
if (group === void 0)
|
|
14275
|
+
return { rest };
|
|
14276
|
+
const next = rest.find((arg) => !arg.startsWith("-"));
|
|
14277
|
+
const groups = await withStore(env, async (store) => Object.keys((await memoListContext(store, env)).groups));
|
|
14278
|
+
const known2 = group === "all" || groups.includes(group);
|
|
14279
|
+
if ((known2 || groupLockOf(APP, env) !== void 0) && next !== void 0 && words.has(next))
|
|
14280
|
+
return { group, rest };
|
|
14281
|
+
throw new CliError("validation_error", known2 ? `"${group}" is a group, and a command follows it: memo ${group} search all \u2026` : `"${group}": unknown command or group \u2014 groups here: ${groups.join(", ")}; memo commands lists the commands`, { reason: "input.invalid", groups });
|
|
14282
|
+
}, "liftGroup");
|
|
13382
14283
|
var refuseJoinedPath = /* @__PURE__ */ __name((program, args) => {
|
|
13383
14284
|
let command = program;
|
|
13384
14285
|
const path = [];
|
|
@@ -13398,5 +14299,6 @@ var refuseJoinedPath = /* @__PURE__ */ __name((program, args) => {
|
|
|
13398
14299
|
export {
|
|
13399
14300
|
SKILL_TOPICS,
|
|
13400
14301
|
createProgram,
|
|
14302
|
+
liftGroup,
|
|
13401
14303
|
refuseJoinedPath
|
|
13402
14304
|
};
|