@wirecat/cli-core 0.377.0 → 0.379.0
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/CHANGELOG.md +37 -0
- package/dist/cli/envelope.d.ts +10 -0
- package/dist/cli/list-query.js +2 -2
- package/dist/cli/meeting-preparation-read.js +5 -5
- package/dist/cli/meeting-series-inventory-read.js +3 -4
- package/dist/cli/messenger/contacts-command.js +1 -1
- package/dist/cli/messenger/stats-command.js +3 -1
- package/dist/context/evidence-response.js +2 -2
- package/dist/context/evidence.d.ts +5 -2
- package/dist/context/evidence.js +21 -6
- package/dist/domain/moment.d.ts +8 -0
- package/dist/domain/moment.js +14 -0
- package/dist/domain/send-time.d.ts +2 -2
- package/dist/domain/send-time.js +4 -3
- package/dist/entities/account-session.d.ts +2 -2
- package/dist/entities/admin-report.d.ts +8 -8
- package/dist/entities/agenda.d.ts +12 -12
- package/dist/entities/chat-event.d.ts +1 -1
- package/dist/entities/chat-stats.d.ts +5 -5
- package/dist/entities/chat.d.ts +4 -4
- package/dist/entities/contact-note.d.ts +2 -2
- package/dist/entities/contact.d.ts +13 -13
- package/dist/entities/conversation.d.ts +3 -3
- package/dist/entities/counter-reading.d.ts +1 -1
- package/dist/entities/counters.d.ts +2 -2
- package/dist/entities/document.d.ts +2 -2
- package/dist/entities/evidence.d.ts +72 -72
- package/dist/entities/fact.d.ts +3 -3
- package/dist/entities/fields.d.ts +3 -1
- package/dist/entities/fields.js +2 -0
- package/dist/entities/hit.d.ts +1 -1
- package/dist/entities/index.d.ts +216 -215
- package/dist/entities/index.js +1 -0
- package/dist/entities/invite-link.d.ts +1 -1
- package/dist/entities/job.d.ts +2 -2
- package/dist/entities/join-request.d.ts +1 -1
- package/dist/entities/meeting-communications.d.ts +4 -4
- package/dist/entities/meeting-findings.d.ts +2 -2
- package/dist/entities/meeting-preparation-parts.d.ts +9 -9
- package/dist/entities/meeting-preparation.d.ts +23 -23
- package/dist/entities/meeting-series-inventory.d.ts +3 -3
- package/dist/entities/member.d.ts +3 -3
- package/dist/entities/memory.d.ts +3 -3
- package/dist/entities/message.d.ts +6 -6
- package/dist/entities/note.d.ts +3 -3
- package/dist/entities/official-stats.d.ts +2 -2
- package/dist/entities/poll-vote.d.ts +1 -1
- package/dist/entities/ranking.d.ts +2 -2
- package/dist/entities/relationship.d.ts +1 -1
- package/dist/entities/retention.d.ts +4 -4
- package/dist/entities/saved-search.d.ts +2 -2
- package/dist/entities/tagging.d.ts +1 -1
- package/dist/entities/task.d.ts +7 -7
- package/dist/entities/topic.d.ts +2 -2
- package/dist/mcp/tools/stats.js +3 -1
- package/dist/meetings/answers.d.ts +14 -14
- package/dist/meetings/cli/index.js +7 -4
- package/dist/meetings/cli/search.js +11 -13
- package/dist/meetings/item.d.ts +4 -4
- package/dist/meetings/project-evidence-answer.d.ts +3 -3
- package/dist/services/admin-statistics.js +2 -2
- package/dist/services/context-evidence.js +1 -0
- package/dist/services/index.d.ts +1 -1
- package/dist/services/meeting-communications-selection.d.ts +1 -0
- package/dist/services/messages-archive-search.js +1 -1
- package/dist/services/moment.d.ts +4 -2
- package/dist/services/moment.js +13 -4
- package/dist/services/project-gathering-request.d.ts +30 -8
- package/dist/services/project-gathering-request.js +61 -8
- package/dist/services/project-gathering.d.ts +5 -2
- package/dist/services/project-gathering.js +11 -5
- package/dist/store/sqlite/context-evidence.js +24 -12
- package/dist/store/sqlite/facts.js +2 -1
- package/package.json +3 -3
|
@@ -18,7 +18,7 @@ export declare const meetingHit: v.StrictObjectSchema<{
|
|
|
18
18
|
readonly source: v.OptionalSchema<v.StrictObjectSchema<{
|
|
19
19
|
readonly ref: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
|
|
20
20
|
readonly title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
21
|
-
readonly started_at: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
21
|
+
readonly started_at: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>, undefined>;
|
|
22
22
|
readonly url: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
23
23
|
}, undefined>, undefined>;
|
|
24
24
|
}, undefined>;
|
|
@@ -29,8 +29,8 @@ export declare const meetingTranscript: v.StrictObjectSchema<{
|
|
|
29
29
|
readonly source: v.StringSchema<undefined>;
|
|
30
30
|
readonly language: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
31
31
|
/** When a newer transcript of the same source replaced it; `meetings transcript --history` shows those too. */
|
|
32
|
-
readonly superseded_at: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
33
|
-
readonly created_at: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
32
|
+
readonly superseded_at: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>, undefined>;
|
|
33
|
+
readonly created_at: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
34
34
|
readonly lines: v.ArraySchema<v.StrictObjectSchema<{
|
|
35
35
|
readonly position: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
36
36
|
readonly offset_ms: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
@@ -53,8 +53,8 @@ export declare const meetingSummary: v.StrictObjectSchema<{
|
|
|
53
53
|
readonly next_steps: v.ArraySchema<v.StringSchema<undefined>, undefined>;
|
|
54
54
|
readonly content: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
55
55
|
readonly url: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
56
|
-
readonly created_at: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
57
|
-
readonly updated_at: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
56
|
+
readonly created_at: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
57
|
+
readonly updated_at: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
58
58
|
}, undefined>;
|
|
59
59
|
/** `meetings show`: the meeting with who took part, what was said in its chat, and what it holds. */
|
|
60
60
|
export declare const meetingDetails: v.StrictObjectSchema<{
|
|
@@ -66,13 +66,13 @@ export declare const meetingDetails: v.StrictObjectSchema<{
|
|
|
66
66
|
readonly description: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
|
|
67
67
|
readonly location: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
|
|
68
68
|
readonly url: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
69
|
-
readonly started_at: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
70
|
-
readonly ended_at: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
69
|
+
readonly started_at: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>, undefined>;
|
|
70
|
+
readonly ended_at: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>, undefined>;
|
|
71
71
|
readonly duration_ms: v.NullableSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>, undefined>;
|
|
72
72
|
readonly timezone: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
|
|
73
73
|
readonly participants_count: v.NullableSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>, undefined>;
|
|
74
|
-
readonly created_at: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
75
|
-
readonly updated_at: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
74
|
+
readonly created_at: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
75
|
+
readonly updated_at: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
76
76
|
/** The stored event and series it belongs to, as `meetings_list` takes them. */
|
|
77
77
|
readonly event_id: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
78
78
|
readonly series_id: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
@@ -81,8 +81,8 @@ export declare const meetingDetails: v.StrictObjectSchema<{
|
|
|
81
81
|
readonly name: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
82
82
|
readonly email: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
83
83
|
readonly role: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
84
|
-
readonly joined_at: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
85
|
-
readonly left_at: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
84
|
+
readonly joined_at: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>, undefined>;
|
|
85
|
+
readonly left_at: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>, undefined>;
|
|
86
86
|
readonly duration_ms: v.NullableSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>, undefined>;
|
|
87
87
|
}, undefined>, undefined>;
|
|
88
88
|
readonly transcripts: v.ArraySchema<v.StrictObjectSchema<{
|
|
@@ -92,7 +92,7 @@ export declare const meetingDetails: v.StrictObjectSchema<{
|
|
|
92
92
|
readonly lines_count: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
93
93
|
}, undefined>, undefined>;
|
|
94
94
|
readonly chat: v.ArraySchema<v.StrictObjectSchema<{
|
|
95
|
-
readonly sent_at: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
95
|
+
readonly sent_at: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
96
96
|
readonly sender: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
97
97
|
readonly recipient: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
98
98
|
readonly text: v.StringSchema<undefined>;
|
|
@@ -110,8 +110,8 @@ export declare const meetingDetails: v.StrictObjectSchema<{
|
|
|
110
110
|
readonly next_steps: v.ArraySchema<v.StringSchema<undefined>, undefined>;
|
|
111
111
|
readonly content: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
112
112
|
readonly url: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
113
|
-
readonly created_at: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
114
|
-
readonly updated_at: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
113
|
+
readonly created_at: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
114
|
+
readonly updated_at: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
115
115
|
}, undefined>, undefined>;
|
|
116
116
|
readonly attachments: v.ArraySchema<v.StrictObjectSchema<{
|
|
117
117
|
readonly position: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { annotate } from "@wirecat/cli-base/commands";
|
|
2
|
-
import { defineQuery, fieldsHelp } from "@wirecat/cli-base/query";
|
|
2
|
+
import { defineQuery, fieldsHelp, timezoneOf, zonedMoment } from "@wirecat/cli-base/query";
|
|
3
3
|
import { InvalidArgumentError, Option } from "commander";
|
|
4
4
|
import { exportMeeting } from "../export.js";
|
|
5
5
|
import { importFiles } from "../import.js";
|
|
@@ -19,9 +19,12 @@ const lookbackDays = (text) => {
|
|
|
19
19
|
return Number(text);
|
|
20
20
|
};
|
|
21
21
|
const date = (text) => {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
try {
|
|
23
|
+
return zonedMoment(text, timezoneOf(), { start: 0, end: text.length });
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
throw new InvalidArgumentError("expected an ISO date, or a time with or without an offset");
|
|
27
|
+
}
|
|
25
28
|
};
|
|
26
29
|
const LOCAL_READ = { remote: "none", local: "read" };
|
|
27
30
|
const LOCAL_WRITE = { remote: "none", local: "write" };
|
|
@@ -1,25 +1,23 @@
|
|
|
1
1
|
import { CliError } from "@wirecat/cli-base";
|
|
2
2
|
import { annotate } from "@wirecat/cli-base/commands";
|
|
3
|
+
import { timezoneOf, zonedMoment } from "@wirecat/cli-base/query";
|
|
3
4
|
import { Command } from "commander";
|
|
4
5
|
import { meetingHitsList } from "../answers.js";
|
|
5
6
|
import { validateMeetingHitSearch } from "../search-validation.js";
|
|
6
7
|
export { validateMeetingHitSearch } from "../search-validation.js";
|
|
8
|
+
const moment = (flag, end) => (value) => {
|
|
9
|
+
try {
|
|
10
|
+
return zonedMoment(value, timezoneOf(), { start: 0, end: value.length }, { end });
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
throw new CliError("validation_error", `${flag} takes an ISO date, or a time with or without an offset`);
|
|
14
|
+
}
|
|
15
|
+
};
|
|
7
16
|
const integer = (value) => {
|
|
8
17
|
if (!/^[1-9]\d*$/.test(value) || !Number.isSafeInteger(Number(value)))
|
|
9
18
|
throw new CliError("validation_error", "expected a positive safe integer");
|
|
10
19
|
return Number(value);
|
|
11
20
|
};
|
|
12
|
-
const timestamp = (value) => {
|
|
13
|
-
const parsed = Date.parse(value);
|
|
14
|
-
const date = value.slice(0, 10);
|
|
15
|
-
const day = Date.parse(`${date}T00:00:00Z`);
|
|
16
|
-
if (!/^\d{4}-\d{2}-\d{2}(?:T.+(?:Z|[+-]\d{2}:\d{2}))?$/.test(value) ||
|
|
17
|
-
!Number.isFinite(parsed) ||
|
|
18
|
-
!Number.isFinite(day) ||
|
|
19
|
-
new Date(day).toISOString().slice(0, 10) !== date)
|
|
20
|
-
throw new CliError("validation_error", "meeting search dates require a real ISO date or timestamp with offset");
|
|
21
|
-
return parsed;
|
|
22
|
-
};
|
|
23
21
|
/** Shared grammar without an action: a host with other source reports supplies their transport routing. */
|
|
24
22
|
export const createMeetingSearchCommand = (program) => {
|
|
25
23
|
let search = program.commands.find((command) => command.name() === "search");
|
|
@@ -39,8 +37,8 @@ export const createMeetingSearchCommand = (program) => {
|
|
|
39
37
|
.option("--project <name>", "meetings confirmed in this project, by name, key or alias")
|
|
40
38
|
.option("--tag <name>", "meetings with this tag, by name or alias")
|
|
41
39
|
.option("--topic <name>", "meetings with this topic, by name or alias")
|
|
42
|
-
.option("--since-time <time>", "meetings starting at or after this ISO 8601 date or time",
|
|
43
|
-
.option("--until-time <time>", "meetings starting at or before this ISO 8601 date or time",
|
|
40
|
+
.option("--since-time <time>", "meetings starting at or after this ISO 8601 date or time", moment("--since-time", false))
|
|
41
|
+
.option("--until-time <time>", "meetings starting at or before this ISO 8601 date or time; a date alone covers that whole local day", moment("--until-time", true))
|
|
44
42
|
.option("--limit <n>", "how many hits, 1 through 1000 (default 100)", integer)
|
|
45
43
|
.option("--cursor <cursor>", "continue from the previous page's page.next_cursor, with the same query and filters")
|
|
46
44
|
.option("--max-read-bytes <bytes>", "most stored bytes to read, 1 through 67108864 (default 4194304)", integer);
|
package/dist/meetings/item.d.ts
CHANGED
|
@@ -11,13 +11,13 @@ export declare const meeting: v.StrictObjectSchema<{
|
|
|
11
11
|
readonly location: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
|
|
12
12
|
/** The link that joins it. */
|
|
13
13
|
readonly url: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
14
|
-
readonly started_at: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
15
|
-
readonly ended_at: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
14
|
+
readonly started_at: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>, undefined>;
|
|
15
|
+
readonly ended_at: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>, undefined>;
|
|
16
16
|
readonly duration_ms: v.NullableSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>, undefined>;
|
|
17
17
|
readonly timezone: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
|
|
18
18
|
readonly participants_count: v.NullableSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>, undefined>;
|
|
19
|
-
readonly created_at: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
20
|
-
readonly updated_at: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
19
|
+
readonly created_at: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
20
|
+
readonly updated_at: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>;
|
|
21
21
|
}, undefined>;
|
|
22
22
|
export type MeetingItem = v.InferOutput<typeof meeting>;
|
|
23
23
|
/** Which provider and account a stored meeting account is, as `MeetingStore.account` answers it. */
|
|
@@ -27,7 +27,7 @@ export declare const meetingProjectEvidence: v.StrictObjectSchema<{
|
|
|
27
27
|
readonly source: v.OptionalSchema<v.StrictObjectSchema<{
|
|
28
28
|
readonly ref: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a reference such as `note:42`">]>;
|
|
29
29
|
readonly title: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
30
|
-
readonly started_at: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
30
|
+
readonly started_at: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>, undefined>;
|
|
31
31
|
readonly url: v.NullableSchema<v.StringSchema<undefined>, undefined>;
|
|
32
32
|
}, undefined>, undefined>;
|
|
33
33
|
}, undefined>, undefined>;
|
|
@@ -40,8 +40,8 @@ export declare const meetingProjectEvidence: v.StrictObjectSchema<{
|
|
|
40
40
|
readonly tag_id: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>, undefined>;
|
|
41
41
|
readonly event_id: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>, undefined>;
|
|
42
42
|
readonly series_id: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>, undefined>;
|
|
43
|
-
readonly since: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
44
|
-
readonly until: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time
|
|
43
|
+
readonly since: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>, undefined>;
|
|
44
|
+
readonly until: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time in UTC">, v.EndsWithAction<string, "Z", "an ISO 8601 time in UTC, ending in `Z`">]>, undefined>;
|
|
45
45
|
}, undefined>;
|
|
46
46
|
readonly limits: v.StrictObjectSchema<{
|
|
47
47
|
readonly limit: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
@@ -213,10 +213,10 @@ export const adminStatisticsService = (deps) => ({
|
|
|
213
213
|
: duration(query.olderThan ?? "24h", "--older-than"),
|
|
214
214
|
within: query.within === undefined && pinned ? pinned.options.within : duration(query.within ?? "7d", "--within"),
|
|
215
215
|
joinSince: query.sinceTime
|
|
216
|
-
? momentOf(query.sinceTime, "--since-time", cutoff)
|
|
216
|
+
? momentOf(query.sinceTime, "--since-time", cutoff, { zone: prepared.timezone })
|
|
217
217
|
: (pinned?.options.joinSince ?? cutoff - 30 * 86_400_000),
|
|
218
218
|
joinUntil: query.untilTime
|
|
219
|
-
? momentOf(query.untilTime, "--until-time", cutoff)
|
|
219
|
+
? momentOf(query.untilTime, "--until-time", cutoff, { zone: prepared.timezone, end: true })
|
|
220
220
|
: (pinned?.options.joinUntil ?? cutoff),
|
|
221
221
|
minViews: count(query.minViews ?? pinned?.options.minViews ?? 1, "--min-views"),
|
|
222
222
|
maxReplies: count(query.maxReplies ?? pinned?.options.maxReplies ?? 0, "--max-replies"),
|
|
@@ -23,6 +23,7 @@ export const createContextEvidenceReader = (port, allowed, limits) => {
|
|
|
23
23
|
source: Object.freeze({ ...source }),
|
|
24
24
|
...(validated.query === undefined ? {} : { query: validated.query }),
|
|
25
25
|
...(validated.chat === undefined ? {} : { chat: validated.chat }),
|
|
26
|
+
...(validated.senders === undefined ? {} : { senders: Object.freeze([...validated.senders]) }),
|
|
26
27
|
after: validated.after,
|
|
27
28
|
before: validated.before,
|
|
28
29
|
limit: validated.limit,
|
package/dist/services/index.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export type { ProjectNeighbour, ProjectNeighbourReader } from "./project-gatheri
|
|
|
9
9
|
export { documentPassage, storedMessageNeighbours, storedNeighbours } from "./project-gathering-around.js";
|
|
10
10
|
export type { EvidenceMention, EvidenceMentions } from "./project-gathering-mentions.js";
|
|
11
11
|
export { findEvidenceMentions } from "./project-gathering-mentions.js";
|
|
12
|
-
export type { ProjectFetchState, ProjectGatheringBudgets, ProjectGatheringRequest, ProjectLane, ProjectLaneKind, ProjectLinkedChat, ProjectUnitState, } from "./project-gathering-request.js";
|
|
12
|
+
export type { ProjectFetchState, ProjectGatheringBudgets, ProjectGatheringRequest, ProjectLane, ProjectLaneKind, ProjectLinkedChat, ProjectPerson, ProjectSender, ProjectUnitState, } from "./project-gathering-request.js";
|
|
13
13
|
import { type AccountService } from "./account.js";
|
|
14
14
|
import { type AdminService } from "./admin.js";
|
|
15
15
|
import { type AdminStatisticsService } from "./admin-statistics.js";
|
|
@@ -16,6 +16,7 @@ export declare const captureCommunicationSelections: (port: MeetingCommunication
|
|
|
16
16
|
source: import("./context-evidence.js").ContextSource;
|
|
17
17
|
query: string | undefined;
|
|
18
18
|
chat: string | undefined;
|
|
19
|
+
senders: string[] | undefined;
|
|
19
20
|
after: number;
|
|
20
21
|
before: number;
|
|
21
22
|
limit: number;
|
|
@@ -65,7 +65,7 @@ const searchPage = async (store, account, request, messenger) => {
|
|
|
65
65
|
throw new CliError("validation_error", "discovery searches the local archive; use backend archive");
|
|
66
66
|
await topUp(store);
|
|
67
67
|
const found = request.discover
|
|
68
|
-
? await searchDiscovery(store, account, request, messenger)
|
|
68
|
+
? await searchDiscovery(store, account, { ...request, thread: undefined }, messenger)
|
|
69
69
|
: await searchLucene(store, account, request, messenger);
|
|
70
70
|
return withThreads(store, found, request);
|
|
71
71
|
};
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
+
import { type MomentZone } from "../domain/moment.js";
|
|
2
|
+
export type { MomentZone };
|
|
1
3
|
/** Shaped like a moment `momentOf` reads, whether or not it is a valid one. */
|
|
2
4
|
export declare const isMoment: (reference: string) => boolean;
|
|
3
5
|
/**
|
|
4
6
|
* `--since` as a moment: ISO 8601, or `30m`, `2h`, `1d` ago. Unlike max-cli, never a message id —
|
|
5
7
|
* a MAX id carries its time, and a Telegram id is only a counter within one chat.
|
|
6
8
|
*/
|
|
7
|
-
export declare const momentOf: (reference: string, flag?: string, now?: number) => number;
|
|
9
|
+
export declare const momentOf: (reference: string, flag?: string, now?: number, at?: MomentZone) => number;
|
|
8
10
|
/**
|
|
9
11
|
* A time ahead, for a due date or the next check: ISO 8601, or `30m`, `2h`, `3d` from now. `none`
|
|
10
12
|
* is not a time; a caller that clears a date checks for it first.
|
|
11
13
|
*/
|
|
12
|
-
export declare const aheadOf: (reference: string, flag: string, now?: number) => number;
|
|
14
|
+
export declare const aheadOf: (reference: string, flag: string, now?: number, at?: MomentZone) => number;
|
package/dist/services/moment.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { CliError } from "@wirecat/cli-base";
|
|
2
|
+
import { calendarMoment } from "../domain/moment.js";
|
|
2
3
|
const AGO = /^(\d+)(m|h|d)$/;
|
|
3
4
|
const AGO_MS = { m: 60_000, h: 3_600_000, d: 86_400_000 };
|
|
4
5
|
const DATE = /^\d{4}-\d{2}-\d{2}/;
|
|
@@ -11,11 +12,15 @@ export const isMoment = (reference) => {
|
|
|
11
12
|
* `--since` as a moment: ISO 8601, or `30m`, `2h`, `1d` ago. Unlike max-cli, never a message id —
|
|
12
13
|
* a MAX id carries its time, and a Telegram id is only a counter within one chat.
|
|
13
14
|
*/
|
|
14
|
-
export const momentOf = (reference, flag = "--since", now = Date.now()) => {
|
|
15
|
+
export const momentOf = (reference, flag = "--since", now = Date.now(), at = {}) => {
|
|
15
16
|
const wanted = reference.trim();
|
|
16
17
|
const [, amount, unit] = AGO.exec(wanted) ?? [];
|
|
17
18
|
// By shape: `Date.parse("12345")` is the year 12345, so a message id would pass as a date.
|
|
18
|
-
const time = amount && unit
|
|
19
|
+
const time = amount && unit
|
|
20
|
+
? now - Number(amount) * (AGO_MS[unit] ?? 0)
|
|
21
|
+
: DATE.test(wanted)
|
|
22
|
+
? calendarMoment(wanted, flag, at)
|
|
23
|
+
: Number.NaN;
|
|
19
24
|
if (Number.isNaN(time)) {
|
|
20
25
|
throw new CliError("validation_error", `${flag} takes an ISO 8601 time or 30m, 2h, 1d ago — not "${wanted}"`);
|
|
21
26
|
}
|
|
@@ -25,10 +30,14 @@ export const momentOf = (reference, flag = "--since", now = Date.now()) => {
|
|
|
25
30
|
* A time ahead, for a due date or the next check: ISO 8601, or `30m`, `2h`, `3d` from now. `none`
|
|
26
31
|
* is not a time; a caller that clears a date checks for it first.
|
|
27
32
|
*/
|
|
28
|
-
export const aheadOf = (reference, flag, now = Date.now()) => {
|
|
33
|
+
export const aheadOf = (reference, flag, now = Date.now(), at = {}) => {
|
|
29
34
|
const wanted = reference.trim();
|
|
30
35
|
const [, amount, unit] = AGO.exec(wanted) ?? [];
|
|
31
|
-
const time = amount && unit
|
|
36
|
+
const time = amount && unit
|
|
37
|
+
? now + Number(amount) * (AGO_MS[unit] ?? 0)
|
|
38
|
+
: DATE.test(wanted)
|
|
39
|
+
? calendarMoment(wanted, flag, at)
|
|
40
|
+
: Number.NaN;
|
|
32
41
|
if (Number.isNaN(time)) {
|
|
33
42
|
throw new CliError("validation_error", `${flag} takes an ISO 8601 time or 30m, 2h, 3d from now — not "${wanted}"`);
|
|
34
43
|
}
|
|
@@ -7,10 +7,7 @@ export interface ProjectGatheringRequest {
|
|
|
7
7
|
aliases?: string[];
|
|
8
8
|
};
|
|
9
9
|
keywords?: string[];
|
|
10
|
-
people?:
|
|
11
|
-
name: string;
|
|
12
|
-
reference?: string;
|
|
13
|
-
}[];
|
|
10
|
+
people?: ProjectPerson[];
|
|
14
11
|
sources: ContextSource[];
|
|
15
12
|
/** Chats the host confirmed as the project's; each is read whole, through the source of its own account. */
|
|
16
13
|
linkedChats?: ProjectLinkedChat[];
|
|
@@ -30,6 +27,20 @@ export interface ProjectGatheringRequest {
|
|
|
30
27
|
checkpoint?: string;
|
|
31
28
|
signal?: AbortSignal;
|
|
32
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* `name` is searched as words; `senders` are the person's stored identities, and every message or mail one of them
|
|
32
|
+
* wrote in the window is read. A sender lane needs the person's `reference`.
|
|
33
|
+
*/
|
|
34
|
+
export interface ProjectPerson {
|
|
35
|
+
name?: string;
|
|
36
|
+
reference?: string;
|
|
37
|
+
senders?: ProjectSender[];
|
|
38
|
+
}
|
|
39
|
+
/** One stored identity by its provider and the provider's own id; an email identity's id is its address. */
|
|
40
|
+
export interface ProjectSender {
|
|
41
|
+
provider: string;
|
|
42
|
+
id: string;
|
|
43
|
+
}
|
|
33
44
|
export interface ProjectLinkedChat {
|
|
34
45
|
provider: string;
|
|
35
46
|
account: string;
|
|
@@ -42,13 +53,15 @@ export interface ProjectGatheringBudgets {
|
|
|
42
53
|
maxElapsedMs?: number;
|
|
43
54
|
maxItems?: number;
|
|
44
55
|
}
|
|
45
|
-
export type ProjectLaneKind = "project" | "key" | "alias" | "keyword" | "person" | "linked-chat";
|
|
56
|
+
export type ProjectLaneKind = "project" | "key" | "alias" | "keyword" | "person" | "sender" | "linked-chat";
|
|
46
57
|
export interface ProjectLane {
|
|
47
58
|
id: string;
|
|
48
59
|
kinds: ProjectLaneKind[];
|
|
49
|
-
/** Null for a linked chat's lane, which
|
|
60
|
+
/** Null for a linked chat's or a sender's lane, which read every message of the chat or of the sender. */
|
|
50
61
|
query: string | null;
|
|
51
62
|
people: string[];
|
|
63
|
+
/** A sender lane only: the identities whose messages and mail it reads. */
|
|
64
|
+
senders?: ProjectSender[];
|
|
52
65
|
/** A linked chat's lane only: the chat's reference. */
|
|
53
66
|
chat?: string;
|
|
54
67
|
}
|
|
@@ -96,10 +109,18 @@ export declare const projectGatheringRequest: (input: ProjectGatheringRequest, n
|
|
|
96
109
|
aliases: string[];
|
|
97
110
|
};
|
|
98
111
|
keywords: string[];
|
|
99
|
-
people: {
|
|
112
|
+
people: ({
|
|
100
113
|
name: string;
|
|
101
114
|
reference: string | null;
|
|
102
|
-
|
|
115
|
+
senders?: undefined;
|
|
116
|
+
} | {
|
|
117
|
+
name: string | null;
|
|
118
|
+
reference: string | null;
|
|
119
|
+
senders: {
|
|
120
|
+
provider: string;
|
|
121
|
+
id: string;
|
|
122
|
+
}[];
|
|
123
|
+
})[];
|
|
103
124
|
lanes: ProjectLane[];
|
|
104
125
|
sources: ContextSource[];
|
|
105
126
|
linkedChats: {
|
|
@@ -148,6 +169,7 @@ export declare const projectUnits: (plan: ProjectGatheringPlan, window: {
|
|
|
148
169
|
before: number;
|
|
149
170
|
};
|
|
150
171
|
chat: string | undefined;
|
|
172
|
+
senders: string[] | undefined;
|
|
151
173
|
}[];
|
|
152
174
|
export declare const seenKey: (ref: string) => string;
|
|
153
175
|
export declare const encodeCheckpoint: (checkpoint: ProjectGatheringCheckpoint) => string;
|
|
@@ -6,7 +6,15 @@ import { formatReference } from "../domain/references.js";
|
|
|
6
6
|
const DAY = 86400000;
|
|
7
7
|
const MAX_TIME = 8_640_000_000_000_000;
|
|
8
8
|
export const CONTEXT_CHUNK_DAYS = 90;
|
|
9
|
-
const LIMITS = {
|
|
9
|
+
const LIMITS = {
|
|
10
|
+
lanes: 16,
|
|
11
|
+
sources: 32,
|
|
12
|
+
units: 512,
|
|
13
|
+
lookbackDays: 730,
|
|
14
|
+
people: 16,
|
|
15
|
+
linkedChats: 16,
|
|
16
|
+
senders: 16,
|
|
17
|
+
};
|
|
10
18
|
const BUDGETS = {
|
|
11
19
|
maxReads: [48, 512],
|
|
12
20
|
maxReadBytes: [2097152, 16777216],
|
|
@@ -77,11 +85,29 @@ export const projectGatheringRequest = (input, now) => {
|
|
|
77
85
|
const people = list(input.people, "people", LIMITS.people).map((person, i) => {
|
|
78
86
|
if (!person || typeof person !== "object")
|
|
79
87
|
return fail(`people.${i} needs a name`, `people.${i}`);
|
|
80
|
-
known(person, ["name", "reference"], `people.${i}.`);
|
|
88
|
+
known(person, ["name", "reference", "senders"], `people.${i}.`);
|
|
81
89
|
const p = person;
|
|
90
|
+
const reference = p.reference === undefined ? null : text(p.reference, `people.${i}.reference`, 1024);
|
|
91
|
+
if (p.senders === undefined)
|
|
92
|
+
return { name: laneQuery(p.name, `people.${i}.name`), reference };
|
|
93
|
+
const senders = list(p.senders, `people.${i}.senders`, LIMITS.senders).map((value, j) => {
|
|
94
|
+
const name = `people.${i}.senders.${j}`;
|
|
95
|
+
if (!value || typeof value !== "object")
|
|
96
|
+
return fail(`${name} needs provider and id`, name);
|
|
97
|
+
known(value, ["provider", "id"], `${name}.`);
|
|
98
|
+
const given = value;
|
|
99
|
+
return { provider: text(given.provider, `${name}.provider`, 128), id: text(given.id, `${name}.id`, 1024) };
|
|
100
|
+
});
|
|
101
|
+
if (!senders.length)
|
|
102
|
+
fail(`people.${i}.senders needs at least one identity`, `people.${i}.senders`);
|
|
103
|
+
if (new Set(senders.map((one) => JSON.stringify([one.provider, one.id]))).size !== senders.length)
|
|
104
|
+
fail(`people.${i}.senders lists one identity twice`, `people.${i}.senders`);
|
|
105
|
+
if (reference === null)
|
|
106
|
+
fail(`people.${i} needs a reference to read by sender`, `people.${i}.reference`);
|
|
82
107
|
return {
|
|
83
|
-
name: laneQuery(p.name, `people.${i}.name`),
|
|
84
|
-
reference
|
|
108
|
+
name: p.name === undefined ? null : laneQuery(p.name, `people.${i}.name`),
|
|
109
|
+
reference,
|
|
110
|
+
senders,
|
|
85
111
|
};
|
|
86
112
|
});
|
|
87
113
|
if (input.scope !== "explicit" && input.scope !== "all-connected")
|
|
@@ -139,7 +165,17 @@ export const projectGatheringRequest = (input, now) => {
|
|
|
139
165
|
for (const k of keywords)
|
|
140
166
|
lane("keyword", k);
|
|
141
167
|
for (const p of people)
|
|
142
|
-
|
|
168
|
+
if (p.name !== null)
|
|
169
|
+
lane("person", p.name, p.reference ?? p.name);
|
|
170
|
+
for (const p of people)
|
|
171
|
+
if (p.senders && p.reference !== null)
|
|
172
|
+
lanes.push({
|
|
173
|
+
id: `l${lanes.length + 1}`,
|
|
174
|
+
kinds: ["sender"],
|
|
175
|
+
query: null,
|
|
176
|
+
people: [p.reference],
|
|
177
|
+
senders: p.senders,
|
|
178
|
+
});
|
|
143
179
|
if (lanes.length > LIMITS.lanes)
|
|
144
180
|
fail(`at most ${LIMITS.lanes} distinct search lanes`, "keywords");
|
|
145
181
|
for (const linked of linkedChats) {
|
|
@@ -248,16 +284,33 @@ export const projectUnits = (plan, window) => {
|
|
|
248
284
|
sourceIndex,
|
|
249
285
|
chunk,
|
|
250
286
|
chat: undefined,
|
|
287
|
+
senders: undefined,
|
|
251
288
|
}))));
|
|
252
|
-
//
|
|
289
|
+
// Only the sources of a sender's own provider: an identity of one messenger never wrote in another.
|
|
290
|
+
const bySender = chunks.flatMap((chunk) => plan.lanes.flatMap((lane) => plan.sources.flatMap((source, sourceIndex) => {
|
|
291
|
+
if (!lane.senders || (source.kind !== "message" && source.kind !== "mail"))
|
|
292
|
+
return [];
|
|
293
|
+
const ids = lane.senders.filter((one) => one.provider === source.provider).map((one) => one.id);
|
|
294
|
+
return ids.length ? [{ lane, source, sourceIndex, chunk, chat: undefined, senders: ids }] : [];
|
|
295
|
+
})));
|
|
296
|
+
// Appended after every literal and sender unit: a checkpoint from a run without links keeps its unit order, and in each
|
|
253
297
|
// round a literal lane labels a shared hit before the linked chat does.
|
|
254
298
|
const linked = chunks.flatMap((chunk) => plan.linkedChats.flatMap(({ lane, source, chat }) => {
|
|
255
299
|
const found = plan.lanes.find((l) => l.id === lane);
|
|
256
300
|
return found && source !== null
|
|
257
|
-
? [
|
|
301
|
+
? [
|
|
302
|
+
{
|
|
303
|
+
lane: found,
|
|
304
|
+
source: plan.sources[source],
|
|
305
|
+
sourceIndex: source,
|
|
306
|
+
chunk,
|
|
307
|
+
chat,
|
|
308
|
+
senders: undefined,
|
|
309
|
+
},
|
|
310
|
+
]
|
|
258
311
|
: [];
|
|
259
312
|
}));
|
|
260
|
-
const units = [...literal, ...linked];
|
|
313
|
+
const units = [...literal, ...bySender, ...linked];
|
|
261
314
|
if (units.length > LIMITS.units)
|
|
262
315
|
fail(`${units.length} lane × source × 90-day reads exceed ${LIMITS.units}; narrow the lanes, sources or window`);
|
|
263
316
|
return units;
|
|
@@ -39,8 +39,11 @@ export interface ProjectEvidenceItem extends Omit<ContextEvidenceItem, "text"> {
|
|
|
39
39
|
/** A document hit with `around`: how many paragraphs after the one it centres on also name a lane word. */
|
|
40
40
|
moreMatches?: number;
|
|
41
41
|
}
|
|
42
|
-
/**
|
|
43
|
-
|
|
42
|
+
/**
|
|
43
|
+
* Strongest first: a hit that names the project, then one only from a linked chat, then one a person wrote, then one
|
|
44
|
+
* naming only a person.
|
|
45
|
+
*/
|
|
46
|
+
export type ProjectEvidenceContext = "project" | "linked-chat" | "sender" | "person-only";
|
|
44
47
|
export type ProjectGatheringStop = "reads" | "read-bytes" | "elapsed" | "items" | null;
|
|
45
48
|
export declare const gatherProjectEvidence: (ports: ProjectGatheringPorts, request: ProjectGatheringRequest) => Promise<{
|
|
46
49
|
schemaVersion: 1;
|
|
@@ -5,12 +5,14 @@ import { excerpt } from "./excerpt.js";
|
|
|
5
5
|
import { attachNeighbours, documentMatches, } from "./project-gathering-around.js";
|
|
6
6
|
import { decodeCheckpoint, encodeCheckpoint, projectGatheringRequest, projectUnits, seenKey, } from "./project-gathering-request.js";
|
|
7
7
|
const terminal = new Set(["done", "unavailable", "failed"]);
|
|
8
|
-
const CONTEXTS = ["person-only", "linked-chat", "project"];
|
|
8
|
+
const CONTEXTS = ["person-only", "sender", "linked-chat", "project"];
|
|
9
9
|
const contextOf = (lane) => lane.kinds.includes("linked-chat")
|
|
10
10
|
? "linked-chat"
|
|
11
|
-
: lane.kinds.
|
|
12
|
-
? "
|
|
13
|
-
: "
|
|
11
|
+
: lane.kinds.includes("sender")
|
|
12
|
+
? "sender"
|
|
13
|
+
: lane.kinds.every((k) => k === "person")
|
|
14
|
+
? "person-only"
|
|
15
|
+
: "project";
|
|
14
16
|
export const gatherProjectEvidence = async (ports, request) => {
|
|
15
17
|
if (!ports?.evidence || typeof ports.evidence.read !== "function")
|
|
16
18
|
throw new CliError("configuration_error", "stored context reads are unavailable in this store");
|
|
@@ -164,7 +166,11 @@ export const gatherProjectEvidence = async (ports, request) => {
|
|
|
164
166
|
try {
|
|
165
167
|
const page = await reader.read({
|
|
166
168
|
source: unit.source,
|
|
167
|
-
...(unit.chat
|
|
169
|
+
...(unit.chat !== undefined
|
|
170
|
+
? { chat: unit.chat }
|
|
171
|
+
: unit.senders !== undefined
|
|
172
|
+
? { senders: unit.senders }
|
|
173
|
+
: { query: unit.lane.query ?? undefined }),
|
|
168
174
|
after: unit.chunk.after,
|
|
169
175
|
before: unit.chunk.before,
|
|
170
176
|
limit,
|