crewly 1.20.382 → 1.20.384

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dist/backend/backend/src/constants.d.ts +53 -0
  2. package/dist/backend/backend/src/constants.d.ts.map +1 -1
  3. package/dist/backend/backend/src/constants.js +53 -0
  4. package/dist/backend/backend/src/constants.js.map +1 -1
  5. package/dist/backend/backend/src/index.d.ts.map +1 -1
  6. package/dist/backend/backend/src/index.js +96 -12
  7. package/dist/backend/backend/src/index.js.map +1 -1
  8. package/dist/backend/backend/src/services/drive/drive-agent.service.d.ts +16 -2
  9. package/dist/backend/backend/src/services/drive/drive-agent.service.d.ts.map +1 -1
  10. package/dist/backend/backend/src/services/drive/drive-agent.service.js +60 -5
  11. package/dist/backend/backend/src/services/drive/drive-agent.service.js.map +1 -1
  12. package/dist/backend/backend/src/services/drive/drive-cloud.contract.d.ts +61 -1
  13. package/dist/backend/backend/src/services/drive/drive-cloud.contract.d.ts.map +1 -1
  14. package/dist/backend/backend/src/services/drive/drive-cloud.contract.js +72 -3
  15. package/dist/backend/backend/src/services/drive/drive-cloud.contract.js.map +1 -1
  16. package/dist/backend/backend/src/services/drive/drive-meeting-pack.d.ts +233 -0
  17. package/dist/backend/backend/src/services/drive/drive-meeting-pack.d.ts.map +1 -0
  18. package/dist/backend/backend/src/services/drive/drive-meeting-pack.js +327 -0
  19. package/dist/backend/backend/src/services/drive/drive-meeting-pack.js.map +1 -0
  20. package/dist/backend/backend/src/services/drive/drive-meeting.service.d.ts +157 -0
  21. package/dist/backend/backend/src/services/drive/drive-meeting.service.d.ts.map +1 -0
  22. package/dist/backend/backend/src/services/drive/drive-meeting.service.js +219 -0
  23. package/dist/backend/backend/src/services/drive/drive-meeting.service.js.map +1 -0
  24. package/dist/backend/backend/src/services/drive/drive-meeting.wiring.d.ts +80 -0
  25. package/dist/backend/backend/src/services/drive/drive-meeting.wiring.d.ts.map +1 -0
  26. package/dist/backend/backend/src/services/drive/drive-meeting.wiring.js +153 -0
  27. package/dist/backend/backend/src/services/drive/drive-meeting.wiring.js.map +1 -0
  28. package/dist/backend/build-info.json +2 -2
  29. package/dist/cli/backend/src/constants.d.ts +53 -0
  30. package/dist/cli/backend/src/constants.d.ts.map +1 -1
  31. package/dist/cli/backend/src/constants.js +53 -0
  32. package/dist/cli/backend/src/constants.js.map +1 -1
  33. package/package.json +1 -1
