@wirecat/cli-memo 0.131.70 → 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-3OEV7GNU.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-7OXLZZ27.js → chunk-DXWDHC2K.js} +14 -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-EQKS6M52.js → chunk-NNUS57F4.js} +5 -5
- package/dist/bundle/{chunk-52F4LHCH.js → chunk-OHBP2KPQ.js} +4 -4
- package/dist/bundle/{chunk-YBTUFOQG.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-57SQU2YO.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-RSUVU6HA.js → program-L5IM35PO.js} +1231 -449
- 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-BVRPQPGY.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/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 +44 -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 +158 -4
- package/dist/program.js.map +1 -1
- package/dist/reasons.d.ts.map +1 -1
- package/dist/reasons.js +12 -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 +4 -3
- 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-CVILDIC6.js +0 -85
- package/dist/bundle/failure-HM55W3NH.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-ZE53ASCW.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
|
{
|
|
@@ -4625,17 +4910,17 @@ var accountTasks = /* @__PURE__ */ __name(async (store, keys, options) => {
|
|
|
4625
4910
|
});
|
|
4626
4911
|
}, "accountTasks");
|
|
4627
4912
|
var accountTerms = /* @__PURE__ */ __name((query) => {
|
|
4628
|
-
const
|
|
4629
|
-
const other =
|
|
4913
|
+
const leaves3 = query ? walkQuery(query.root) : [];
|
|
4914
|
+
const other = leaves3.find(({ field: field2 }) => !ACCOUNT_FIELDS.has(field2));
|
|
4630
4915
|
if (other)
|
|
4631
4916
|
throw new CliError("validation_error", `${other.field}: narrows project tasks: add project:<key>, or project:* for every project`);
|
|
4632
|
-
const states = new Set(
|
|
4917
|
+
const states = new Set(leaves3.filter(({ field: field2 }) => field2 === "state").map(({ value }) => value.toLowerCase()));
|
|
4633
4918
|
if ((states.has("todo") || states.has("in_progress")) && !states.has("open"))
|
|
4634
4919
|
throw new CliError("validation_error", "todo and in_progress are steps of a project task: add project:");
|
|
4635
4920
|
const closed = [...states].filter(isClosedState);
|
|
4636
4921
|
if (closed.length > 1 || closed.length === 1 && states.size > 1)
|
|
4637
4922
|
throw new CliError("validation_error", "an account's tasks are listed in one state: state:open, done or dismissed");
|
|
4638
|
-
const sources =
|
|
4923
|
+
const sources = leaves3.filter(({ field: field2 }) => field2 === "source").map(({ value }) => value);
|
|
4639
4924
|
if (sources.length > 1)
|
|
4640
4925
|
throw new CliError("validation_error", "source: only once here");
|
|
4641
4926
|
return { state: closed[0] ?? "open", source: sources[0] };
|
|
@@ -4691,9 +4976,9 @@ var listTasks = /* @__PURE__ */ __name(async (store, words, options, accounts) =
|
|
|
4691
4976
|
}
|
|
4692
4977
|
const typed = typedQuery(words);
|
|
4693
4978
|
const query = listQuery(typed, TASKS_LIST_QUERY, "tasks list", { defaultField: "text" });
|
|
4694
|
-
const
|
|
4695
|
-
if (
|
|
4696
|
-
if (
|
|
4979
|
+
const leaves3 = query ? walkQuery(query.root) : [];
|
|
4980
|
+
if (leaves3.some(({ field: field2 }) => field2 === "project")) {
|
|
4981
|
+
if (leaves3.some(({ field: field2 }) => field2 === "source"))
|
|
4697
4982
|
throw new CliError("validation_error", "source: narrows an account's tasks, not a project's");
|
|
4698
4983
|
return projectTasks(store, typed, await resolveProjects(store, query), options);
|
|
4699
4984
|
}
|
|
@@ -4783,13 +5068,13 @@ var onPath = /* @__PURE__ */ __name((name2, env) => (env.PATH ?? "").split(delim
|
|
|
4783
5068
|
var runChild = /* @__PURE__ */ __name((command, args, { env, signal, onStderr }) => new Promise((resolve6, reject) => {
|
|
4784
5069
|
const child = spawn(command, args, { env, stdio: ["ignore", "pipe", "pipe"] });
|
|
4785
5070
|
let stdout = "";
|
|
4786
|
-
let
|
|
5071
|
+
let pending = "";
|
|
4787
5072
|
child.stdout.setEncoding("utf8").on("data", (chunk) => {
|
|
4788
5073
|
stdout += chunk;
|
|
4789
5074
|
});
|
|
4790
5075
|
child.stderr.setEncoding("utf8").on("data", (chunk) => {
|
|
4791
|
-
const lines2 = (
|
|
4792
|
-
|
|
5076
|
+
const lines2 = (pending + chunk).split("\n");
|
|
5077
|
+
pending = lines2.pop() ?? "";
|
|
4793
5078
|
for (const line3 of lines2)
|
|
4794
5079
|
if (line3)
|
|
4795
5080
|
onStderr?.(line3);
|
|
@@ -4804,8 +5089,8 @@ var runChild = /* @__PURE__ */ __name((command, args, { env, signal, onStderr })
|
|
|
4804
5089
|
child.on("close", (code) => {
|
|
4805
5090
|
clearTimeout(hard);
|
|
4806
5091
|
signal?.removeEventListener("abort", stop);
|
|
4807
|
-
if (
|
|
4808
|
-
onStderr?.(
|
|
5092
|
+
if (pending)
|
|
5093
|
+
onStderr?.(pending);
|
|
4809
5094
|
resolve6({ code, stdout });
|
|
4810
5095
|
});
|
|
4811
5096
|
}), "runChild");
|
|
@@ -5015,7 +5300,7 @@ var QUIET_AFTER = 3 * DAY3;
|
|
|
5015
5300
|
var QUIET_GAPS = 3;
|
|
5016
5301
|
var hours = /* @__PURE__ */ __name((from, now) => Math.max(0, Math.floor((now - from) / HOUR)), "hours");
|
|
5017
5302
|
var healthOf = /* @__PURE__ */ __name((sync, activity, now) => {
|
|
5018
|
-
const recent = /* @__PURE__ */ __name((
|
|
5303
|
+
const recent = /* @__PURE__ */ __name((at2) => at2 !== null && at2 >= now - DAY3, "recent");
|
|
5019
5304
|
if (recent(activity.storedAt) || sync.runs.some((run) => run.exitCode === 0 && recent(Date.parse(run.at))))
|
|
5020
5305
|
return void 0;
|
|
5021
5306
|
if (!sync.serving && sync.runs.length > 0 && sync.runs.every((run) => run.exitCode !== 0)) {
|
|
@@ -5059,9 +5344,9 @@ var digestReportTimes = /* @__PURE__ */ __name((env) => {
|
|
|
5059
5344
|
const runs = schedule ? join6(state, "schedules", schedule.name, "runs") : void 0;
|
|
5060
5345
|
if (!runs || !existsSync6(runs))
|
|
5061
5346
|
return [];
|
|
5062
|
-
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);
|
|
5063
5348
|
}, "digestReportTimes");
|
|
5064
|
-
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");
|
|
5065
5350
|
var previousDigestAt = /* @__PURE__ */ __name((env, now) => {
|
|
5066
5351
|
const last = digestSchedule(env).schedule?.last;
|
|
5067
5352
|
if (!last)
|
|
@@ -5158,8 +5443,8 @@ var gatherTasks = /* @__PURE__ */ __name(async (store, keys, { now, newSince, un
|
|
|
5158
5443
|
// dist/digest/backfill.js
|
|
5159
5444
|
var DAY5 = 864e5;
|
|
5160
5445
|
var DATE = /^(\d{4})-(\d{2})-(\d{2})$/;
|
|
5161
|
-
var localDate = /* @__PURE__ */ __name((
|
|
5162
|
-
const day2 = new Date(
|
|
5446
|
+
var localDate = /* @__PURE__ */ __name((at2) => {
|
|
5447
|
+
const day2 = new Date(at2);
|
|
5163
5448
|
return `${day2.getFullYear()}-${String(day2.getMonth() + 1).padStart(2, "0")}-${String(day2.getDate()).padStart(2, "0")}`;
|
|
5164
5449
|
}, "localDate");
|
|
5165
5450
|
var dateOf = /* @__PURE__ */ __name((value, flag) => {
|
|
@@ -5179,8 +5464,8 @@ var daysOf = /* @__PURE__ */ __name((from, to, time) => {
|
|
|
5179
5464
|
});
|
|
5180
5465
|
return days2;
|
|
5181
5466
|
}, "daysOf");
|
|
5182
|
-
var inputOf = /* @__PURE__ */ __name((date,
|
|
5183
|
-
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()}
|
|
5184
5469
|
`, "inputOf");
|
|
5185
5470
|
var usd = /* @__PURE__ */ __name((value) => `$${value.toFixed(2)}`, "usd");
|
|
5186
5471
|
var cents = /* @__PURE__ */ __name((value) => Math.round(value * 100) / 100, "cents");
|
|
@@ -5314,6 +5599,7 @@ var SECTIONS = [
|
|
|
5314
5599
|
["deals", "organise"],
|
|
5315
5600
|
["leads", "organise"],
|
|
5316
5601
|
["pipelines", "organise"],
|
|
5602
|
+
["stages", "organise"],
|
|
5317
5603
|
["payments", "organise"],
|
|
5318
5604
|
["products", "organise"],
|
|
5319
5605
|
["contracts", "organise"],
|
|
@@ -5330,6 +5616,7 @@ var SECTIONS = [
|
|
|
5330
5616
|
["jobs", "automate"],
|
|
5331
5617
|
["digest", "automate"],
|
|
5332
5618
|
["folders", "setup"],
|
|
5619
|
+
["groups", "setup"],
|
|
5333
5620
|
["config", "setup"]
|
|
5334
5621
|
];
|
|
5335
5622
|
var placeInSections = /* @__PURE__ */ __name((program) => {
|
|
@@ -5451,7 +5738,7 @@ var diagnose = /* @__PURE__ */ __name(async (env, program, { deep = false } = {}
|
|
|
5451
5738
|
};
|
|
5452
5739
|
}, "diagnose");
|
|
5453
5740
|
var yes = /* @__PURE__ */ __name((value) => value ? "yes" : "no", "yes");
|
|
5454
|
-
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");
|
|
5455
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");
|
|
5456
5743
|
var doctorText = /* @__PURE__ */ __name((d, fixes = [], online) => [
|
|
5457
5744
|
`memo ${d.memo.version} on Node ${d.memo.node}, installed by ${d.memo.installed_by}`,
|
|
@@ -5509,7 +5796,7 @@ var doctorCommand = /* @__PURE__ */ __name((...args) => {
|
|
|
5509
5796
|
}, SHELL_OVERRIDES.doctor);
|
|
5510
5797
|
}, "doctorCommand");
|
|
5511
5798
|
|
|
5512
|
-
// 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
|
|
5513
5800
|
var DAY6 = 864e5;
|
|
5514
5801
|
var SLOTS_EVERY = 7 * DAY6;
|
|
5515
5802
|
var isWindow = /* @__PURE__ */ __name((value) => typeof value?.from === "number" && typeof value.to === "number", "isWindow");
|
|
@@ -5589,10 +5876,10 @@ var calendarStatus = /* @__PURE__ */ __name(async (store, accountId, { profile,
|
|
|
5589
5876
|
return { items, page: 1, limit: Math.max(1, items.length), hasMore: false };
|
|
5590
5877
|
}, "calendarStatus");
|
|
5591
5878
|
|
|
5592
|
-
// 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
|
|
5593
5880
|
var FEED_LIMITS = { maxBytes: 10 * 1024 * 1024, timeoutMs: 3e4, redirects: 5 };
|
|
5594
5881
|
|
|
5595
|
-
// 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
|
|
5596
5883
|
var LIST = "events list";
|
|
5597
5884
|
var EVENT_TYPES = [
|
|
5598
5885
|
"default",
|
|
@@ -5669,7 +5956,7 @@ var accountsMeta = /* @__PURE__ */ __name(async (store, accounts, skipped, now)
|
|
|
5669
5956
|
};
|
|
5670
5957
|
}, "accountsMeta");
|
|
5671
5958
|
|
|
5672
|
-
// 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
|
|
5673
5960
|
var EVENTS_NOTIFY_KEY = "events.notify";
|
|
5674
5961
|
var EVENTS_DELETE_SERIES_KEY = "events.delete.series";
|
|
5675
5962
|
var EVENTS_REMIND_HOOK_KEY = "events.remind.hook";
|
|
@@ -5750,7 +6037,7 @@ var calendarOf = /* @__PURE__ */ __name((accounts, value) => {
|
|
|
5750
6037
|
throw new CliError("not_found", `calendar:${value} names no calendar in the accounts read`);
|
|
5751
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(", "));
|
|
5752
6039
|
}, "calendarOf");
|
|
5753
|
-
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");
|
|
5754
6041
|
var plusDays = /* @__PURE__ */ __name((date, days2) => {
|
|
5755
6042
|
const [year, month, day2] = date.split("-").map(Number);
|
|
5756
6043
|
return new Date(Date.UTC(year, month - 1, day2 + days2)).toISOString().slice(0, 10);
|
|
@@ -5884,7 +6171,11 @@ ${plainText(body, command)}`);
|
|
|
5884
6171
|
|
|
5885
6172
|
// dist/examples.js
|
|
5886
6173
|
var EXAMPLES = {
|
|
5887
|
-
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
|
+
],
|
|
5888
6179
|
show: [
|
|
5889
6180
|
"memo show chat:max/500/-1001 document:413",
|
|
5890
6181
|
"memo show note:12 msg:telegram/1/77/42 --json",
|
|
@@ -5915,6 +6206,10 @@ var EXAMPLES = {
|
|
|
5915
6206
|
"folders update": ["memo folders update 1 ~/notes"],
|
|
5916
6207
|
"folders remove": ["memo folders remove 1", "memo folders remove 1 --allow-delete --yes"],
|
|
5917
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"],
|
|
5918
6213
|
"config show": ["memo config show", "memo config show --json"],
|
|
5919
6214
|
"config migrate": ["memo config migrate"],
|
|
5920
6215
|
"config unset": ["memo config unset permissions.notes.edit"],
|
|
@@ -5974,7 +6269,7 @@ var EXAMPLES = {
|
|
|
5974
6269
|
],
|
|
5975
6270
|
"models list": ["memo models list kind:text --json"],
|
|
5976
6271
|
"commands info": ["memo commands info --json"],
|
|
5977
|
-
"models download": ["memo models download
|
|
6272
|
+
"models download": ["memo models download embeddinggemma", "memo models download e5-small"],
|
|
5978
6273
|
"models set": ["memo models set e5-large"],
|
|
5979
6274
|
"models consents show": ["memo models consents show --json"],
|
|
5980
6275
|
"models consents set": [
|
|
@@ -5982,6 +6277,8 @@ var EXAMPLES = {
|
|
|
5982
6277
|
"memo models consents set openai --model gpt-4o-mini --yes"
|
|
5983
6278
|
],
|
|
5984
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"],
|
|
5985
6282
|
"models add": [
|
|
5986
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: "}}'`
|
|
5987
6284
|
],
|
|
@@ -6038,8 +6335,12 @@ var EXAMPLES = {
|
|
|
6038
6335
|
"memo organizations rename 1 'Harbour Studio Ltd' --json"
|
|
6039
6336
|
],
|
|
6040
6337
|
"organizations show": ["memo organizations show organization:1"],
|
|
6041
|
-
"organizations list": [
|
|
6042
|
-
|
|
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"],
|
|
6043
6344
|
"projects meetings list": ["memo projects meetings list HRB --source zoom:me@example.com"],
|
|
6044
6345
|
"projects meetings link": ["memo projects meetings link HRB 31 --account zoom:me@example.com"],
|
|
6045
6346
|
"projects add": ["memo projects add 'Harbour' --key HRB --type client --organization 1"],
|
|
@@ -6063,12 +6364,20 @@ var EXAMPLES = {
|
|
|
6063
6364
|
"memo relationships update 12 --role approver --role-note 'signs the acts'"
|
|
6064
6365
|
],
|
|
6065
6366
|
"relationships add": [
|
|
6066
|
-
"memo relationships add person:3 organization:1 --role employee",
|
|
6067
|
-
"memo relationships add person:3
|
|
6068
|
-
"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"
|
|
6069
6375
|
],
|
|
6070
|
-
"relationships list": ['memo relationships list about:"person:3"', "memo relationships list confirmed:false"],
|
|
6071
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"],
|
|
6072
6381
|
"relationships confirm": ["memo relationships confirm 4"],
|
|
6073
6382
|
"relationships scan": [
|
|
6074
6383
|
"memo relationships scan HRB --source all",
|
|
@@ -6118,16 +6427,28 @@ var EXAMPLES = {
|
|
|
6118
6427
|
],
|
|
6119
6428
|
"deals list": ["memo deals list status:open project:HRB", "memo deals list stage:Quote --json"],
|
|
6120
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"],
|
|
6121
6432
|
"deals add": [
|
|
6122
6433
|
"memo deals add 'Site for the clinic' Call 500000.00 RUB --organization organization:3 --project HRB",
|
|
6123
6434
|
"memo deals add 'Support contract' Sales/Quote --person person:7 --role decision-maker --due 2026-12-01"
|
|
6124
6435
|
],
|
|
6125
|
-
"deals move": ["memo deals move deal:5 Quote"],
|
|
6436
|
+
"deals move": ["memo deals move deal:5 Quote", "memo deals move deal:5 stage:5"],
|
|
6126
6437
|
"deals close": ["memo deals close deal:5 won", "memo deals close deal:6 lost --reason 'chose a cheaper studio'"],
|
|
6127
6438
|
"leads list": ["memo leads list status:open"],
|
|
6128
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"],
|
|
6129
6442
|
"leads add": ["memo leads add 'Call from the site'", "memo leads add 'Clinic in Kazan' contacted --person person:9"],
|
|
6130
|
-
"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"],
|
|
6131
6452
|
"leads close": ["memo leads close lead:3 lost --reason 'no budget'"],
|
|
6132
6453
|
"orders add": [
|
|
6133
6454
|
"memo orders add 'Shop One' 2499.00 RUB --kind personal --title A-1042",
|
|
@@ -6364,8 +6685,8 @@ var EXAMPLES = {
|
|
|
6364
6685
|
help: ["memo help options", "memo help tasks agenda"]
|
|
6365
6686
|
};
|
|
6366
6687
|
var leaves = /* @__PURE__ */ __name((command, path = []) => command.commands.flatMap((child) => {
|
|
6367
|
-
const
|
|
6368
|
-
return child.commands.length ? leaves(child,
|
|
6688
|
+
const at2 = [...path, child.name()];
|
|
6689
|
+
return child.commands.length ? leaves(child, at2) : [[at2.join(" "), child]];
|
|
6369
6690
|
}), "leaves");
|
|
6370
6691
|
var addExamples = /* @__PURE__ */ __name((program) => {
|
|
6371
6692
|
for (const [path, command] of leaves(program)) {
|
|
@@ -6582,11 +6903,11 @@ var statusLine = /* @__PURE__ */ __name((data) => {
|
|
|
6582
6903
|
var personal = /* @__PURE__ */ __name((newest) => !newest.bulk && !newest.list && !newest.envelope && !newest.demoted, "personal");
|
|
6583
6904
|
var gatherDigest = /* @__PURE__ */ __name(async (store, env, { since, now: clock = Date.now(), until, limit, excerpt: excerpt2, owedWithin, newSince }) => {
|
|
6584
6905
|
const now = until ?? clock;
|
|
6585
|
-
const by = /* @__PURE__ */ __name((
|
|
6906
|
+
const by = /* @__PURE__ */ __name((at2) => until === void 0 || at2 <= until, "by");
|
|
6586
6907
|
const upTo = /* @__PURE__ */ __name((found) => found.filter((one2) => by(Date.parse(one2.item.at))), "upTo");
|
|
6587
6908
|
const window = (now - since) / DAY7;
|
|
6588
6909
|
const days2 = `${Math.max(1, Math.ceil(window))}d`;
|
|
6589
|
-
const accounts = await store
|
|
6910
|
+
const accounts = await scopedAccounts(store, env);
|
|
6590
6911
|
const messengers2 = accounts.filter((key) => MESSENGERS2.has(key.provider));
|
|
6591
6912
|
const mailboxes = accounts.filter((key) => key.provider === "email");
|
|
6592
6913
|
const owedSince = Math.min(since, now - owedWithin);
|
|
@@ -6723,7 +7044,7 @@ var gatherDigest = /* @__PURE__ */ __name(async (store, env, { since, now: clock
|
|
|
6723
7044
|
bulk++;
|
|
6724
7045
|
continue;
|
|
6725
7046
|
}
|
|
6726
|
-
const
|
|
7047
|
+
const pending = /* @__PURE__ */ __name((why) => ({
|
|
6727
7048
|
item: {
|
|
6728
7049
|
ref: ref(thread.threadId),
|
|
6729
7050
|
who: null,
|
|
@@ -6735,15 +7056,15 @@ var gatherDigest = /* @__PURE__ */ __name(async (store, env, { since, now: clock
|
|
|
6735
7056
|
}), "pending");
|
|
6736
7057
|
if (isWatchedChat(key, thread.threadId)) {
|
|
6737
7058
|
if (inWindow)
|
|
6738
|
-
watch.push(
|
|
7059
|
+
watch.push(pending("watched thread"));
|
|
6739
7060
|
} else if (mailTurn(last) === "owed") {
|
|
6740
7061
|
if (inWindow)
|
|
6741
|
-
owedMail.push({ pending:
|
|
7062
|
+
owedMail.push({ pending: pending("owed reply"), externalId: last.externalId });
|
|
6742
7063
|
else if (thread.lastEmailAt >= owedSince)
|
|
6743
7064
|
olderMail++;
|
|
6744
7065
|
owedHere++;
|
|
6745
7066
|
} else if (inWindow && !last.outgoing) {
|
|
6746
|
-
mail.push(
|
|
7067
|
+
mail.push(pending("new mail"));
|
|
6747
7068
|
newHere++;
|
|
6748
7069
|
}
|
|
6749
7070
|
}
|
|
@@ -6992,16 +7313,16 @@ var sinceOf = /* @__PURE__ */ __name((value, now = Date.now()) => {
|
|
|
6992
7313
|
return since;
|
|
6993
7314
|
}, "sinceOf");
|
|
6994
7315
|
var beforeOf = /* @__PURE__ */ __name((value, now = Date.now()) => {
|
|
6995
|
-
const
|
|
6996
|
-
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))
|
|
6997
7318
|
throw new CliError("validation_error", `--before-time takes an ISO time or a date, not "${value}"`, {
|
|
6998
7319
|
param: "before-time"
|
|
6999
7320
|
});
|
|
7000
|
-
if (
|
|
7321
|
+
if (at2 > now)
|
|
7001
7322
|
throw new CliError("validation_error", "--before-time is in the future; leave it out for now", {
|
|
7002
7323
|
param: "before-time"
|
|
7003
7324
|
});
|
|
7004
|
-
return
|
|
7325
|
+
return at2;
|
|
7005
7326
|
}, "beforeOf");
|
|
7006
7327
|
var reviewAgendaCommand = /* @__PURE__ */ __name((review, print, streams, env) => {
|
|
7007
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) => {
|
|
@@ -7096,7 +7417,7 @@ var challengeCommand = /* @__PURE__ */ __name((parent, type, streams, env) => {
|
|
|
7096
7417
|
by,
|
|
7097
7418
|
...options.suggest === void 0 ? {} : { suggestion: options.suggest }
|
|
7098
7419
|
});
|
|
7099
|
-
return itemAnswer(await
|
|
7420
|
+
return itemAnswer(await reviewItemOf(store, proposal.id));
|
|
7100
7421
|
});
|
|
7101
7422
|
});
|
|
7102
7423
|
}, "challengeCommand");
|
|
@@ -7122,11 +7443,11 @@ var memoriesCommand = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
7122
7443
|
...options.supersedes === void 0 ? {} : { supersedes: options.supersedes }
|
|
7123
7444
|
}, await by).catch(explainQuote))));
|
|
7124
7445
|
});
|
|
7125
|
-
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)));
|
|
7126
|
-
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, {
|
|
7127
7448
|
...memoryItem(await store.memories.get(ref)),
|
|
7128
|
-
...options.sources ?
|
|
7129
|
-
})));
|
|
7449
|
+
...options.sources ? await sourcesIn(store, env, await store.memories.sources(ref)) : {}
|
|
7450
|
+
}))));
|
|
7130
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, {
|
|
7131
7452
|
project: options.project === "none" ? null : await canonicalProject(store, options.project)
|
|
7132
7453
|
})))));
|
|
@@ -7144,7 +7465,7 @@ var memoriesCommand = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
7144
7465
|
const decided = /* @__PURE__ */ __name(async (store, ref, by, confirm) => {
|
|
7145
7466
|
if ((await store.memories.get(ref)).status !== "proposed")
|
|
7146
7467
|
return confirm ? store.memories.confirm(ref, by) : store.memories.markStale(ref, by);
|
|
7147
|
-
await decideOne(store, ref, { confirm, by });
|
|
7468
|
+
await decideOne(store, env, ref, { confirm, by });
|
|
7148
7469
|
return store.memories.get(ref);
|
|
7149
7470
|
}, "decided");
|
|
7150
7471
|
decide2("confirm", "stand behind a memory: its evidence was checked now", (store, ref, by) => decided(store, ref, by, true));
|
|
@@ -7244,11 +7565,11 @@ var factsCommand = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
7244
7565
|
...options.supersedes === void 0 ? {} : { supersedes: options.supersedes }
|
|
7245
7566
|
}).catch(explainQuote))));
|
|
7246
7567
|
});
|
|
7247
|
-
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)));
|
|
7248
|
-
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, {
|
|
7249
7570
|
...factItem(await store.facts.get(ref)),
|
|
7250
|
-
...options.sources ?
|
|
7251
|
-
})));
|
|
7571
|
+
...options.sources ? await sourcesIn(store, env, await store.facts.sources(ref)) : {}
|
|
7572
|
+
}))));
|
|
7252
7573
|
const decide2 = /* @__PURE__ */ __name((name2, description, act) => reasonOption(byOption(annotate(facts.command(name2), {
|
|
7253
7574
|
effects: LOCAL_WRITE,
|
|
7254
7575
|
...name2 === "remove" ? {} : { output: { entity: "fact" } }
|
|
@@ -7261,13 +7582,13 @@ var factsCommand = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
7261
7582
|
});
|
|
7262
7583
|
}), "decide");
|
|
7263
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) => {
|
|
7264
|
-
await decideOne(store, ref, decisionOf(true, by, why));
|
|
7585
|
+
await decideOne(store, env, ref, decisionOf(true, by, why));
|
|
7265
7586
|
return store.facts.get(ref);
|
|
7266
7587
|
}).summary("stand behind a fact an agent proposed");
|
|
7267
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");
|
|
7268
7589
|
decide2("reverse", "an accepted decision no longer holds, and nothing replaced it", (store, ref, by) => store.facts.reverse(ref, by));
|
|
7269
7590
|
decide2("reject", "turn down a fact an agent proposed; it stays, marked rejected", async (store, ref, by, why) => {
|
|
7270
|
-
await decideOne(store, ref, decisionOf(false, by, why));
|
|
7591
|
+
await decideOne(store, env, ref, decisionOf(false, by, why));
|
|
7271
7592
|
return store.facts.get(ref);
|
|
7272
7593
|
});
|
|
7273
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", `
|
|
@@ -7294,7 +7615,7 @@ var SOURCED = new Set(Object.keys(READS));
|
|
|
7294
7615
|
var readSourced = /* @__PURE__ */ __name((store, kind, ref) => READS[kind]?.(store, ref), "readSourced");
|
|
7295
7616
|
var IMPORT = "import:";
|
|
7296
7617
|
var imported = /* @__PURE__ */ __name(({ source, account: account2 }) => (account2 ?? null) !== null || !!source?.startsWith(IMPORT), "imported");
|
|
7297
|
-
var
|
|
7618
|
+
var sourceAccounts2 = /* @__PURE__ */ __name(async (store, { source, account: account2 }) => {
|
|
7298
7619
|
if (account2)
|
|
7299
7620
|
return [account2];
|
|
7300
7621
|
if (!source?.startsWith(IMPORT))
|
|
@@ -7309,7 +7630,7 @@ var named2 = /* @__PURE__ */ __name((key) => ({
|
|
|
7309
7630
|
var sourcesOf = /* @__PURE__ */ __name(async (store, entity) => {
|
|
7310
7631
|
const { ref } = entity;
|
|
7311
7632
|
const records = [];
|
|
7312
|
-
for (const { provider, account: account2 } of await
|
|
7633
|
+
for (const { provider, account: account2 } of await sourceAccounts2(store, entity)) {
|
|
7313
7634
|
if (records.length > MOST)
|
|
7314
7635
|
break;
|
|
7315
7636
|
for (const one2 of await store.records.list({ provider, account: account2, entity: ref, limit: MOST + 1 }))
|
|
@@ -7654,6 +7975,46 @@ var contractCommands = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
7654
7975
|
});
|
|
7655
7976
|
}, "contractCommands");
|
|
7656
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
|
+
|
|
7657
8018
|
// dist/finance/deals-command.js
|
|
7658
8019
|
var queryOf = /* @__PURE__ */ __name((entity) => ({
|
|
7659
8020
|
entity,
|
|
@@ -7672,7 +8033,14 @@ var PIPELINE_QUERY = {
|
|
|
7672
8033
|
backend: "native",
|
|
7673
8034
|
fields: [termField("kind", "enum", "kind:lead", { values: DEAL_KINDS }), termField("name", "kw", "name:Sales")]
|
|
7674
8035
|
};
|
|
7675
|
-
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) => {
|
|
7676
8044
|
const command = `${kind}s list`;
|
|
7677
8045
|
const terms2 = queryTerms(words, QUERIES[kind], command);
|
|
7678
8046
|
const filter = {
|
|
@@ -7683,8 +8051,21 @@ var listDeals = /* @__PURE__ */ __name(async (store, kind, words, limit) => {
|
|
|
7683
8051
|
...terms2.has("pipeline") ? { pipeline: terms2.get("pipeline") } : {},
|
|
7684
8052
|
...terms2.has("organization") ? { organization: terms2.get("organization") } : {}
|
|
7685
8053
|
};
|
|
7686
|
-
|
|
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));
|
|
7687
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");
|
|
7688
8069
|
var roleOf = /* @__PURE__ */ __name((role) => {
|
|
7689
8070
|
const value = role ?? "contact";
|
|
7690
8071
|
if (!DEAL_ROLES.includes(value))
|
|
@@ -7695,18 +8076,38 @@ var referenceOf = /* @__PURE__ */ __name((kind, value) => /^\d+$/.test(value.tri
|
|
|
7695
8076
|
var stageOf = /* @__PURE__ */ __name((stage) => {
|
|
7696
8077
|
if (stage === void 0)
|
|
7697
8078
|
return {};
|
|
7698
|
-
const
|
|
7699
|
-
return
|
|
8079
|
+
const at2 = stage.lastIndexOf("/");
|
|
8080
|
+
return at2 <= 0 ? { stage } : { pipeline: stage.slice(0, at2), stage: stage.slice(at2 + 1) };
|
|
7700
8081
|
}, "stageOf");
|
|
7701
8082
|
var WHAT = {
|
|
7702
8083
|
deal: { one: "deal", hope: "what you hope to sell, such as 'Site for the clinic'" },
|
|
7703
8084
|
lead: { one: "lead", hope: "who or what came in, such as 'Call from the site'" }
|
|
7704
8085
|
};
|
|
7705
|
-
var itemCommands = /* @__PURE__ */ __name((program, kind, run, env) => {
|
|
8086
|
+
var itemCommands = /* @__PURE__ */ __name((program, kind, { run, print }, env) => {
|
|
7706
8087
|
const { one: one2, hope } = WHAT[kind];
|
|
7707
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");
|
|
7708
|
-
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)));
|
|
7709
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
|
+
});
|
|
7710
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) => {
|
|
7711
8112
|
const by = authorOf(env);
|
|
7712
8113
|
const role = roleOf(options.role);
|
|
@@ -7728,9 +8129,9 @@ var itemCommands = /* @__PURE__ */ __name((program, kind, run, env) => {
|
|
|
7728
8129
|
}));
|
|
7729
8130
|
});
|
|
7730
8131
|
});
|
|
7731
|
-
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) => {
|
|
7732
8133
|
const by = authorOf(env);
|
|
7733
|
-
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 })));
|
|
7734
8135
|
});
|
|
7735
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) => {
|
|
7736
8137
|
if (outcome !== "won" && outcome !== "lost")
|
|
@@ -7751,6 +8152,21 @@ var funnelText = /* @__PURE__ */ __name((report) => [
|
|
|
7751
8152
|
...report.stages.map((stage) => ` ${stage.position}. ${stage.name}${stage.outcome === "open" ? "" : ` [${stage.outcome}]`}: ${stage.open} open, ${stage.reached} reached${percent(stage.conversion)}`),
|
|
7752
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)}%`)
|
|
7753
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");
|
|
7754
8170
|
var dealCommands = /* @__PURE__ */ __name((program, streams, env) => {
|
|
7755
8171
|
const { run, print } = answers(program, streams, env);
|
|
7756
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");
|
|
@@ -7758,15 +8174,17 @@ var dealCommands = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
7758
8174
|
const terms2 = queryTerms(words, PIPELINE_QUERY, "pipelines list");
|
|
7759
8175
|
const name2 = terms2.get("name")?.toLocaleLowerCase();
|
|
7760
8176
|
const kind = terms2.get("kind");
|
|
7761
|
-
const
|
|
7762
|
-
|
|
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));
|
|
7763
8181
|
}));
|
|
7764
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) => {
|
|
7765
8183
|
const since = dayOf2(options.sinceTime);
|
|
7766
|
-
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 })));
|
|
7767
8185
|
print(options.json, itemAnswer(report), funnelText(report));
|
|
7768
8186
|
});
|
|
7769
|
-
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) => {
|
|
7770
8188
|
const kind = options.kind ?? "deal";
|
|
7771
8189
|
if (!DEAL_KINDS.includes(kind))
|
|
7772
8190
|
throw new CliError("validation_error", "--kind is deal or lead", { param: "--kind" });
|
|
@@ -7774,15 +8192,24 @@ var dealCommands = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
7774
8192
|
await run(options.json, async (store) => itemAnswer(await store.deals.addPipeline({
|
|
7775
8193
|
name: name2,
|
|
7776
8194
|
kind,
|
|
7777
|
-
stages:
|
|
8195
|
+
stages: stages2.map((stage) => {
|
|
7778
8196
|
const word = stage.trim().toLocaleLowerCase();
|
|
7779
8197
|
return word === "won" || word === "lost" ? { name: stage, outcome: word } : stage;
|
|
7780
8198
|
}),
|
|
7781
8199
|
by
|
|
7782
8200
|
})));
|
|
7783
8201
|
});
|
|
7784
|
-
itemCommands(program, "deal", run, env);
|
|
7785
|
-
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);
|
|
7786
8213
|
}, "dealCommands");
|
|
7787
8214
|
var STATUS_DEALS = 5;
|
|
7788
8215
|
var openDealsOf = /* @__PURE__ */ __name(async (store, projects) => {
|
|
@@ -8130,7 +8557,7 @@ var listWallets = /* @__PURE__ */ __name(async (store, words, limit) => {
|
|
|
8130
8557
|
var sourceSays = /* @__PURE__ */ __name(async (store, wallet) => {
|
|
8131
8558
|
if (wallet.openingBalance !== null)
|
|
8132
8559
|
return null;
|
|
8133
|
-
for (const { provider, account: account2 } of await
|
|
8560
|
+
for (const { provider, account: account2 } of await sourceAccounts2(store, wallet)) {
|
|
8134
8561
|
const [record2] = await store.records.list({ provider, account: account2, entity: wallet.ref, limit: 1 });
|
|
8135
8562
|
const { opening_balance: balance, opening_date: date } = record2?.fields ?? {};
|
|
8136
8563
|
if (record2 && typeof balance === "string")
|
|
@@ -8256,15 +8683,15 @@ var findingsCommand = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
8256
8683
|
|
|
8257
8684
|
// dist/json-fields.js
|
|
8258
8685
|
var commandIn = /* @__PURE__ */ __name((root, words) => {
|
|
8259
|
-
let
|
|
8686
|
+
let at2 = root;
|
|
8260
8687
|
for (const word of words) {
|
|
8261
8688
|
if (word.startsWith("-"))
|
|
8262
8689
|
continue;
|
|
8263
|
-
const child =
|
|
8690
|
+
const child = at2.commands.find((command) => command.name() === word || command.aliases().includes(word));
|
|
8264
8691
|
if (child)
|
|
8265
|
-
|
|
8692
|
+
at2 = child;
|
|
8266
8693
|
}
|
|
8267
|
-
return
|
|
8694
|
+
return at2 === root ? void 0 : at2;
|
|
8268
8695
|
}, "commandIn");
|
|
8269
8696
|
var keep = /* @__PURE__ */ __name((text3, paths) => {
|
|
8270
8697
|
let value;
|
|
@@ -8359,6 +8786,27 @@ var meetingProjectsCommand = /* @__PURE__ */ __name((projects, streams, env) =>
|
|
|
8359
8786
|
})), true));
|
|
8360
8787
|
}, "meetingProjectsCommand");
|
|
8361
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
|
+
|
|
8362
8810
|
// dist/knowledge/project-actions.js
|
|
8363
8811
|
var evidenceContext = /* @__PURE__ */ __name(async (store, ref, fingerprint, words, window) => {
|
|
8364
8812
|
const record2 = await store.contextRecords?.read(ref);
|
|
@@ -8418,14 +8866,14 @@ var projectActions = /* @__PURE__ */ __name(async (store, project, options) => {
|
|
|
8418
8866
|
hasMore: found.hasMore
|
|
8419
8867
|
};
|
|
8420
8868
|
}, "projectActions");
|
|
8421
|
-
var decideAction = /* @__PURE__ */ __name(async (store, project, id, decision) => {
|
|
8869
|
+
var decideAction = /* @__PURE__ */ __name(async (store, env, project, id, decision) => {
|
|
8422
8870
|
if (!/^(key:)?[1-9]\d*$/.test(id))
|
|
8423
8871
|
throw new CliError("validation_error", "an action ID is a batch number or key:<id>");
|
|
8424
8872
|
const row = await proposalRegistry(store).get(id);
|
|
8425
8873
|
if (row.project !== project.ref || row.kind !== "key_document" && row.kind !== "findings")
|
|
8426
8874
|
throw new CliError("not_found", `no proposal ${id} in ${project.ref}; memo projects actions list shows them`);
|
|
8427
8875
|
if (row.kind === "key_document") {
|
|
8428
|
-
await decideOne(store, id, decisionOf(decision.confirm, decision.by, decision.reason));
|
|
8876
|
+
await decideOne(store, env, id, decisionOf(decision.confirm, decision.by, decision.reason));
|
|
8429
8877
|
return { id, kind: "key_document", ref: row.subject, confirmed: decision.confirm, decided_by: decision.by };
|
|
8430
8878
|
}
|
|
8431
8879
|
if (decision.fingerprint === void 0)
|
|
@@ -8504,7 +8952,7 @@ var projectActionsCommand = /* @__PURE__ */ __name((projects, streams, env) => {
|
|
|
8504
8952
|
const by = await deciderOf(command, env, { ...given2, question: `${name2} ${id} as you, the owner?` });
|
|
8505
8953
|
await run(given2.json, async (store) => {
|
|
8506
8954
|
const project = await projectOf(store, reference2);
|
|
8507
|
-
return itemAnswer(await decideAction(store, project, id, {
|
|
8955
|
+
return itemAnswer(await decideAction(store, env, project, id, {
|
|
8508
8956
|
confirm: name2 === "confirm",
|
|
8509
8957
|
...given2.fingerprint === void 0 ? {} : { fingerprint: given2.fingerprint },
|
|
8510
8958
|
...given2.reason === void 0 ? {} : { reason: given2.reason },
|
|
@@ -8558,15 +9006,17 @@ var projectFindings = /* @__PURE__ */ __name(async (store, project, links) => {
|
|
|
8558
9006
|
// dist/knowledge/project-context.js
|
|
8559
9007
|
var projectContext = /* @__PURE__ */ __name(async (store, env, reference2) => {
|
|
8560
9008
|
const project = await projectOf(store, reference2);
|
|
8561
|
-
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);
|
|
8562
9011
|
const documents = await keyDocuments(store, project);
|
|
8563
|
-
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");
|
|
8564
9014
|
const [facts, tasks, findings, keys, links, waiting2] = await Promise.all([
|
|
8565
9015
|
store.facts.list({ project: project.ref, status: "proposed", limit: 21 }),
|
|
8566
9016
|
store.tasks.find({ project: project.ref, status: "open", limit: 21 }),
|
|
8567
9017
|
projectFindings(store, project.ref, relationships),
|
|
8568
|
-
|
|
8569
|
-
|
|
9018
|
+
pending("key_document"),
|
|
9019
|
+
pending("relationship"),
|
|
8570
9020
|
waitingAbout(store, env, [project.ref])
|
|
8571
9021
|
]);
|
|
8572
9022
|
const label = await labelsFor(store, [...keys.items, ...links.items].flatMap((row) => [row.subject, row.object]));
|
|
@@ -8761,7 +9211,7 @@ var projectGatherCommand = /* @__PURE__ */ __name((projects, print, env, warn) =
|
|
|
8761
9211
|
...found,
|
|
8762
9212
|
linkedChats: found.linkedChats.map((one2, i) => ({ ...one2, syncCommand: syncs[i]?.command ?? null }))
|
|
8763
9213
|
}, { ...parts2, ...missing.length ? { missing } : {}, ...next.length ? { next } : {} }), projectEvidenceText(found, {
|
|
8764
|
-
sync: /* @__PURE__ */ __name((chat,
|
|
9214
|
+
sync: /* @__PURE__ */ __name((chat, at2) => syncHint(chat, at2, env, chosen), "sync"),
|
|
8765
9215
|
showDocument: "memo notes show"
|
|
8766
9216
|
}));
|
|
8767
9217
|
})
|
|
@@ -8801,7 +9251,7 @@ var outside = /* @__PURE__ */ __name((blocked) => (step, found) => {
|
|
|
8801
9251
|
};
|
|
8802
9252
|
}, "outside");
|
|
8803
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");
|
|
8804
|
-
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) => {
|
|
8805
9255
|
if (options.compact && options.json)
|
|
8806
9256
|
throw new CliError("validation_error", "--compact and --json ask for different output \u2014 pick one", {
|
|
8807
9257
|
reason: "output.conflict",
|
|
@@ -8809,8 +9259,10 @@ var projectStatusCommand = /* @__PURE__ */ __name((projects, print, env) => answ
|
|
|
8809
9259
|
});
|
|
8810
9260
|
const chosen = options.syncProfile ?? {};
|
|
8811
9261
|
const { found, finance, open: open2 } = await withStore(env, async (store) => {
|
|
9262
|
+
const scope = await groupScopeOf(store, env);
|
|
8812
9263
|
const status = await projectStatus(store, {
|
|
8813
9264
|
project,
|
|
9265
|
+
...scope === void 0 ? {} : { accounts: scope.accounts },
|
|
8814
9266
|
...projectWindowOf(options.sinceTime),
|
|
8815
9267
|
...options.beforeTime === void 0 ? {} : { asOf: projectCutoffTime(options.beforeTime) },
|
|
8816
9268
|
contextQueries: options.contextQuery,
|
|
@@ -8827,8 +9279,15 @@ var projectStatusCommand = /* @__PURE__ */ __name((projects, print, env) => answ
|
|
|
8827
9279
|
read: /* @__PURE__ */ __name((chat, since) => step("messages.list", chatRead(linked(chat), since, env, chosen)), "read"),
|
|
8828
9280
|
line: /* @__PURE__ */ __name((one2) => one2.kind === "command" ? one2.line ?? one2.command : one2.why, "line")
|
|
8829
9281
|
};
|
|
8830
|
-
const
|
|
8831
|
-
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
|
+
];
|
|
8832
9291
|
print(options.json, itemOf({
|
|
8833
9292
|
...item,
|
|
8834
9293
|
...finance.length ? { finance } : {},
|
|
@@ -8838,7 +9297,7 @@ var projectStatusCommand = /* @__PURE__ */ __name((projects, print, env) => answ
|
|
|
8838
9297
|
...next.length ? { next: next.map(asAction) } : {},
|
|
8839
9298
|
...gaps.length ? { missing: gaps } : {},
|
|
8840
9299
|
meta
|
|
8841
|
-
}), [projectStatusText(
|
|
9300
|
+
}), [projectStatusText(shown3, hints), ...financeText(finance), ...dealsText(open2)].join("\n"), options.compact === true);
|
|
8842
9301
|
}), "projectStatusCommand");
|
|
8843
9302
|
|
|
8844
9303
|
// dist/knowledge/project-transfer.js
|
|
@@ -8971,73 +9430,142 @@ var RELATIONSHIP_QUERY = {
|
|
|
8971
9430
|
entity: "relationship",
|
|
8972
9431
|
backend: "native",
|
|
8973
9432
|
fields: [
|
|
8974
|
-
termField("about", "ref", 'about:"
|
|
8975
|
-
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"
|
|
8976
9435
|
}),
|
|
8977
|
-
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"] })
|
|
8978
9444
|
]
|
|
8979
9445
|
};
|
|
8980
|
-
var
|
|
8981
|
-
var
|
|
8982
|
-
const
|
|
8983
|
-
|
|
8984
|
-
|
|
8985
|
-
|
|
8986
|
-
|
|
8987
|
-
|
|
8988
|
-
|
|
8989
|
-
|
|
8990
|
-
one2.id,
|
|
8991
|
-
one2.payload ?? {}
|
|
8992
|
-
]));
|
|
8993
|
-
const rows = found.items.filter((row) => about === void 0 || row.subject === about || row.object === about);
|
|
8994
|
-
return {
|
|
8995
|
-
hasMore: found.hasMore,
|
|
8996
|
-
items: rows.map((row) => ({
|
|
8997
|
-
id: row.id,
|
|
8998
|
-
from: row.subject,
|
|
8999
|
-
to: row.object,
|
|
9000
|
-
kind: payloads.get(row.id)?.kind ?? null,
|
|
9001
|
-
role: row.summary,
|
|
9002
|
-
purpose: payloads.get(row.id)?.purpose ?? null,
|
|
9003
|
-
evidence: row.reason,
|
|
9004
|
-
confirmed: false,
|
|
9005
|
-
status: "proposed",
|
|
9006
|
-
proposer: proposerName(row.proposedBy),
|
|
9007
|
-
score: row.score,
|
|
9008
|
-
createdAt: row.createdAt
|
|
9009
|
-
}))
|
|
9010
|
-
};
|
|
9011
|
-
}, "pending");
|
|
9012
|
-
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 }) => {
|
|
9013
9456
|
const terms2 = queryTerms(words, RELATIONSHIP_QUERY, "relationships list");
|
|
9014
|
-
const about = terms2.get("about");
|
|
9015
9457
|
const confirmed = terms2.get("confirmed");
|
|
9016
|
-
const
|
|
9017
|
-
|
|
9018
|
-
|
|
9019
|
-
|
|
9020
|
-
|
|
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]));
|
|
9021
9480
|
return {
|
|
9022
9481
|
hasMore: found.hasMore,
|
|
9023
|
-
limit
|
|
9024
|
-
|
|
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
|
+
})))
|
|
9025
9492
|
};
|
|
9026
9493
|
}, "listRelationships");
|
|
9027
9494
|
var relationshipsText = /* @__PURE__ */ __name((items) => items.length ? items.map((one2) => [
|
|
9028
9495
|
one2.id,
|
|
9029
9496
|
`${one2.fromTitle} \u2192 ${one2.toTitle}`,
|
|
9030
9497
|
[
|
|
9031
|
-
one2.kind,
|
|
9032
|
-
one2.role && `as ${one2.role}`,
|
|
9498
|
+
one2.direction === "incoming" ? one2.inverse ?? one2.kind : one2.kind,
|
|
9499
|
+
one2.role && `as ${one2.role}${one2.custom ? " (custom)" : ""}`,
|
|
9033
9500
|
"roleNote" in one2 && one2.roleNote && `(${one2.roleNote})`,
|
|
9501
|
+
one2.position && `(${one2.position})`,
|
|
9034
9502
|
one2.purpose && `for ${one2.purpose}`,
|
|
9035
9503
|
"engagement" in one2 && one2.engagement && `engagement ${one2.engagement}`
|
|
9036
9504
|
].filter(Boolean).join(" "),
|
|
9037
|
-
"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(" ")
|
|
9038
9506
|
].filter(Boolean).join(" ")).join("\n") : "no relationships", "relationshipsText");
|
|
9039
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
|
+
|
|
9040
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");
|
|
9041
9569
|
var pendingLink = /* @__PURE__ */ __name(async (store, id) => {
|
|
9042
9570
|
try {
|
|
9043
9571
|
return await proposalRegistry(store).get(`link:${id}`);
|
|
@@ -9054,17 +9582,6 @@ var knowledgeCommands = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
9054
9582
|
const act = /* @__PURE__ */ __name((options, work) => run(options.json, async (store) => work(store, await writeAccount(store, env, options, warn))), "act");
|
|
9055
9583
|
const owned = /* @__PURE__ */ __name((options, work) => run(options.json, async (store) => itemAnswer(await work(store))), "owned");
|
|
9056
9584
|
const ownedList = /* @__PURE__ */ __name((command, options, work) => run(options.json, async (store) => wholeList(command, await work(store))), "ownedList");
|
|
9057
|
-
const contextOf = /* @__PURE__ */ __name(async (store, thing, type, reference2) => {
|
|
9058
|
-
if (thing === void 0)
|
|
9059
|
-
throw new CliError("not_found", `no ${type} ${reference2}; memo ${type}s list shows them`);
|
|
9060
|
-
const { id } = thing;
|
|
9061
|
-
return {
|
|
9062
|
-
[type]: thing,
|
|
9063
|
-
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"),
|
|
9064
|
-
notes: await notesAbout(store, { ref: `${type}:${id}` }),
|
|
9065
|
-
tags: await store.knowledge.tags(null, { type, id })
|
|
9066
|
-
};
|
|
9067
|
-
}, "contextOf");
|
|
9068
9585
|
const organizations = program.command("organizations").description("companies, teams, families and communities of yours");
|
|
9069
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({
|
|
9070
9587
|
kind: options.kind,
|
|
@@ -9079,14 +9596,38 @@ var knowledgeCommands = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
9079
9596
|
throw new CliError("not_found", `no organization ${reference2}; memo organizations list shows them`);
|
|
9080
9597
|
return found;
|
|
9081
9598
|
}));
|
|
9082
|
-
withQuery(annotate(organizations.command("list"), { effects: LOCAL_READ }),
|
|
9083
|
-
const
|
|
9084
|
-
|
|
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));
|
|
9085
9630
|
});
|
|
9086
|
-
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) => {
|
|
9087
|
-
const wanted = reference2.replace(/^organization:/, "");
|
|
9088
|
-
return contextOf(store, (await store.knowledge.organizations()).find((organization) => organization.id === wanted), "organization", reference2);
|
|
9089
|
-
}));
|
|
9090
9631
|
const projects = program.command("projects").description("projects of yours, each with a short key");
|
|
9091
9632
|
meetingProjectsCommand(projects, streams, env);
|
|
9092
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({
|
|
@@ -9102,7 +9643,7 @@ var knowledgeCommands = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
9102
9643
|
});
|
|
9103
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) => {
|
|
9104
9645
|
const { context, next } = await withStore(env, async (store) => {
|
|
9105
|
-
const context2 = await projectContext(store, env, reference2);
|
|
9646
|
+
const context2 = await stripped(store, env, await projectContext(store, env, reference2));
|
|
9106
9647
|
return { context: context2, next: await scanStep(store, context2.project, "all") };
|
|
9107
9648
|
});
|
|
9108
9649
|
print(options.json, itemAnswer(context, next.length ? { next } : {}), projectContextText(context));
|
|
@@ -9125,7 +9666,7 @@ var knowledgeCommands = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
9125
9666
|
return ownedList("projects key-documents list", options, async (store) => keyDocuments(store, await projectOf(store, project), id === void 0 ? {} : { id }));
|
|
9126
9667
|
});
|
|
9127
9668
|
const relations = program.command("relationships").description("relations between people, organizations and projects; never between identities");
|
|
9128
|
-
byOption(annotate(relations.command("add"), { effects: LOCAL_WRITE }).description("state that a person, organization or project belongs to or relates to another, or that a chat is a project's (member-of only); an agent's waits for you to confirm it").summary("state that a person, organization, project or chat belongs or relates to another")).argument("<from>", "the person:, organization: or project: that belongs or relates, or chat:<provider>/<account>/<chat> of a project").argument("<to>", "the person:, organization: or project: it belongs or relates to").option("--json", "print JSON; --json=id,title keeps only those fields").option("--kind <kind>", "
|
|
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) => {
|
|
9129
9670
|
const by = await whoRuns(command, env, { asOwner: options.asOwner, question: "state it as yours?" });
|
|
9130
9671
|
return owned(options, async (store) => {
|
|
9131
9672
|
const input = {
|
|
@@ -9135,27 +9676,46 @@ var knowledgeCommands = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
9135
9676
|
...options.role === void 0 ? {} : { role: options.role },
|
|
9136
9677
|
...options.roleNote === void 0 ? {} : { roleNote: options.roleNote },
|
|
9137
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 },
|
|
9138
9682
|
...options.reason === void 0 ? {} : { evidence: options.reason }
|
|
9139
9683
|
};
|
|
9140
9684
|
return by === "owner" ? store.knowledge.relate(null, { ...input, by }) : store.knowledge.relate(null, { ...input, by });
|
|
9141
9685
|
});
|
|
9142
9686
|
});
|
|
9143
|
-
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) => {
|
|
9144
|
-
const found = await withStore(env, (store) =>
|
|
9145
|
-
|
|
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));
|
|
9146
9704
|
});
|
|
9147
|
-
byOption(annotate(relations.command("update"), { effects: LOCAL_WRITE }).description("set what a relationship is: its role and a note beside it, how much you deal with a person on a project, or what a chat is for in a project (work, sales, support, other); an agent's change waits for you in memo review").summary("set a relationship's role, engagement or a chat's purpose in a project").argument("<id>", "the relationship's id, as relationships list gives it").option("--role <role>",
|
|
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) => {
|
|
9148
9706
|
const cleared = /* @__PURE__ */ __name((value) => value === "" ? null : value, "cleared");
|
|
9149
9707
|
const change = {
|
|
9150
9708
|
...options.role === void 0 ? {} : { role: cleared(options.role) },
|
|
9151
9709
|
...options.roleNote === void 0 ? {} : { roleNote: cleared(options.roleNote) },
|
|
9152
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 },
|
|
9153
9713
|
...options.purpose === void 0 ? {} : { purpose: options.purpose }
|
|
9154
9714
|
};
|
|
9155
9715
|
const by = await whoRuns(command, env, { asOwner: options.asOwner, question: `change relationship ${id}?` });
|
|
9156
|
-
return owned(options, (store) => {
|
|
9157
|
-
if (
|
|
9158
|
-
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", {
|
|
9159
9719
|
reason: "input.invalid",
|
|
9160
9720
|
param: "--purpose"
|
|
9161
9721
|
});
|
|
@@ -9181,12 +9741,20 @@ var knowledgeCommands = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
9181
9741
|
const suggestion = await pendingLink(store, id);
|
|
9182
9742
|
if (suggestion === void 0)
|
|
9183
9743
|
return name2 === "remove" ? store.knowledge.removeRelation(null, id, by) : store.knowledge.confirmRelation(null, id, by);
|
|
9184
|
-
await decideOne(store, suggestion.id, decisionOf(name2 === "confirm", by, options.reason));
|
|
9744
|
+
await decideOne(store, env, suggestion.id, decisionOf(name2 === "confirm", by, options.reason));
|
|
9185
9745
|
if (name2 === "remove")
|
|
9186
9746
|
return { id, removed: true };
|
|
9187
9747
|
return (await store.knowledge.relations(null, suggestion.subject)).find((one2) => one2.id === id);
|
|
9188
9748
|
});
|
|
9189
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);
|
|
9190
9758
|
relationshipsScanCommand(relations, print, env, warn);
|
|
9191
9759
|
const reminders = program.command("reminders").description("durable local reminders; poll hands one out and ack confirms it was shown");
|
|
9192
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) => {
|
|
@@ -9633,10 +10201,10 @@ var mcpCommandDefinition = /* @__PURE__ */ __name((program, streams, env, create
|
|
|
9633
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) => {
|
|
9634
10202
|
if (!options.http && (options.port !== void 0 || options.publicUrl !== void 0))
|
|
9635
10203
|
throw new CliError("validation_error", "--port and --public-url require --http");
|
|
9636
|
-
const { createMemoServer } = await import("./server-
|
|
10204
|
+
const { createMemoServer } = await import("./server-LWQAHDBH.js");
|
|
9637
10205
|
const build = /* @__PURE__ */ __name(() => createMemoServer(env, createProgram2, options.permission), "build");
|
|
9638
10206
|
if (options.http) {
|
|
9639
|
-
const { httpLockFile, mcpUrlOf, portOf, publicUrlOf, serveOverHttp } = await import("./mcp-
|
|
10207
|
+
const { httpLockFile, mcpUrlOf, portOf, publicUrlOf, serveOverHttp } = await import("./mcp-FQPK2KAF.js");
|
|
9640
10208
|
const publicUrl = publicUrlOf(options.publicUrl, {
|
|
9641
10209
|
missing: "--http",
|
|
9642
10210
|
reaches: "the browser apps reach memo",
|
|
@@ -9688,7 +10256,7 @@ var mcpCommandDefinition = /* @__PURE__ */ __name((program, streams, env, create
|
|
|
9688
10256
|
});
|
|
9689
10257
|
});
|
|
9690
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() {
|
|
9691
|
-
const { revokeAll } = await import("./mcp-
|
|
10259
|
+
const { revokeAll } = await import("./mcp-FQPK2KAF.js");
|
|
9692
10260
|
revokeAll(httpTokenFile(env));
|
|
9693
10261
|
out.print(this.opts().json, itemAnswer({ revoked: true }));
|
|
9694
10262
|
});
|
|
@@ -9963,7 +10531,7 @@ may be ${found.candidates.join(", ")}` : ""));
|
|
|
9963
10531
|
}, "mentionsCommand");
|
|
9964
10532
|
|
|
9965
10533
|
// dist/models/command.js
|
|
9966
|
-
var modelsCommand = /* @__PURE__ */ __name((program, streams, env, keyring) => {
|
|
10534
|
+
var modelsCommand = /* @__PURE__ */ __name((program, streams, env, keyring, stdin) => {
|
|
9967
10535
|
const { print } = answers(program, streams, env);
|
|
9968
10536
|
program.addCommand(modelCatalogueCommand(APP, {
|
|
9969
10537
|
kinds: ["text"],
|
|
@@ -9972,6 +10540,7 @@ var modelsCommand = /* @__PURE__ */ __name((program, streams, env, keyring) => {
|
|
|
9972
10540
|
jsonOption: true,
|
|
9973
10541
|
env: /* @__PURE__ */ __name(() => env, "env"),
|
|
9974
10542
|
...keyring ? { keyring } : {},
|
|
10543
|
+
...stdin ? { stdin: /* @__PURE__ */ __name(() => stdin, "stdin") } : {},
|
|
9975
10544
|
output: /* @__PURE__ */ __name((body, command) => print(command.optsWithGlobals().json, body), "output"),
|
|
9976
10545
|
diagnostic: /* @__PURE__ */ __name((line3) => streams.diagnostic(line3), "diagnostic"),
|
|
9977
10546
|
offline: /* @__PURE__ */ __name(() => program.opts().offline === true, "offline")
|
|
@@ -10242,11 +10811,14 @@ var notesCommandDefinition = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
10242
10811
|
if (about !== void 0 && terms2.size > 1)
|
|
10243
10812
|
throw new CliError("validation_error", "about: stands alone in notes list: its notes are found through links");
|
|
10244
10813
|
const options = { ...paging, json: json5 };
|
|
10245
|
-
const page = await withNotes(async (store) =>
|
|
10246
|
-
|
|
10247
|
-
|
|
10248
|
-
|
|
10249
|
-
|
|
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
|
+
});
|
|
10250
10822
|
print(options.json, listAnswer("notes list", {
|
|
10251
10823
|
items: page.items,
|
|
10252
10824
|
limit: options.limit,
|
|
@@ -10269,7 +10841,7 @@ var notesCommandDefinition = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
10269
10841
|
const answer = await withNotes(async (store) => {
|
|
10270
10842
|
const about = await Promise.all((options.subject ?? []).map(async (subject) => (await subjectOf(store, subject)).ref));
|
|
10271
10843
|
if (options.meeting !== void 0)
|
|
10272
|
-
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")));
|
|
10273
10845
|
const note = await store.notes.addNote({
|
|
10274
10846
|
text: body,
|
|
10275
10847
|
about,
|
|
@@ -10353,15 +10925,15 @@ var formatOf2 = /* @__PURE__ */ __name((value) => {
|
|
|
10353
10925
|
return value;
|
|
10354
10926
|
}, "formatOf");
|
|
10355
10927
|
var directory = /* @__PURE__ */ __name((path) => {
|
|
10356
|
-
const
|
|
10928
|
+
const at2 = resolve4(path);
|
|
10357
10929
|
let isDirectory = false;
|
|
10358
10930
|
try {
|
|
10359
|
-
isDirectory = statSync4(
|
|
10931
|
+
isDirectory = statSync4(at2).isDirectory();
|
|
10360
10932
|
} catch {
|
|
10361
10933
|
}
|
|
10362
10934
|
if (!isDirectory)
|
|
10363
|
-
throw new CliError("not_found", `${
|
|
10364
|
-
return
|
|
10935
|
+
throw new CliError("not_found", `${at2} is not a folder`);
|
|
10936
|
+
return at2;
|
|
10365
10937
|
}, "directory");
|
|
10366
10938
|
var FOLDERS_QUERY = { entity: "notes_folder", backend: "native", fields: [] };
|
|
10367
10939
|
var keptByDrive = /* @__PURE__ */ __name((name2) => name2.startsWith("google-drive:"), "keptByDrive");
|
|
@@ -10374,10 +10946,10 @@ var foldersCommand = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
10374
10946
|
const { print } = answers(program, streams, env);
|
|
10375
10947
|
const folders = program.command("folders").description("folders of notes: the id links and the store use, and the path on this computer");
|
|
10376
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) => {
|
|
10377
|
-
const
|
|
10949
|
+
const at2 = directory(path);
|
|
10378
10950
|
const answer = await withStore(env, async (store) => {
|
|
10379
10951
|
const known2 = new Set((await store.notes.folders()).map(({ id }) => id));
|
|
10380
|
-
const current = noteFolders(loadConfig(env).notes).find((folder2) => folder2.path ===
|
|
10952
|
+
const current = noteFolders(loadConfig(env).notes).find((folder2) => folder2.path === at2);
|
|
10381
10953
|
if (current?.id && known2.has(current.id)) {
|
|
10382
10954
|
const folder2 = { ...current, id: current.id, format: options.format ?? current.format };
|
|
10383
10955
|
if (folder2.format !== current.format)
|
|
@@ -10385,15 +10957,15 @@ var foldersCommand = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
10385
10957
|
return { ...folder2, created: false };
|
|
10386
10958
|
}
|
|
10387
10959
|
const format = options.format ?? current?.format ?? "obsidian";
|
|
10388
|
-
const made = await store.notes.addFolder({ name: basename2(
|
|
10389
|
-
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 };
|
|
10390
10962
|
updateConfig((config) => bindFolder(config, folder), env);
|
|
10391
10963
|
return { ...folder, created: true };
|
|
10392
10964
|
});
|
|
10393
10965
|
print(options.json, itemAnswer(answer), answer.id);
|
|
10394
10966
|
});
|
|
10395
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) => {
|
|
10396
|
-
const
|
|
10968
|
+
const at2 = directory(path);
|
|
10397
10969
|
const folder = await withStore(env, async (store) => {
|
|
10398
10970
|
const stored = (await storedFolders(store)).find((candidate) => candidate.id === id);
|
|
10399
10971
|
if (!stored)
|
|
@@ -10404,7 +10976,7 @@ var foldersCommand = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
10404
10976
|
throw new CliError("validation_error", `folder ${id} is Google Drive's (${stored.name}) \u2014 drive keeps it, and memo search already reads it`);
|
|
10405
10977
|
let bound;
|
|
10406
10978
|
updateConfig((config) => {
|
|
10407
|
-
const result = attachFolder(config, id,
|
|
10979
|
+
const result = attachFolder(config, id, at2, options.format ?? stored.format);
|
|
10408
10980
|
bound = result.folder;
|
|
10409
10981
|
return result.config;
|
|
10410
10982
|
}, env);
|
|
@@ -10537,7 +11109,7 @@ var peopleCommand = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
10537
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) => {
|
|
10538
11110
|
listQuery(typedQuery(words), query, "people list");
|
|
10539
11111
|
await withStore(env, async (store) => {
|
|
10540
|
-
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);
|
|
10541
11113
|
print(options.json, wholeList("people list", found.map(({ person, ...rest }) => ({ ref: person, ...rest }))));
|
|
10542
11114
|
});
|
|
10543
11115
|
});
|
|
@@ -10580,19 +11152,19 @@ var headerOf2 = /* @__PURE__ */ __name((line3) => {
|
|
|
10580
11152
|
return void 0;
|
|
10581
11153
|
}
|
|
10582
11154
|
}, "headerOf");
|
|
10583
|
-
var
|
|
11155
|
+
var accountIn2 = /* @__PURE__ */ __name((envelope, given2) => {
|
|
10584
11156
|
const provider = envelope?.source?.provider;
|
|
10585
11157
|
return typeof provider === "string" && given2.startsWith(`${provider}:`) ? given2.slice(provider.length + 1) : given2;
|
|
10586
11158
|
}, "accountIn");
|
|
10587
11159
|
var deviceOf = /* @__PURE__ */ __name((given2) => {
|
|
10588
|
-
const
|
|
10589
|
-
if (
|
|
11160
|
+
const at2 = given2.indexOf(":");
|
|
11161
|
+
if (at2 < 0)
|
|
10590
11162
|
return given2;
|
|
10591
|
-
if (given2.slice(0,
|
|
11163
|
+
if (given2.slice(0, at2) !== PHONE)
|
|
10592
11164
|
throw new CliError("validation_error", "a vCard file holds a phone's contacts: --account phone:<device>", {
|
|
10593
11165
|
param: "--account"
|
|
10594
11166
|
});
|
|
10595
|
-
return given2.slice(
|
|
11167
|
+
return given2.slice(at2 + 1);
|
|
10596
11168
|
}, "deviceOf");
|
|
10597
11169
|
var importRecords = /* @__PURE__ */ __name(async (store, { file, stdin, account: account2, dryRun, onIssue, region }) => {
|
|
10598
11170
|
const iterator = (await linesOf(file, stdin))[Symbol.asyncIterator]();
|
|
@@ -10649,10 +11221,10 @@ var importRecords = /* @__PURE__ */ __name(async (store, { file, stdin, account:
|
|
|
10649
11221
|
}
|
|
10650
11222
|
}
|
|
10651
11223
|
__name(all, "all");
|
|
10652
|
-
return ingestLines(store, all(), { account:
|
|
11224
|
+
return ingestLines(store, all(), { account: accountIn2(header, account2), dryRun, onIssue });
|
|
10653
11225
|
}
|
|
10654
11226
|
const envelope = envelopeOfText(await whole2([first]));
|
|
10655
|
-
return ingest(store, envelope, { account:
|
|
11227
|
+
return ingest(store, envelope, { account: accountIn2(envelope, account2), dryRun, onIssue });
|
|
10656
11228
|
}, "importRecords");
|
|
10657
11229
|
|
|
10658
11230
|
// dist/records/mapping.js
|
|
@@ -10680,10 +11252,10 @@ var sourceOf4 = /* @__PURE__ */ __name((account2) => {
|
|
|
10680
11252
|
}, "sourceOf");
|
|
10681
11253
|
var recordOf = /* @__PURE__ */ __name((record2) => {
|
|
10682
11254
|
const from = record2.startsWith("custom:") ? "custom:".length : 0;
|
|
10683
|
-
const
|
|
10684
|
-
if (
|
|
11255
|
+
const at2 = record2.indexOf(":", from);
|
|
11256
|
+
if (at2 <= from || at2 === record2.length - 1)
|
|
10685
11257
|
throw new CliError("validation_error", `${record2} is not <type>:<external_id>, such as organization:client or custom:quote:Q-7`, { param: "record" });
|
|
10686
|
-
return { type: record2.slice(0,
|
|
11258
|
+
return { type: record2.slice(0, at2), externalId: record2.slice(at2 + 1) };
|
|
10687
11259
|
}, "recordOf");
|
|
10688
11260
|
var RECORD_HELP = "<type>:<external_id> as the source names it, such as organization:client or custom:quote:Q-7";
|
|
10689
11261
|
var ACCOUNT_HELP = "the source, <provider>:<account> as the envelope's source names it, such as sheet:rentals";
|
|
@@ -10941,7 +11513,7 @@ ${SOURCE_REVIEW_HELP}`);
|
|
|
10941
11513
|
...given2,
|
|
10942
11514
|
question: `${name2} ${ids.length} proposal${ids.length === 1 ? "" : "s"} as you, the owner?`
|
|
10943
11515
|
});
|
|
10944
|
-
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)));
|
|
10945
11517
|
const issues = result.refused.map((one2) => ({
|
|
10946
11518
|
code: one2.code,
|
|
10947
11519
|
source: one2.id,
|
|
@@ -10962,18 +11534,18 @@ ${SOURCE_REVIEW_HELP}`);
|
|
|
10962
11534
|
import { existsSync as existsSync10, readdirSync as readdirSync7 } from "node:fs";
|
|
10963
11535
|
import { join as join13 } from "node:path";
|
|
10964
11536
|
var EMBED_PER_RUN = 600;
|
|
11537
|
+
var MEASURED_WITH = "e5-small";
|
|
10965
11538
|
var SLOWEST_KNOWN = 2;
|
|
10966
11539
|
var embedPerRun = /* @__PURE__ */ __name((env = process.env) => {
|
|
10967
11540
|
const models = textModels(env);
|
|
10968
11541
|
const speed = /* @__PURE__ */ __name((id) => models.find((model) => model.id === id)?.chunksPerSecond ?? SLOWEST_KNOWN, "speed");
|
|
10969
|
-
const ratio = speed(chosenTextModel(env).id) / speed(
|
|
11542
|
+
const ratio = speed(chosenTextModel(env).id) / speed(MEASURED_WITH);
|
|
10970
11543
|
return Math.max(8, Math.min(EMBED_PER_RUN, Math.round(EMBED_PER_RUN * ratio)));
|
|
10971
11544
|
}, "embedPerRun");
|
|
10972
11545
|
var missingModel = /* @__PURE__ */ __name((error, env) => {
|
|
10973
11546
|
const named5 = isCliError(error) ? error.details.model : void 0;
|
|
10974
11547
|
const id = typeof named5 === "string" ? named5 : chosenTextModel(env).id;
|
|
10975
|
-
|
|
10976
|
-
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}`;
|
|
10977
11549
|
}, "missingModel");
|
|
10978
11550
|
var searchModelPresent = /* @__PURE__ */ __name((env) => {
|
|
10979
11551
|
try {
|
|
@@ -10987,7 +11559,7 @@ var isMissingModel = /* @__PURE__ */ __name((error) => isCliError(error) && erro
|
|
|
10987
11559
|
var reportOf = /* @__PURE__ */ __name((run) => {
|
|
10988
11560
|
if (run === void 0)
|
|
10989
11561
|
return void 0;
|
|
10990
|
-
if (
|
|
11562
|
+
if (!("provider" in run))
|
|
10991
11563
|
return {
|
|
10992
11564
|
status: "failed",
|
|
10993
11565
|
sent: 0,
|
|
@@ -10997,7 +11569,8 @@ var reportOf = /* @__PURE__ */ __name((run) => {
|
|
|
10997
11569
|
inputTokens: 0,
|
|
10998
11570
|
outputTokens: 0,
|
|
10999
11571
|
costUsd: 0,
|
|
11000
|
-
reason: run.reason
|
|
11572
|
+
reason: run.reason,
|
|
11573
|
+
reasonId: run.reason_id
|
|
11001
11574
|
};
|
|
11002
11575
|
return {
|
|
11003
11576
|
status: run.status,
|
|
@@ -11010,7 +11583,8 @@ var reportOf = /* @__PURE__ */ __name((run) => {
|
|
|
11010
11583
|
inputTokens: run.usage.input,
|
|
11011
11584
|
outputTokens: run.usage.output,
|
|
11012
11585
|
costUsd: run.cost_usd,
|
|
11013
|
-
...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 }
|
|
11014
11588
|
};
|
|
11015
11589
|
}, "reportOf");
|
|
11016
11590
|
var combinedEnrichment = /* @__PURE__ */ __name((...parts2) => {
|
|
@@ -11019,20 +11593,23 @@ var combinedEnrichment = /* @__PURE__ */ __name((...parts2) => {
|
|
|
11019
11593
|
return void 0;
|
|
11020
11594
|
const rank = { done: 0, stopped: 1, failed: 2 };
|
|
11021
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;
|
|
11022
11598
|
const named5 = present2.find((part) => part.provider !== void 0);
|
|
11023
11599
|
const costs = present2.map((part) => part.costUsd);
|
|
11024
11600
|
return {
|
|
11025
|
-
status
|
|
11601
|
+
status,
|
|
11026
11602
|
...named5?.provider === void 0 ? {} : { provider: named5.provider },
|
|
11027
11603
|
...named5?.model === void 0 ? {} : { model: named5.model },
|
|
11028
11604
|
sent: present2.reduce((sum, part) => sum + part.sent, 0),
|
|
11029
|
-
enriched
|
|
11605
|
+
enriched,
|
|
11030
11606
|
failed: present2.reduce((sum, part) => sum + part.failed, 0),
|
|
11031
11607
|
left: present2.reduce((sum, part) => sum + part.left, 0),
|
|
11032
11608
|
inputTokens: present2.reduce((sum, part) => sum + part.inputTokens, 0),
|
|
11033
11609
|
outputTokens: present2.reduce((sum, part) => sum + part.outputTokens, 0),
|
|
11034
11610
|
costUsd: costs.includes(null) ? null : Math.round(costs.reduce((sum, cost) => sum + (cost ?? 0), 0) * 1e6) / 1e6,
|
|
11035
|
-
...worst.reason === void 0 ? {} : { reason: worst.reason }
|
|
11611
|
+
...worst.reason === void 0 ? {} : { reason: worst.reason },
|
|
11612
|
+
...worst.reasonId === void 0 ? {} : { reasonId: worst.reasonId }
|
|
11036
11613
|
};
|
|
11037
11614
|
}, "combinedEnrichment");
|
|
11038
11615
|
var embedNoteChunks = /* @__PURE__ */ __name(async (store, { embed = true, env, maxChunks = embedPerRun(env), keyring } = {}) => {
|
|
@@ -11193,6 +11770,7 @@ var syncCommand = /* @__PURE__ */ __name((program, streams, env, signal, keyring
|
|
|
11193
11770
|
}), "answer");
|
|
11194
11771
|
const work = withImportLock(env, async () => {
|
|
11195
11772
|
const store = await openStore({ env, ...STORE_CLIENT, decisions: decisionPolicy(env) });
|
|
11773
|
+
const enriched = [];
|
|
11196
11774
|
const attempt = /* @__PURE__ */ __name(async (source, work2) => {
|
|
11197
11775
|
halt();
|
|
11198
11776
|
try {
|
|
@@ -11231,11 +11809,13 @@ var syncCommand = /* @__PURE__ */ __name((program, streams, env, signal, keyring
|
|
|
11231
11809
|
});
|
|
11232
11810
|
if (folders.length > 0)
|
|
11233
11811
|
await attempt("notes by meaning", async () => {
|
|
11234
|
-
|
|
11812
|
+
const { enrichment: enrichment2, ...embedded } = await embedNoteChunks(store, {
|
|
11235
11813
|
embed: options.embed && config.notes?.embed !== false,
|
|
11236
11814
|
env,
|
|
11237
11815
|
...keyring ? { keyring } : {}
|
|
11238
11816
|
});
|
|
11817
|
+
run.notesEmbedded = embedded;
|
|
11818
|
+
enriched.push(enrichment2);
|
|
11239
11819
|
});
|
|
11240
11820
|
await attempt("people-notes.json", async () => {
|
|
11241
11821
|
await importNotesMap(store, env, folders);
|
|
@@ -11243,13 +11823,15 @@ var syncCommand = /* @__PURE__ */ __name((program, streams, env, signal, keyring
|
|
|
11243
11823
|
}
|
|
11244
11824
|
if (synced.has("mail"))
|
|
11245
11825
|
await attempt("mail by meaning", async () => {
|
|
11246
|
-
|
|
11826
|
+
const { enrichment: enrichment2, ...embedded } = await embedMailChunks(store, {
|
|
11247
11827
|
embed: options.embed,
|
|
11248
11828
|
env,
|
|
11249
11829
|
...keyring ? { keyring } : {}
|
|
11250
11830
|
});
|
|
11831
|
+
run.mailEmbedded = embedded;
|
|
11832
|
+
enriched.push(enrichment2);
|
|
11251
11833
|
});
|
|
11252
|
-
const enrichment = combinedEnrichment(
|
|
11834
|
+
const enrichment = combinedEnrichment(...enriched);
|
|
11253
11835
|
if (enrichment)
|
|
11254
11836
|
run.enrichment = enrichment;
|
|
11255
11837
|
halt();
|
|
@@ -11368,10 +11950,10 @@ var mailboxBlock = /* @__PURE__ */ __name((source, review, room = Number.POSITIV
|
|
|
11368
11950
|
let fit;
|
|
11369
11951
|
for (let end = 1; end < cuts.length; end++) {
|
|
11370
11952
|
const kept = new Set(cuts.slice(0, end).flatMap((cut2) => cut2.items));
|
|
11371
|
-
const
|
|
11953
|
+
const at2 = cuts[end - 1];
|
|
11372
11954
|
const block = lines(source, review, {
|
|
11373
|
-
key:
|
|
11374
|
-
cursor:
|
|
11955
|
+
key: at2?.key,
|
|
11956
|
+
cursor: at2?.cursor,
|
|
11375
11957
|
items: items.filter((item) => kept.has(item)),
|
|
11376
11958
|
waiting: items.length - kept.size
|
|
11377
11959
|
});
|
|
@@ -11556,7 +12138,7 @@ var notesAnswer = /* @__PURE__ */ __name((found, limit, page, args = {}) => list
|
|
|
11556
12138
|
var holdsNoPeople = /* @__PURE__ */ __name((provider) => provider === "notes" || isFolderProvider(provider), "holdsNoPeople");
|
|
11557
12139
|
var fold4 = /* @__PURE__ */ __name((text3) => text3.normalize("NFKD").replace(new RegExp("\\p{M}", "gu"), "").toLowerCase(), "fold");
|
|
11558
12140
|
var scopeOf2 = /* @__PURE__ */ __name(async (store, env, source) => {
|
|
11559
|
-
const keys = source === void 0 ? await store
|
|
12141
|
+
const keys = source === void 0 ? await scopedAccounts(store, env) : await accountsOf(store, env, source);
|
|
11560
12142
|
const held = keys.filter((key) => !holdsNoPeople(key.provider));
|
|
11561
12143
|
if (source !== void 0 && held.length === 0)
|
|
11562
12144
|
throw new CliError("validation_error", `${source} names no messenger, mail or meeting account that holds people`, {
|
|
@@ -11596,6 +12178,13 @@ var searchPeople = /* @__PURE__ */ __name(async (store, env, words, { limit, sou
|
|
|
11596
12178
|
hits.set(ref, hit);
|
|
11597
12179
|
}
|
|
11598
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
|
+
}
|
|
11599
12188
|
const first = wanted.join(" ");
|
|
11600
12189
|
const rank = /* @__PURE__ */ __name((hit) => fold4(hit.name ?? "").startsWith(first) ? 0 : 1, "rank");
|
|
11601
12190
|
const sorted = [...hits.values()].sort((a, b) => rank(a) - rank(b) || (a.name ?? "").localeCompare(b.name ?? "") || a.ref.localeCompare(b.ref));
|
|
@@ -11613,6 +12202,17 @@ var peopleText = /* @__PURE__ */ __name((found) => found.items.map((hit) => [
|
|
|
11613
12202
|
].join("\n")).join("\n") || "nobody found", "peopleText");
|
|
11614
12203
|
|
|
11615
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");
|
|
11616
12216
|
var ONLY = ["messages", "mail", "notes", "events", "crm", "business"];
|
|
11617
12217
|
var onlyOf2 = /* @__PURE__ */ __name((value) => {
|
|
11618
12218
|
const selected = value.split(",").map((part) => part.trim());
|
|
@@ -11636,7 +12236,7 @@ var searchCommandDefinition = /* @__PURE__ */ __name((program, streams, env) =>
|
|
|
11636
12236
|
throw new InvalidArgumentError("at most 100");
|
|
11637
12237
|
return limit;
|
|
11638
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");
|
|
11639
|
-
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", `
|
|
11640
12240
|
content: narrows a search to the text of files, transcript: to voice transcripts, filename: to file names \u2014 memo search all 'content:invoice'.
|
|
11641
12241
|
Calendar events come from every calendar gcal stored; an event's title, description and place are written by whoever sent the invitation.
|
|
11642
12242
|
crm finds deals and leads by the words of their title only.
|
|
@@ -11704,7 +12304,7 @@ For an agent: read with --compact, one line per hit with its reference. Never wr
|
|
|
11704
12304
|
const level = levelOf(options);
|
|
11705
12305
|
const text3 = words.join(" ");
|
|
11706
12306
|
const answer = await withStore(env, async (store) => {
|
|
11707
|
-
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;
|
|
11708
12308
|
return searchKind(store, kind, {
|
|
11709
12309
|
text: text3,
|
|
11710
12310
|
limit: options.limit,
|
|
@@ -11858,7 +12458,7 @@ var showReferences = /* @__PURE__ */ __name(async (store, env, texts, command) =
|
|
|
11858
12458
|
}
|
|
11859
12459
|
return shown3;
|
|
11860
12460
|
}, "showReferences");
|
|
11861
|
-
var minute2 = /* @__PURE__ */ __name((
|
|
12461
|
+
var minute2 = /* @__PURE__ */ __name((at2) => at2 === null ? null : at2.slice(0, 16).replace("T", " "), "minute");
|
|
11862
12462
|
var blockOf = /* @__PURE__ */ __name((one2) => [
|
|
11863
12463
|
`${one2.ref} ${one2.title ?? ""}`.trimEnd(),
|
|
11864
12464
|
` ${[one2.kind, one2.in, one2.state, minute2(one2.at)].filter((part) => part !== null).join(" \xB7 ")}`,
|
|
@@ -11914,7 +12514,7 @@ var escaped = /* @__PURE__ */ __name((text3) => text3.replace(/[.*+?^${}()|[\]\\
|
|
|
11914
12514
|
var folded = /* @__PURE__ */ __name((text3) => text3.normalize("NFC").toLocaleLowerCase(), "folded");
|
|
11915
12515
|
var mentionsOf = /* @__PURE__ */ __name(async (store, note) => {
|
|
11916
12516
|
const id = Number(note.id);
|
|
11917
|
-
const
|
|
12517
|
+
const at2 = note.modifiedAt ?? note.updatedAt;
|
|
11918
12518
|
const found = [];
|
|
11919
12519
|
for (let offset = 0; ; offset += PAGE6) {
|
|
11920
12520
|
const page = await store.sourceMentions.list("document", void 0, { limit: PAGE6, offset }, []);
|
|
@@ -11922,7 +12522,7 @@ var mentionsOf = /* @__PURE__ */ __name(async (store, note) => {
|
|
|
11922
12522
|
const when = mention.source.at ?? "";
|
|
11923
12523
|
if (mention.source.id === id)
|
|
11924
12524
|
found.push(mention);
|
|
11925
|
-
else if (found.length > 0 || when <
|
|
12525
|
+
else if (found.length > 0 || when < at2 || when === at2 && mention.source.id < id)
|
|
11926
12526
|
return found;
|
|
11927
12527
|
}
|
|
11928
12528
|
if (!page.hasMore)
|
|
@@ -11965,8 +12565,8 @@ ${note.text}`);
|
|
|
11965
12565
|
const name2 = organization.name.trim();
|
|
11966
12566
|
if (name2.length < 3)
|
|
11967
12567
|
continue;
|
|
11968
|
-
const
|
|
11969
|
-
if (
|
|
12568
|
+
const at2 = new RegExp(`(?<![\\p{L}\\p{N}])${escaped(folded(name2))}(?![\\p{L}\\p{N}])`, "u");
|
|
12569
|
+
if (at2.test(text3))
|
|
11970
12570
|
add(organization.ref, "organization", organization.name, name2);
|
|
11971
12571
|
}
|
|
11972
12572
|
return {
|
|
@@ -12342,6 +12942,56 @@ var sourcesCommand = /* @__PURE__ */ __name((program, streams, env, { fetch: fet
|
|
|
12342
12942
|
});
|
|
12343
12943
|
}, "sourcesCommand");
|
|
12344
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
|
+
|
|
12345
12995
|
// dist/store/info-command.js
|
|
12346
12996
|
var storeCommand = /* @__PURE__ */ __name((program, streams, env) => {
|
|
12347
12997
|
const { print } = answers(program, streams, env);
|
|
@@ -12443,7 +13093,7 @@ var tagsCommand = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
12443
13093
|
}
|
|
12444
13094
|
if (options.contact !== void 0 || options.meeting !== void 0) {
|
|
12445
13095
|
await withStore(env, async (store) => {
|
|
12446
|
-
const { key, target: target2 } = await selectTarget(store, { ...options, ...await scoped3(store) });
|
|
13096
|
+
const { key, target: target2 } = await selectTarget(store, env, { ...options, ...await scoped3(store) });
|
|
12447
13097
|
const changed = await (operation === "add" ? store.knowledge.addTags : store.knowledge.removeTags)(key, target2, given2);
|
|
12448
13098
|
print(options.json, itemAnswer({ ...key, target: target2, [operation === "add" ? "added" : "removed"]: changed }), `${operation}: ${changed.join(", ") || "no labels changed"}`);
|
|
12449
13099
|
});
|
|
@@ -12480,7 +13130,7 @@ var tagsCommand = /* @__PURE__ */ __name((program, streams, env) => {
|
|
|
12480
13130
|
...terms2.has("type") ? { type: terms2.get("type") } : {}
|
|
12481
13131
|
};
|
|
12482
13132
|
await withStore(env, async (store) => {
|
|
12483
|
-
const keys = value === void 0 ? await store
|
|
13133
|
+
const keys = value === void 0 ? await scopedAccounts(store, env) : await accountsOf(store, env, value);
|
|
12484
13134
|
const answer = await listTags(store, { ...options, keys });
|
|
12485
13135
|
const owned = options.type === void 0 || OWNED.includes(options.type) ? await store.knowledge.labelled(null, {
|
|
12486
13136
|
...options.tag === void 0 ? {} : { tag: options.tag },
|
|
@@ -12552,7 +13202,7 @@ var requireAccount = /* @__PURE__ */ __name((env, warn) => async (_, command) =>
|
|
|
12552
13202
|
return;
|
|
12553
13203
|
if (["show", "update", "claim", "release"].includes(command.name()) && first !== void 0 && await store.tasks.projectTask(first))
|
|
12554
13204
|
return;
|
|
12555
|
-
const listed2 = (await store
|
|
13205
|
+
const listed2 = (await scopedAccounts(store, env)).map((key) => `${option} ${key.provider}:${key.account}`).join("; ");
|
|
12556
13206
|
throw new CliError("validation_error", `give ${option} \u2014 the stored accounts: ${listed2 || "none yet"}`);
|
|
12557
13207
|
} finally {
|
|
12558
13208
|
await store.close();
|
|
@@ -12628,7 +13278,7 @@ var addFromSource = /* @__PURE__ */ __name(async (store, env, source, options) =
|
|
|
12628
13278
|
const parsed = native ? void 0 : parseLocator(source);
|
|
12629
13279
|
if (parsed && (options.provider && options.provider !== parsed.provider || options.account && options.account !== parsed.account))
|
|
12630
13280
|
throw new CliError("validation_error", "locator and selected account disagree");
|
|
12631
|
-
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);
|
|
12632
13282
|
if (parsed && parsed.provider !== "notes" && await heldMessage(store, key, parsed.message, parsed.chat) === void 0)
|
|
12633
13283
|
throw new CliError("not_found", "the task source is unavailable or deleted");
|
|
12634
13284
|
const author = authorOf(env);
|
|
@@ -12657,7 +13307,7 @@ var closeTask = /* @__PURE__ */ __name(async (store, env, id, options) => {
|
|
|
12657
13307
|
}
|
|
12658
13308
|
if (options.revision !== void 0)
|
|
12659
13309
|
throw new CliError("validation_error", "--revision checks a project task; a task from a message has none");
|
|
12660
|
-
const key = await selectAccount(store, options);
|
|
13310
|
+
const key = await selectAccount(store, env, options);
|
|
12661
13311
|
return tasksService(storeOnlyDeps(store, key, { app: APP, env })).close(id, {
|
|
12662
13312
|
as: options.as,
|
|
12663
13313
|
by: "owner",
|
|
@@ -12689,7 +13339,7 @@ var updateTask = /* @__PURE__ */ __name(async (store, env, id, options) => {
|
|
|
12689
13339
|
if (options.priority !== void 0 || options.parent !== void 0)
|
|
12690
13340
|
throw new CliError("validation_error", "--priority and --parent are for a task in a project");
|
|
12691
13341
|
const assignees = options.assignee?.map((one2) => one2 === "sender" || one2 === "none" ? one2 : personRef(one2));
|
|
12692
|
-
const key = await selectAccount(store, options);
|
|
13342
|
+
const key = await selectAccount(store, env, options);
|
|
12693
13343
|
return tasksService(storeOnlyDeps(store, key, { app: APP, env })).plan(id, {
|
|
12694
13344
|
...options.title === void 0 ? {} : { title: options.title },
|
|
12695
13345
|
...options.description === void 0 ? {} : { description: options.description },
|
|
@@ -13070,6 +13720,38 @@ var OWN_ENTITIES = entityFields({
|
|
|
13070
13720
|
agent_action: ["id", "actor", "tool", "tier", "target", "status", "error", "started_at", "finished_at"],
|
|
13071
13721
|
meeting_project: ["id", "meeting", "project", "confirmed", "provenance", "fingerprint"],
|
|
13072
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
|
+
],
|
|
13073
13755
|
order: [
|
|
13074
13756
|
"id",
|
|
13075
13757
|
"ref",
|
|
@@ -13346,6 +14028,89 @@ var OWN_ENTITIES = entityFields({
|
|
|
13346
14028
|
records_match: ["linked", "created", "unmatched", "proposed", "errors", "truncated"],
|
|
13347
14029
|
payment_allocation: ["payment", "invoice", "amount", "currency", "created_at"]
|
|
13348
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");
|
|
13349
14114
|
var SKILL_TOPICS = [
|
|
13350
14115
|
"search",
|
|
13351
14116
|
"projects",
|
|
@@ -13371,11 +14136,13 @@ var FIRST_SCREEN = {
|
|
|
13371
14136
|
profile: false,
|
|
13372
14137
|
start: "memo folders add <path>"
|
|
13373
14138
|
};
|
|
13374
|
-
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 };
|
|
13375
14141
|
const fields = jsonFields(raw, OWN_ENTITIES);
|
|
13376
14142
|
const { streams } = fields;
|
|
13377
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");
|
|
13378
14144
|
refuseWritesUnderLock(program, env);
|
|
14145
|
+
scopeRunsToGroup(program, env, group);
|
|
13379
14146
|
provideTerminal(program, terminal);
|
|
13380
14147
|
contextCommand(program, streams, env);
|
|
13381
14148
|
showCommand(program, streams, env);
|
|
@@ -13407,7 +14174,7 @@ var createProgram = /* @__PURE__ */ __name(({ streams: raw = processStreams, env
|
|
|
13407
14174
|
reviewCommand(program, streams, env);
|
|
13408
14175
|
agentsCommand(program, streams, env);
|
|
13409
14176
|
mcpCommand(program, streams, env, createProgram);
|
|
13410
|
-
modelsCommand(program, streams, env, keyring);
|
|
14177
|
+
modelsCommand(program, streams, env, keyring, stdin);
|
|
13411
14178
|
templatesCommand2(program, streams, env);
|
|
13412
14179
|
searchCommand(program, streams, env);
|
|
13413
14180
|
meetingReadCommands(program, streams, env);
|
|
@@ -13416,6 +14183,7 @@ var createProgram = /* @__PURE__ */ __name(({ streams: raw = processStreams, env
|
|
|
13416
14183
|
askCommand(program, streams, env);
|
|
13417
14184
|
syncCommand(program, streams, env, signal, keyring);
|
|
13418
14185
|
storeCommand(program, streams, env);
|
|
14186
|
+
groupsCommand(program, streams, env);
|
|
13419
14187
|
autoCommand(program, streams, env);
|
|
13420
14188
|
configCommand(program, streams, env);
|
|
13421
14189
|
doctorCommand(program, streams, env);
|
|
@@ -13481,6 +14249,7 @@ var createProgram = /* @__PURE__ */ __name(({ streams: raw = processStreams, env
|
|
|
13481
14249
|
});
|
|
13482
14250
|
trackAnswers(program);
|
|
13483
14251
|
placeInSections(program);
|
|
14252
|
+
markGroupAware(program);
|
|
13484
14253
|
installHelp(program, FIRST_SCREEN);
|
|
13485
14254
|
provide(program, {
|
|
13486
14255
|
...environmentOf(program),
|
|
@@ -13499,6 +14268,18 @@ var createProgram = /* @__PURE__ */ __name(({ streams: raw = processStreams, env
|
|
|
13499
14268
|
assertSharedContracts(program);
|
|
13500
14269
|
return program;
|
|
13501
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");
|
|
13502
14283
|
var refuseJoinedPath = /* @__PURE__ */ __name((program, args) => {
|
|
13503
14284
|
let command = program;
|
|
13504
14285
|
const path = [];
|
|
@@ -13518,5 +14299,6 @@ var refuseJoinedPath = /* @__PURE__ */ __name((program, args) => {
|
|
|
13518
14299
|
export {
|
|
13519
14300
|
SKILL_TOPICS,
|
|
13520
14301
|
createProgram,
|
|
14302
|
+
liftGroup,
|
|
13521
14303
|
refuseJoinedPath
|
|
13522
14304
|
};
|