@@ -0,0 +1,157 @@
1
+ /**
2
+ * DriveMeetingService — the machine side of a voice 1:1 meeting with one
3
+ * agent (Meetings P2b, crewly#1415). Cloud hosts the meeting; this machine
4
+ * answers what only it can, for that agent only:
5
+ *
6
+ * - `buildPack` (`op:'meeting_pack'`): the agent's meeting pack — role,
7
+ * team, handover, work, the last owner↔agent messages, recent decisions,
8
+ * the agenda of open threads and relevant wiki pages
9
+ * (drive-meeting-pack.ts);
10
+ * - `searchWiki` (`op:'wiki_search'`): BM25 over the agent's own team and
11
+ * project vaults, top snippets in plain words, with the time it took;
12
+ * - `writeBack` (a delivery carrying `writeBack`): a decision, answer, task
13
+ * or note from the meeting is written into the thread it belongs to — a
14
+ * Slack thread (posted by the agent's bot, recorded in Crewly chat), a
15
+ * Crewly chat thread, or the open decision card it answers — and the
16
+ * agent gets it like any message from the owner. A new topic starts a
17
+ * new thread, which later write-backs on that topic reuse.
18
+ *
19
+ * Nothing the owner or the agent says is written to this machine's server
20
+ * logs: only counts, sizes and timings.
21
+ *
22
+ * @module services/drive/drive-meeting.service
23
+ */
24
+ import { MEETING_CONSTANTS } from '../../constants.js';
25
+ import { type ComponentLogger } from '../core/logger.service.js';
26
+ import type { BriefingSnapshot } from './drive-briefing.contract.js';
27
+ import type { DriveMeetingPackFetch, DriveWikiFetch, DriveWriteBack } from './drive-cloud.contract.js';
28
+ import { type MeetingDecisionSource, type MeetingPackWire, type MeetingTimelineRow } from './drive-meeting-pack.js';
29
+ /** A vault the agent may read. */
30
+ export interface MeetingVault {
31
+ vaultPath: string;
32
+ label: string;
33
+ }
34
+ /** A wiki hit, as the machine reads it. */
35
+ export interface MeetingWikiPageHit {
36
+ title: string;
37
+ where: string;
38
+ text: string;
39
+ /** The page file, for the pack's longer excerpt */
40
+ absPath?: string;
41
+ }
42
+ /** Collaborators (wired in index.ts; fakes in tests). */
43
+ export interface DriveMeetingDeps {
44
+ /** The agent's chat timeline since a time (its DMs, rooms and threads) */
45
+ timeline: (agentSession: string, sinceMs: number) => Promise<MeetingTimelineRow[]>;
46
+ /** Owner decision cards (open and settled) */
47
+ decisions: () => Promise<MeetingDecisionSource[]>;
48
+ /** The latest status snapshot (work and waiting items), when there is one */
49
+ snapshot?: () => Promise<BriefingSnapshot | null>;
50
+ /** The agent's latest handover text, when there is one */
51
+ handover: (agentSession: string) => Promise<string | null>;
52
+ /** The vaults the agent may read: its teams' and their projects' (never the global wiki) */
53
+ vaults: (agentSession: string) => Promise<MeetingVault[]>;
54
+ /** BM25 over those vaults as that agent reads them (page visibility by its role), best first */
55
+ searchWiki: (vaults: MeetingVault[], query: string, agentSession: string) => Promise<MeetingWikiPageHit[]>;
56
+ /** A page's text (frontmatter removed), for the pack */
57
+ readPage?: (absPath: string) => Promise<string | null>;
58
+ /** Settle an open decision card with the owner's words; false when the words settle nothing */
59
+ answerDecision?: (decisionId: string, text: string) => Promise<boolean>;
60
+ /** The agent's Slack DM, when it has one its own bot can post in */
61
+ slackDmOf: (agentSession: string) => {
62
+ slackChannelId: string;
63
+ chatChannelId: string;
64
+ } | null;
65
+ /** The Crewly chat channel a Slack conversation is mirrored into */
66
+ chatChannelOfSlack: (slackChannelId: string) => {
67
+ chatChannelId: string;
68
+ dm: boolean;
69
+ } | null;
70
+ /** The chat thread root of a Slack thread in a room (rooms thread their Slack threads; DMs do not) */
71
+ slackRootId: (chatChannelId: string, threadTs: string) => string | null;
72
+ /** Post in Slack as the agent (its bot in a DM; in a room the agent's identity); returns the message ts */
73
+ postSlack: (input: {
74
+ agentSession: string;
75
+ slackChannelId: string;
76
+ threadTs?: string;
77
+ text: string;
78
+ }) => Promise<string | null>;
79
+ /** The owner's DM channel with the agent in Crewly chat */
80
+ ownerDmChannel: (agentSession: string) => string;
81
+ /** Record the owner's turn in Crewly chat and deliver it to the agent */
82
+ recordOwnerTurn: (input: {
83
+ agentSession: string;
84
+ channelId: string;
85
+ threadId?: string;
86
+ text: string;
87
+ metadata: MeetingRowMetadata;
88
+ }) => Promise<{
89
+ messageId: string;
90
+ }>;
91
+ now?: () => Date;
92
+ logger?: ComponentLogger;
93
+ }
94
+ /** Metadata on a chat row a write-back records. */
95
+ export interface MeetingRowMetadata {
96
+ source: typeof MEETING_CONSTANTS.SOURCE;
97
+ [key: string]: unknown;
98
+ }
99
+ /** What a write-back did. */
100
+ export interface MeetingWriteBackResult {
101
+ /** The thread it went into (a new topic's new thread included) */
102
+ threadRef?: string;
103
+ via: 'decision' | 'slack' | 'chat';
104
+ }
105
+ /** The machine side of a 1:1 meeting — see module docs. */
106
+ export declare class DriveMeetingService {
107
+ private readonly deps;
108
+ private readonly logger;
109
+ private readonly now;
110
+ /** New-topic threads by `<sessionId>\u0000<topic>`, so a second write-back reuses the first one's thread */
111
+ private readonly newThreads;
112
+ /**
113
+ * @param deps - Collaborators
114
+ */
115
+ constructor(deps: DriveMeetingDeps);
116
+ /**
117
+ * Build the meeting pack for one agent. Each source is read on its own; a
118
+ * failing one is left empty, never the whole pack.
119
+ *
120
+ * @param req - Who the meeting is with
121
+ * @returns The pack (within the token budget)
122
+ */
123
+ buildPack(req: DriveMeetingPackFetch): Promise<MeetingPackWire>;
124
+ /**
125
+ * Live wiki search for the meeting: BM25 over the agent's own vaults.
126
+ *
127
+ * @param req - Agent + query
128
+ * @returns Top hits in plain words, and how long the search took (ms)
129
+ */
130
+ searchWiki(req: DriveWikiFetch): Promise<{
131
+ hits: Array<{
132
+ title: string;
133
+ where: string;
134
+ text: string;
135
+ }>;
136
+ ms: number;
137
+ }>;
138
+ /**
139
+ * Write one meeting outcome into the thread it belongs to and hand it to
140
+ * the agent.
141
+ *
142
+ * @param input - Session, agent, the owner's words and where they go
143
+ * @returns Where it was written
144
+ */
145
+ writeBack(input: {
146
+ sessionId: string;
147
+ agentSession: string;
148
+ text: string;
149
+ writeBack: DriveWriteBack;
150
+ }): Promise<MeetingWriteBackResult>;
151
+ /** Post in a Slack thread as the agent and record it in Crewly chat. */
152
+ private writeSlack;
153
+ /** Settle the agent's open card in that thread, when there is one and the words answer it. */
154
+ private settleCard;
155
+ private remember;
156
+ }
157
+ //# sourceMappingURL=drive-meeting.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drive-meeting.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/drive/drive-meeting.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,219 @@
1
+ /**
2
+ * DriveMeetingService — the machine side of a voice 1:1 meeting with one
3
+ * agent (Meetings P2b, crewly#1415). Cloud hosts the meeting; this machine
4
+ * answers what only it can, for that agent only:
5
+ *
6
+ * - `buildPack` (`op:'meeting_pack'`): the agent's meeting pack — role,
7
+ * team, handover, work, the last owner↔agent messages, recent decisions,
8
+ * the agenda of open threads and relevant wiki pages
9
+ * (drive-meeting-pack.ts);
10
+ * - `searchWiki` (`op:'wiki_search'`): BM25 over the agent's own team and
11
+ * project vaults, top snippets in plain words, with the time it took;
12
+ * - `writeBack` (a delivery carrying `writeBack`): a decision, answer, task
13
+ * or note from the meeting is written into the thread it belongs to — a
14
+ * Slack thread (posted by the agent's bot, recorded in Crewly chat), a
15
+ * Crewly chat thread, or the open decision card it answers — and the
16
+ * agent gets it like any message from the owner. A new topic starts a
17
+ * new thread, which later write-backs on that topic reuse.
18
+ *
19
+ * Nothing the owner or the agent says is written to this machine's server
20
+ * logs: only counts, sizes and timings.
21
+ *
22
+ * @module services/drive/drive-meeting.service
23
+ */
24
+ import { performance } from 'node:perf_hooks';
25
+ import { MEETING_CONSTANTS } from '../../constants.js';
26
+ import { LoggerService } from '../core/logger.service.js';
27
+ import { clip } from '../briefing/briefing.utils.js';
28
+ import { redactSecrets } from '../../utils/secret-redactor.js';
29
+ import { buildMeetingPack, packWikiQuery, parseChatThreadRef, parseSlackThreadRef, plainWords, buildAgenda, } from './drive-meeting-pack.js';
30
+ const C = MEETING_CONSTANTS;
31
+ const KIND_LABEL = {
32
+ decision: 'Decision',
33
+ answer: 'Answer',
34
+ task: 'New task',
35
+ note: 'Note',
36
+ };
37
+ /** The machine side of a 1:1 meeting — see module docs. */
38
+ export class DriveMeetingService {
39
+ deps;
40
+ logger;
41
+ now;
42
+ /** New-topic threads by `<sessionId>\u0000<topic>`, so a second write-back reuses the first one's thread */
43
+ newThreads = new Map();
44
+ /**
45
+ * @param deps - Collaborators
46
+ */
47
+ constructor(deps) {
48
+ this.deps = deps;
49
+ this.logger = deps.logger ?? LoggerService.getInstance().createComponentLogger('DriveMeeting');
50
+ this.now = deps.now ?? (() => new Date());
51
+ }
52
+ /**
53
+ * Build the meeting pack for one agent. Each source is read on its own; a
54
+ * failing one is left empty, never the whole pack.
55
+ *
56
+ * @param req - Who the meeting is with
57
+ * @returns The pack (within the token budget)
58
+ */
59
+ async buildPack(req) {
60
+ const started = performance.now();
61
+ const now = this.now();
62
+ const agent = { session: req.agentSession, name: req.name, ...(req.role ? { role: req.role } : {}), ...(req.team ? { team: req.team } : {}) };
63
+ const [timeline, decisions, snapshot, handover] = await Promise.all([
64
+ read(() => this.deps.timeline(req.agentSession, now.getTime() - C.AGENDA_WINDOW_MS), []),
65
+ read(() => this.deps.decisions(), []),
66
+ read(async () => (this.deps.snapshot ? this.deps.snapshot() : null), null),
67
+ read(() => this.deps.handover(req.agentSession), null),
68
+ ]);
69
+ // Wiki pages for the team and the agenda topics.
70
+ const agenda = buildAgenda({ now, agent, timeline, decisions });
71
+ const query = packWikiQuery(agent, agenda);
72
+ let wiki = [];
73
+ if (query) {
74
+ const vaults = await read(() => this.deps.vaults(req.agentSession), []);
75
+ const hits = vaults.length ? await read(() => this.deps.searchWiki(vaults, query, req.agentSession), []) : [];
76
+ wiki = await Promise.all(hits.slice(0, C.WIKI_PAGES_MAX).map(async (h) => {
77
+ const page = h.absPath && this.deps.readPage ? await read(() => this.deps.readPage(h.absPath), null) : null;
78
+ return { title: h.title, where: h.where, text: clip((page ?? h.text).trim(), C.WIKI_PAGE_MAX_CHARS) };
79
+ }));
80
+ }
81
+ const pack = buildMeetingPack({ now, agent, handover, snapshot, timeline, decisions, wiki });
82
+ this.logger.info('Meeting pack built', {
83
+ agent: req.agentSession,
84
+ ms: Math.round(performance.now() - started),
85
+ estTokens: pack.estTokens,
86
+ agenda: pack.agenda.length,
87
+ messages: pack.messages.length,
88
+ work: pack.work.length,
89
+ wiki: pack.wiki.length,
90
+ handover: !!pack.handover,
91
+ });
92
+ return pack;
93
+ }
94
+ /**
95
+ * Live wiki search for the meeting: BM25 over the agent's own vaults.
96
+ *
97
+ * @param req - Agent + query
98
+ * @returns Top hits in plain words, and how long the search took (ms)
99
+ */
100
+ async searchWiki(req) {
101
+ const started = performance.now();
102
+ const vaults = await read(() => this.deps.vaults(req.agentSession), []);
103
+ const raw = vaults.length ? await read(() => this.deps.searchWiki(vaults, req.query, req.agentSession), []) : [];
104
+ const hits = raw
105
+ .slice(0, C.WIKI_HITS_MAX)
106
+ .map((h) => ({ title: clip(h.title, 160), where: clip(h.where, 160), text: plainWords(h.text, C.WIKI_HIT_MAX_CHARS) }))
107
+ .filter((h) => h.title && h.text);
108
+ const ms = Math.round(performance.now() - started);
109
+ this.logger.info('Meeting wiki search', { agent: req.agentSession, vaults: vaults.length, hits: hits.length, ms });
110
+ return { hits, ms };
111
+ }
112
+ /**
113
+ * Write one meeting outcome into the thread it belongs to and hand it to
114
+ * the agent.
115
+ *
116
+ * @param input - Session, agent, the owner's words and where they go
117
+ * @returns Where it was written
118
+ */
119
+ async writeBack(input) {
120
+ const w = input.writeBack;
121
+ const words = clip(redactSecrets(input.text.trim()), C.WRITE_BACK_MAX_CHARS);
122
+ const key = `${input.sessionId}\u0000${(w.newTopic ?? w.topic).toLowerCase()}`;
123
+ const ref = w.threadRef ?? this.newThreads.get(key);
124
+ const line = `From our voice meeting — ${KIND_LABEL[w.kind]}: ${words}`;
125
+ const meta = { source: C.SOURCE, via: C.VIA, inputMode: 'voice', meetingSessionId: input.sessionId, meetingKind: w.kind };
126
+ if (ref) {
127
+ const slack = parseSlackThreadRef(ref);
128
+ if (slack) {
129
+ // An open card in that thread: the owner's words settle it.
130
+ if ((w.kind === 'decision' || w.kind === 'answer') && (await this.settleCard(input.agentSession, ref, words))) {
131
+ return { threadRef: ref, via: 'decision' };
132
+ }
133
+ await this.writeSlack(input.agentSession, slack.slackChannelId, slack.threadTs, line, meta);
134
+ return { threadRef: ref, via: 'slack' };
135
+ }
136
+ const chat = parseChatThreadRef(ref);
137
+ if (chat) {
138
+ await this.deps.recordOwnerTurn({ agentSession: input.agentSession, channelId: chat.channelId, ...(chat.rootId ? { threadId: chat.rootId } : {}), text: line, metadata: meta });
139
+ return { threadRef: ref, via: 'chat' };
140
+ }
141
+ }
142
+ // A new topic: a new thread, in Slack when the agent has a DM there.
143
+ const topic = clip(w.newTopic ?? w.topic, C.TOPIC_MAX_CHARS);
144
+ const opening = `${topic}\n${line}`;
145
+ const dm = this.deps.slackDmOf(input.agentSession);
146
+ let made = null;
147
+ if (dm) {
148
+ const ts = await this.deps.postSlack({ agentSession: input.agentSession, slackChannelId: dm.slackChannelId, text: opening }).catch(() => null);
149
+ if (ts) {
150
+ await this.deps.recordOwnerTurn({
151
+ agentSession: input.agentSession,
152
+ channelId: dm.chatChannelId,
153
+ text: opening,
154
+ metadata: { ...meta, slackChannelId: dm.slackChannelId, slackTs: ts, slackThreadTs: ts, slackAlreadyPosted: true },
155
+ });
156
+ made = { threadRef: `slack:${dm.slackChannelId}:${ts}`, via: 'slack' };
157
+ }
158
+ }
159
+ if (!made) {
160
+ const channelId = this.deps.ownerDmChannel(input.agentSession);
161
+ const { messageId } = await this.deps.recordOwnerTurn({ agentSession: input.agentSession, channelId, text: opening, metadata: meta });
162
+ made = { threadRef: `chat:${channelId}:${messageId}`, via: 'chat' };
163
+ }
164
+ if (made.threadRef)
165
+ this.remember(key, made.threadRef);
166
+ return made;
167
+ }
168
+ /** Post in a Slack thread as the agent and record it in Crewly chat. */
169
+ async writeSlack(agentSession, slackChannelId, threadTs, text, meta) {
170
+ const ts = await this.deps.postSlack({ agentSession, slackChannelId, threadTs, text }).catch((err) => {
171
+ this.logger.warn('Meeting write-back: Slack post failed', { agent: agentSession, error: err instanceof Error ? err.message : String(err) });
172
+ return null;
173
+ });
174
+ const chat = this.deps.chatChannelOfSlack(slackChannelId);
175
+ const slackMeta = { ...meta, slackChannelId, slackThreadTs: threadTs, ...(ts ? { slackTs: ts, slackAlreadyPosted: true } : {}) };
176
+ if (chat) {
177
+ const root = chat.dm ? null : this.deps.slackRootId(chat.chatChannelId, threadTs);
178
+ await this.deps.recordOwnerTurn({ agentSession, channelId: chat.chatChannelId, ...(root ? { threadId: root } : {}), text, metadata: slackMeta });
179
+ return;
180
+ }
181
+ // Not mirrored here: the agent still gets it, in its DM.
182
+ await this.deps.recordOwnerTurn({ agentSession, channelId: this.deps.ownerDmChannel(agentSession), text, metadata: slackMeta });
183
+ }
184
+ /** Settle the agent's open card in that thread, when there is one and the words answer it. */
185
+ async settleCard(agentSession, ref, words) {
186
+ if (!this.deps.answerDecision)
187
+ return false;
188
+ const decisions = await read(() => this.deps.decisions(), []);
189
+ const card = decisions.find((d) => {
190
+ if (d.status !== 'open' || (d.asker !== agentSession && d.requestedBy !== agentSession))
191
+ return false;
192
+ const ch = d.card?.slackChannelId ?? d.place?.slackChannelId;
193
+ const ts = d.card ? (d.card.threadTs ?? d.card.messageTs) : d.place?.threadTs;
194
+ return !!ch && !!ts && `slack:${ch}:${ts}` === ref;
195
+ });
196
+ if (!card)
197
+ return false;
198
+ return this.deps.answerDecision(card.id, words).catch(() => false);
199
+ }
200
+ remember(key, ref) {
201
+ this.newThreads.set(key, ref);
202
+ while (this.newThreads.size > C.NEW_THREADS_MAX) {
203
+ const oldest = this.newThreads.keys().next().value;
204
+ if (oldest === undefined)
205
+ break;
206
+ this.newThreads.delete(oldest);
207
+ }
208
+ }
209
+ }
210
+ /** Read a source; a failure gives the fallback. */
211
+ async function read(fn, fallback) {
212
+ try {
213
+ return await fn();
214
+ }
215
+ catch {
216
+ return fallback;
217
+ }
218
+ }
219
+ //# sourceMappingURL=drive-meeting.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drive-meeting.service.js","sourceRoot":"","sources":["../../../../../../backend/src/services/drive/drive-meeting.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Reading the sources of a 1:1 meeting (Meetings P2b, crewly#1415) from this
3
+ * machine: which wiki vaults an agent may read, its latest handover, wiki
4
+ * hits as meeting pages, and decision cards in the shape the pack uses. The
5
+ * glue that binds these to the running services lives in index.ts.
6
+ *
7
+ * Privacy: an agent's vaults are its own teams' vaults and those teams'
8
+ * project vaults — never the global wiki, never another team's.
9
+ *
10
+ * @module services/drive/drive-meeting.wiring
11
+ */
12
+ import type { Team } from '../../types/index.js';
13
+ import type { OwnerDecision } from '../../types/decision.types.js';
14
+ import type { WikiSearchHit } from '../wiki/wiki-search.service.js';
15
+ import type { MeetingDecisionSource } from './drive-meeting-pack.js';
16
+ import type { MeetingVault, MeetingWikiPageHit } from './drive-meeting.service.js';
17
+ /**
18
+ * The teams an agent is a member of.
19
+ *
20
+ * @param teams - Every team
21
+ * @param agentSession - The agent
22
+ * @returns Its teams, with its role in each
23
+ */
24
+ export declare function teamsOfAgent(teams: readonly Team[], agentSession: string): Array<{
25
+ team: Team;
26
+ role?: string;
27
+ }>;
28
+ /**
29
+ * The vaults an agent may read: each of its teams' vaults, then those teams'
30
+ * project vaults (deduplicated).
31
+ *
32
+ * @param teams - Every team
33
+ * @param projects - Every project
34
+ * @param agentSession - The agent
35
+ * @param crewlyHome - CREWLY_HOME
36
+ * @returns Vaults with labels (team / project names)
37
+ */
38
+ export declare function vaultsOfAgent(teams: readonly Team[], projects: ReadonlyArray<{
39
+ id: string;
40
+ name: string;
41
+ path: string;
42
+ }>, agentSession: string, crewlyHome: string): MeetingVault[];
43
+ /**
44
+ * A wiki hit as a meeting page: a readable title, where it is, its matching
45
+ * lines, and the page file.
46
+ *
47
+ * @param hit - BM25 hit
48
+ * @returns Page hit
49
+ */
50
+ export declare function wikiHitToPage(hit: WikiSearchHit): MeetingWikiPageHit;
51
+ /**
52
+ * Remove a page's YAML frontmatter.
53
+ *
54
+ * @param text - Page text
55
+ * @returns The body
56
+ */
57
+ export declare function stripFrontmatter(text: string): string;
58
+ /**
59
+ * A wiki page's body, clipped, or null when it cannot be read.
60
+ *
61
+ * @param absPath - Page file
62
+ * @returns The body
63
+ */
64
+ export declare function readWikiPage(absPath: string): Promise<string | null>;
65
+ /**
66
+ * The agent's newest handover text, or null.
67
+ *
68
+ * @param handoverDir - Handover directory
69
+ * @param agentSession - The agent
70
+ * @returns Text (title line removed), clipped
71
+ */
72
+ export declare function readLatestHandover(handoverDir: string, agentSession: string): Promise<string | null>;
73
+ /**
74
+ * A decision card in the shape the pack uses.
75
+ *
76
+ * @param d - Owner decision
77
+ * @returns Pack source
78
+ */
79
+ export declare function decisionSource(d: OwnerDecision): MeetingDecisionSource;
80
+ //# sourceMappingURL=drive-meeting.wiring.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drive-meeting.wiring.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/drive/drive-meeting.wiring.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAGnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAQnF;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,IAAI,EAAE,EAAE,YAAY,EAAE,MAAM,GAAG,KAAK,CAAC;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAO/G;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,SAAS,IAAI,EAAE,EACtB,QAAQ,EAAE,aAAa,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,EACnE,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,GACjB,YAAY,EAAE,CAkBhB;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,aAAa,GAAG,kBAAkB,CASpE;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAErD;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAO1E;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAS1G;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,aAAa,GAAG,qBAAqB,CAgBtE"}
@@ -0,0 +1,153 @@
1
+ /**
2
+ * Reading the sources of a 1:1 meeting (Meetings P2b, crewly#1415) from this
3
+ * machine: which wiki vaults an agent may read, its latest handover, wiki
4
+ * hits as meeting pages, and decision cards in the shape the pack uses. The
5
+ * glue that binds these to the running services lives in index.ts.
6
+ *
7
+ * Privacy: an agent's vaults are its own teams' vaults and those teams'
8
+ * project vaults — never the global wiki, never another team's.
9
+ *
10
+ * @module services/drive/drive-meeting.wiring
11
+ */
12
+ import { promises as fs } from 'node:fs';
13
+ import path from 'node:path';
14
+ import { MEETING_CONSTANTS } from '../../constants.js';
15
+ import { resolveMemberSessionName } from '../../utils/member-session-name.utils.js';
16
+ import { latestHandoverFile } from '../agent/runtime-session-recovery.js';
17
+ /** Where team vaults live under the Crewly home. */
18
+ const TEAMS_DIR = 'teams';
19
+ const WIKI_DIR = 'wiki';
20
+ /** A project's vault, under its root. */
21
+ const PROJECT_VAULT = path.join('.crewly', 'wiki');
22
+ /**
23
+ * The teams an agent is a member of.
24
+ *
25
+ * @param teams - Every team
26
+ * @param agentSession - The agent
27
+ * @returns Its teams, with its role in each
28
+ */
29
+ export function teamsOfAgent(teams, agentSession) {
30
+ const out = [];
31
+ for (const team of teams) {
32
+ const m = (team.members ?? []).find((x) => x?.id && resolveMemberSessionName(team.name, x) === agentSession);
33
+ if (m)
34
+ out.push({ team, ...(m.role ? { role: String(m.role) } : {}) });
35
+ }
36
+ return out;
37
+ }
38
+ /**
39
+ * The vaults an agent may read: each of its teams' vaults, then those teams'
40
+ * project vaults (deduplicated).
41
+ *
42
+ * @param teams - Every team
43
+ * @param projects - Every project
44
+ * @param agentSession - The agent
45
+ * @param crewlyHome - CREWLY_HOME
46
+ * @returns Vaults with labels (team / project names)
47
+ */
48
+ export function vaultsOfAgent(teams, projects, agentSession, crewlyHome) {
49
+ const out = [];
50
+ const seen = new Set();
51
+ const add = (vaultPath, label) => {
52
+ const key = path.resolve(vaultPath);
53
+ if (seen.has(key))
54
+ return;
55
+ seen.add(key);
56
+ out.push({ vaultPath: key, label });
57
+ };
58
+ const mine = teamsOfAgent(teams, agentSession);
59
+ for (const { team } of mine)
60
+ add(path.join(crewlyHome, TEAMS_DIR, team.id, WIKI_DIR), team.name);
61
+ for (const { team } of mine) {
62
+ for (const id of team.projectIds ?? []) {
63
+ const p = projects.find((x) => x.id === id);
64
+ if (p?.path && path.isAbsolute(p.path))
65
+ add(path.join(p.path, PROJECT_VAULT), p.name);
66
+ }
67
+ }
68
+ return out;
69
+ }
70
+ /**
71
+ * A wiki hit as a meeting page: a readable title, where it is, its matching
72
+ * lines, and the page file.
73
+ *
74
+ * @param hit - BM25 hit
75
+ * @returns Page hit
76
+ */
77
+ export function wikiHitToPage(hit) {
78
+ const base = path.basename(hit.relativePath).replace(/\.md$/i, '');
79
+ const title = base.replace(/[-_]+/g, ' ').trim() || hit.relativePath;
80
+ return {
81
+ title,
82
+ where: hit.vaultLabel ? `${hit.vaultLabel}/${hit.relativePath}` : hit.relativePath,
83
+ text: hit.snippets.map((s) => s.text).join(' … '),
84
+ ...(hit.vaultPath ? { absPath: path.join(hit.vaultPath, hit.relativePath) } : {}),
85
+ };
86
+ }
87
+ /**
88
+ * Remove a page's YAML frontmatter.
89
+ *
90
+ * @param text - Page text
91
+ * @returns The body
92
+ */
93
+ export function stripFrontmatter(text) {
94
+ return text.replace(/^---\r?\n[\s\S]*?\r?\n---\r?\n?/, '').trim();
95
+ }
96
+ /**
97
+ * A wiki page's body, clipped, or null when it cannot be read.
98
+ *
99
+ * @param absPath - Page file
100
+ * @returns The body
101
+ */
102
+ export async function readWikiPage(absPath) {
103
+ try {
104
+ const raw = await fs.readFile(absPath, 'utf8');
105
+ return stripFrontmatter(raw).slice(0, MEETING_CONSTANTS.WIKI_PAGE_MAX_CHARS * 2);
106
+ }
107
+ catch {
108
+ return null;
109
+ }
110
+ }
111
+ /**
112
+ * The agent's newest handover text, or null.
113
+ *
114
+ * @param handoverDir - Handover directory
115
+ * @param agentSession - The agent
116
+ * @returns Text (title line removed), clipped
117
+ */
118
+ export async function readLatestHandover(handoverDir, agentSession) {
119
+ const file = latestHandoverFile(handoverDir, agentSession);
120
+ if (!file)
121
+ return null;
122
+ try {
123
+ const raw = await fs.readFile(file.path, 'utf8');
124
+ return raw.replace(/^#[^\n]*\n/, '').trim().slice(0, MEETING_CONSTANTS.HANDOVER_MAX_CHARS * 2) || null;
125
+ }
126
+ catch {
127
+ return null;
128
+ }
129
+ }
130
+ /**
131
+ * A decision card in the shape the pack uses.
132
+ *
133
+ * @param d - Owner decision
134
+ * @returns Pack source
135
+ */
136
+ export function decisionSource(d) {
137
+ return {
138
+ id: d.id,
139
+ question: d.question,
140
+ status: d.status,
141
+ asker: d.asker,
142
+ requestedBy: d.requestedBy,
143
+ options: d.options.map((o) => ({ key: o.key, label: o.label })),
144
+ ...(d.card ? { card: { slackChannelId: d.card.slackChannelId, messageTs: d.card.messageTs, ...(d.card.threadTs ? { threadTs: d.card.threadTs } : {}) } } : {}),
145
+ ...(d.place ? { place: d.place } : {}),
146
+ ...(d.chosenKey ? { chosenKey: d.chosenKey } : {}),
147
+ ...(d.answerText ? { answerText: d.answerText } : {}),
148
+ ...(d.ownerWords ? { ownerWords: d.ownerWords } : {}),
149
+ createdAt: d.createdAt,
150
+ updatedAt: d.updatedAt,
151
+ };
152
+ }
153
+ //# sourceMappingURL=drive-meeting.wiring.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drive-meeting.wiring.js","sourceRoot":"","sources":["../../../../../../backend/src/services/drive/drive-meeting.wiring.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
1
  {
2
- "commit": "d4cb6994ec29704875477f0243c62c814eb29cad",
3
- "builtAt": "2026-10-21T14:13:09.939Z"
2
+ "commit": "74a294b062e7ff433d27b64eebba988e4d93c7b7",
3
+ "builtAt": "2026-10-21T15:05:11.556Z"
4
4
  }