crewly 1.20.459 → 1.20.461

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 (52) hide show
  1. package/config/skills/agent/core/reply/SKILL.md +1 -0
  2. package/config/skills/agent/core/reply/execute.sh +7 -1
  3. package/config/skills/agent/core/reply/execute.test.sh +3 -0
  4. package/dist/backend/backend/src/controllers/chat/agent-reply.controller.d.ts.map +1 -1
  5. package/dist/backend/backend/src/controllers/chat/agent-reply.controller.js +5 -0
  6. package/dist/backend/backend/src/controllers/chat/agent-reply.controller.js.map +1 -1
  7. package/dist/backend/backend/src/controllers/chat/chat.controller.d.ts.map +1 -1
  8. package/dist/backend/backend/src/controllers/chat/chat.controller.js +1 -0
  9. package/dist/backend/backend/src/controllers/chat/chat.controller.js.map +1 -1
  10. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.d.ts.map +1 -1
  11. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.js +1 -0
  12. package/dist/backend/backend/src/controllers/chat-v2/chat-v2.controller.js.map +1 -1
  13. package/dist/backend/backend/src/index.d.ts.map +1 -1
  14. package/dist/backend/backend/src/index.js +29 -0
  15. package/dist/backend/backend/src/index.js.map +1 -1
  16. package/dist/backend/backend/src/services/decisions/decision-card.d.ts +15 -1
  17. package/dist/backend/backend/src/services/decisions/decision-card.d.ts.map +1 -1
  18. package/dist/backend/backend/src/services/decisions/decision-card.js +20 -4
  19. package/dist/backend/backend/src/services/decisions/decision-card.js.map +1 -1
  20. package/dist/backend/backend/src/services/decisions/decision.service.d.ts +2 -0
  21. package/dist/backend/backend/src/services/decisions/decision.service.d.ts.map +1 -1
  22. package/dist/backend/backend/src/services/decisions/decision.service.js +5 -4
  23. package/dist/backend/backend/src/services/decisions/decision.service.js.map +1 -1
  24. package/dist/backend/backend/src/services/orc/private-share-decisions.d.ts +139 -0
  25. package/dist/backend/backend/src/services/orc/private-share-decisions.d.ts.map +1 -0
  26. package/dist/backend/backend/src/services/orc/private-share-decisions.js +200 -0
  27. package/dist/backend/backend/src/services/orc/private-share-decisions.js.map +1 -0
  28. package/dist/backend/backend/src/services/orc/reply-audience.d.ts +26 -0
  29. package/dist/backend/backend/src/services/orc/reply-audience.d.ts.map +1 -1
  30. package/dist/backend/backend/src/services/orc/reply-audience.js +61 -9
  31. package/dist/backend/backend/src/services/orc/reply-audience.js.map +1 -1
  32. package/dist/backend/backend/src/services/orc/reply-destination.wiring.d.ts +26 -0
  33. package/dist/backend/backend/src/services/orc/reply-destination.wiring.d.ts.map +1 -1
  34. package/dist/backend/backend/src/services/orc/reply-destination.wiring.js +66 -9
  35. package/dist/backend/backend/src/services/orc/reply-destination.wiring.js.map +1 -1
  36. package/dist/backend/backend/src/services/v3/owner-receipt/owner-pulls-weekly.d.ts.map +1 -1
  37. package/dist/backend/backend/src/services/v3/owner-receipt/owner-pulls-weekly.js +1 -0
  38. package/dist/backend/backend/src/services/v3/owner-receipt/owner-pulls-weekly.js.map +1 -1
  39. package/dist/backend/backend/src/types/decision.types.d.ts +26 -1
  40. package/dist/backend/backend/src/types/decision.types.d.ts.map +1 -1
  41. package/dist/backend/build-info.json +2 -2
  42. package/dist/cli/backend/src/services/decisions/decision-card.d.ts +15 -1
  43. package/dist/cli/backend/src/services/decisions/decision-card.d.ts.map +1 -1
  44. package/dist/cli/backend/src/services/decisions/decision-card.js +20 -4
  45. package/dist/cli/backend/src/services/decisions/decision-card.js.map +1 -1
  46. package/dist/cli/backend/src/services/decisions/decision.service.d.ts +2 -0
  47. package/dist/cli/backend/src/services/decisions/decision.service.d.ts.map +1 -1
  48. package/dist/cli/backend/src/services/decisions/decision.service.js +5 -4
  49. package/dist/cli/backend/src/services/decisions/decision.service.js.map +1 -1
  50. package/dist/cli/backend/src/types/decision.types.d.ts +26 -1
  51. package/dist/cli/backend/src/types/decision.types.d.ts.map +1 -1
  52. package/package.json +1 -1
@@ -0,0 +1,200 @@
1
+ /**
2
+ * Private-share decisions (crewly#969, specs/per-person-access.md).
3
+ *
4
+ * When the audience check moves an agent's reply from a shared place to the
5
+ * owner's DM (it draws on someone's private data), the owner gets a card
6
+ * under it: *Share in #room?* — Share / Keep private. A tap on Share posts
7
+ * the reply where it was going, as written, and logs the share; anything
8
+ * else leaves it in the DM. The default, applied unanswered after a day, is
9
+ * Keep private.
10
+ *
11
+ * The post happens in exactly one place, {@link PrivateShareDecisions.onSettled},
12
+ * which the decision service calls when the card settles. Nothing an agent
13
+ * can call reaches it, so an agent cannot share its own held reply (the
14
+ * owner's word in the DM plus `reply --share` remains the other way).
15
+ *
16
+ * @module services/orc/private-share-decisions
17
+ */
18
+ import { LoggerService } from '../core/logger.service.js';
19
+ import { recordActivity } from '../activity/activity-log.service.js';
20
+ import { PRIVATE_REPLY_ACTIONS } from './reply-audience.js';
21
+ import { stripTraceMarkers } from '../trace/trace-markers.js';
22
+ /** Option keys on the card. */
23
+ export const PRIVATE_SHARE_KEYS = { SHARE: 'share', KEEP: 'keep' };
24
+ /** How long the card waits before the (safe) default, Keep private, applies. */
25
+ export const PRIVATE_SHARE_DEADLINE_MS = 24 * 60 * 60 * 1000;
26
+ /** Reply characters quoted on the card. */
27
+ const PREVIEW_CHARS = 400;
28
+ /**
29
+ * Who acted on the card for the activity log: the owner when they answered
30
+ * and how; a deadline outcome is the system.
31
+ *
32
+ * @param decision - Settled decision
33
+ * @returns Actor
34
+ */
35
+ function decisionActor(decision) {
36
+ if (decision.answeredVia === 'deadline' || decision.status === 'expired' || decision.status === 'defaulted')
37
+ return { type: 'system', via: 'deadline' };
38
+ return { type: 'owner', ...(decision.answeredBy ? { id: decision.answeredBy } : {}), ...(decision.answeredVia ? { via: decision.answeredVia } : {}) };
39
+ }
40
+ /**
41
+ * Names for a list of person ids ("Alice and Bob").
42
+ *
43
+ * @param people - Person ids
44
+ * @param name - Lookup
45
+ * @returns Names joined for a sentence
46
+ */
47
+ function namesOf(people, name) {
48
+ const names = people.map((p) => name?.(p) || p);
49
+ if (names.length <= 1)
50
+ return names.join('');
51
+ return `${names.slice(0, -1).join(', ')} and ${names[names.length - 1]}`;
52
+ }
53
+ /**
54
+ * Raises the share card for a held reply and applies the owner's answer.
55
+ */
56
+ export class PrivateShareDecisions {
57
+ deps;
58
+ logger;
59
+ constructor(deps) {
60
+ this.deps = deps;
61
+ this.logger = LoggerService.getInstance().createComponentLogger('PrivateShareDecisions');
62
+ }
63
+ /**
64
+ * Whether a card would go up for a held reply right now (the DM copy's
65
+ * note can then point at it).
66
+ *
67
+ * @returns True when the decision service is up and Slack is connected
68
+ */
69
+ offersCard() {
70
+ try {
71
+ return !!this.deps.decisions() && this.deps.canAsk();
72
+ }
73
+ catch {
74
+ return false;
75
+ }
76
+ }
77
+ /**
78
+ * A reply was moved to the owner DM: ask the owner, in that DM, whether to
79
+ * post it where it was going. One open card per agent + place + text.
80
+ *
81
+ * @param held - The held reply
82
+ * @returns The card's decision, or null when none was raised
83
+ */
84
+ async onHeld(held) {
85
+ const decisions = this.deps.decisions();
86
+ if (!decisions || !this.deps.canAsk())
87
+ return null;
88
+ const open = await decisions.list('open').catch(() => []);
89
+ const same = open.find((d) => d.kind === 'private_share' && d.privateShare?.agentSession === held.session && d.privateShare.heldFrom === held.heldFrom && d.privateShare.content === held.content);
90
+ if (same) {
91
+ this.logger.info('Held reply asked again while its card is open — reusing it', { decisionId: same.id, session: held.session });
92
+ return same;
93
+ }
94
+ const agentName = (await this.deps.agentNameOf?.(held.session).catch(() => undefined)) ?? held.session;
95
+ const who = namesOf(held.people, this.deps.personName);
96
+ const slackDm = this.deps.slackChannelOf(held.ownerDm);
97
+ const shown = stripTraceMarkers(held.content).trim();
98
+ const preview = shown.length > PREVIEW_CHARS ? `${shown.slice(0, PREVIEW_CHARS)}…` : shown;
99
+ const decision = await decisions.askPrebuilt({
100
+ kind: 'private_share',
101
+ asker: held.session,
102
+ question: `Share ${agentName}'s reply in ${held.heldFrom}? It draws on ${who}'s data, which only you and they may see.`,
103
+ options: [
104
+ { key: PRIVATE_SHARE_KEYS.SHARE, label: 'Share', detail: `post it in ${held.heldFrom} as written, once` },
105
+ { key: PRIVATE_SHARE_KEYS.KEEP, label: 'Keep private', detail: 'it stays here in your DM' },
106
+ ],
107
+ defaultKey: PRIVATE_SHARE_KEYS.KEEP,
108
+ yesKey: PRIVATE_SHARE_KEYS.SHARE,
109
+ deadline: new Date((this.deps.now?.() ?? Date.now()) + PRIVATE_SHARE_DEADLINE_MS),
110
+ title: 'Private data',
111
+ body: [`> ${preview.replace(/\n/g, '\n> ')}`],
112
+ ...(slackDm ? { place: { slackChannelId: slackDm } } : {}),
113
+ privateShare: {
114
+ agentSession: held.session,
115
+ agentName,
116
+ content: held.content,
117
+ destination: held.destination,
118
+ heldFrom: held.heldFrom,
119
+ people: held.people,
120
+ ownerDm: held.ownerDm,
121
+ },
122
+ });
123
+ this.logger.info('Asked the owner whether to share a held reply', { decisionId: decision.id, session: held.session, heldFrom: held.heldFrom });
124
+ return decision;
125
+ }
126
+ /**
127
+ * A `private_share` card settled. The only place a held reply is posted
128
+ * from a card.
129
+ *
130
+ * @param decision - The settled decision
131
+ * @returns Note for the agent, or null (a quiet default wakes nobody)
132
+ */
133
+ async onSettled(decision) {
134
+ const subject = decision.privateShare;
135
+ if (!subject)
136
+ return null;
137
+ const shareChosen = decision.status === 'resolved' && decision.chosenKey === PRIVATE_SHARE_KEYS.SHARE;
138
+ const record = this.deps.record ?? recordActivity;
139
+ if (!shareChosen) {
140
+ this.logger.info('Held reply kept private', { decisionId: decision.id, status: decision.status });
141
+ if (decision.status !== 'resolved')
142
+ return null;
143
+ record({
144
+ actor: decisionActor(decision),
145
+ action: PRIVATE_REPLY_ACTIONS.KEPT,
146
+ target: { type: 'conversation', id: subject.ownerDm },
147
+ after: { people: subject.people, heldFrom: subject.heldFrom, decisionId: decision.id },
148
+ note: `the owner kept ${subject.agentSession}'s reply held from ${subject.heldFrom} private`,
149
+ });
150
+ return `[PRIVATE] The owner kept your reply held from ${subject.heldFrom} in their DM. Do not post it there another way.`;
151
+ }
152
+ const held = {
153
+ session: subject.agentSession,
154
+ content: subject.content,
155
+ destination: subject.destination,
156
+ heldFrom: subject.heldFrom,
157
+ people: subject.people,
158
+ ownerDm: subject.ownerDm,
159
+ };
160
+ let posted;
161
+ try {
162
+ posted = await this.deps.post(held);
163
+ }
164
+ catch (err) {
165
+ posted = { ok: false, error: err instanceof Error ? err.message : String(err) };
166
+ }
167
+ if (!posted.ok) {
168
+ this.logger.warn('Owner tapped Share but the held reply could not be posted', { decisionId: decision.id, error: posted.error });
169
+ return `[PRIVATE] The owner tapped Share on your reply held from ${subject.heldFrom}, but it could not be posted there: ${posted.error}. Tell the owner in your DM.`;
170
+ }
171
+ record({
172
+ actor: decisionActor(decision),
173
+ action: PRIVATE_REPLY_ACTIONS.SHARED,
174
+ target: held.destination.kind === 'conversation' ? { type: 'conversation', id: held.destination.conversationId } : { type: 'reply', id: subject.agentSession },
175
+ after: { people: subject.people, sharedTo: posted.place, decisionId: decision.id },
176
+ note: `the owner shared ${subject.agentSession}'s reply drawing on ${namesOf(subject.people, this.deps.personName)}'s data in ${posted.place} from the card`,
177
+ });
178
+ this.logger.info('Held reply shared from the card', { decisionId: decision.id, session: subject.agentSession, place: posted.place });
179
+ return `[PRIVATE] The owner shared your reply held from ${subject.heldFrom}; it is posted there now. Nothing more to send.`;
180
+ }
181
+ }
182
+ let instance = null;
183
+ /**
184
+ * The private-share handler the composition root registered, or null.
185
+ *
186
+ * @returns Handler or null
187
+ */
188
+ export function getPrivateShareDecisions() {
189
+ return instance;
190
+ }
191
+ /**
192
+ * Register (or clear, with null) the private-share handler the reply
193
+ * delivery raises cards through.
194
+ *
195
+ * @param handler - Handler or null
196
+ */
197
+ export function setPrivateShareDecisions(handler) {
198
+ instance = handler;
199
+ }
200
+ //# sourceMappingURL=private-share-decisions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"private-share-decisions.js","sourceRoot":"","sources":["../../../../../../backend/src/services/orc/private-share-decisions.ts"],"names":[],"mappings":"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"}
@@ -22,6 +22,10 @@ export declare const PRIVATE_REPLY_ACTIONS: {
22
22
  readonly REDIRECTED: "connector.private_output.redirected";
23
23
  /** The reply was held: no owner DM to move it to */
24
24
  readonly HELD: "connector.private_output.held";
25
+ /** The owner said to share it: posted to the shared place with `--share` */
26
+ readonly SHARED: "connector.private_output.shared";
27
+ /** The owner kept a held reply in their DM (the card's Keep private) */
28
+ readonly KEPT: "connector.private_output.kept";
25
29
  };
26
30
  /** What the check needs to know. */
27
31
  export interface ReplyAudienceDeps {
@@ -39,6 +43,8 @@ export interface ReplyAudienceDeps {
39
43
  conversationPlace?(conversationId: string): string | null;
40
44
  /** Activity-log writer (default: the real one) */
41
45
  record?(input: ActivityEntryInput): void;
46
+ /** Whether a Share / Keep private card follows the DM copy (the note then points at it) */
47
+ offersCard?(): boolean;
42
48
  }
43
49
  /** The check's verdict. */
44
50
  export type ReplyAudienceVerdict =
@@ -74,6 +80,26 @@ export type ReplyAudienceVerdict =
74
80
  export declare function isSharedPlace(dest: Exclude<ReplyDestination, {
75
81
  kind: 'unresolved';
76
82
  }>, deps: ReplyAudienceDeps): boolean;
83
+ /**
84
+ * The people (other than the owner) whose grants the session read recently.
85
+ *
86
+ * @param session - Agent session
87
+ * @param deps - Lookups
88
+ * @returns Person ids; empty when none or when the tracker fails
89
+ */
90
+ export declare function privatePeopleOf(session: string, deps: Pick<ReplyAudienceDeps, 'recentPeople'>): string[];
91
+ /**
92
+ * Note that the owner had a private-sourced reply posted to a shared place
93
+ * (`reply --share` after the owner said so in the agent's DM).
94
+ *
95
+ * @param session - Agent session
96
+ * @param dest - Where it goes
97
+ * @param deps - Lookups
98
+ * @returns The people the reply draws on (empty: nothing private, nothing logged)
99
+ */
100
+ export declare function recordPrivateShare(session: string, dest: Exclude<ReplyDestination, {
101
+ kind: 'unresolved';
102
+ }>, deps: ReplyAudienceDeps): string[];
77
103
  /**
78
104
  * Check whether a reply may go where the resolver sent it.
79
105
  *
@@ -1 +1 @@
1
- {"version":3,"file":"reply-audience.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/orc/reply-audience.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,EAAkB,KAAK,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAE9F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAExE,iDAAiD;AACjD,eAAO,MAAM,qBAAqB;IAChC,0CAA0C;;IAE1C,oDAAoD;;CAE5C,CAAC;AAEX,oCAAoC;AACpC,MAAM,WAAW,iBAAiB;IAChC,kFAAkF;IAClF,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACxC,oFAAoF;IACpF,gBAAgB,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,GAAG,QAAQ,GAAG,SAAS,CAAC;IACtE,2FAA2F;IAC3F,cAAc,CAAC,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IACvD,iDAAiD;IACjD,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACjD,8BAA8B;IAC9B,UAAU,CAAC,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAC5C,6DAA6D;IAC7D,iBAAiB,CAAC,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAC1D,kDAAkD;IAClD,MAAM,CAAC,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI,CAAC;CAC1C;AAED,2BAA2B;AAC3B,MAAM,MAAM,oBAAoB;AAC9B,4DAA4D;AAC1D;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE;AAClB,+EAA+E;GAC7E;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,WAAW,EAAE,OAAO,CAAC,gBAAgB,EAAE;QAAE,IAAI,EAAE,cAAc,CAAA;KAAE,CAAC,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE;AAC1I,qFAAqF;GACnF;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtF;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,gBAAgB,EAAE;IAAE,IAAI,EAAE,YAAY,CAAA;CAAE,CAAC,EAAE,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAYvH;AA+BD;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,OAAO,CAAC,gBAAgB,EAAE;IAAE,IAAI,EAAE,YAAY,CAAA;CAAE,CAAC,EACvD,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,oBAAoB,CAAC,CAiD/B"}
1
+ {"version":3,"file":"reply-audience.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/orc/reply-audience.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,EAAkB,KAAK,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAE9F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAExE,iDAAiD;AACjD,eAAO,MAAM,qBAAqB;IAChC,0CAA0C;;IAE1C,oDAAoD;;IAEpD,4EAA4E;;IAE5E,wEAAwE;;CAEhE,CAAC;AAEX,oCAAoC;AACpC,MAAM,WAAW,iBAAiB;IAChC,kFAAkF;IAClF,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACxC,oFAAoF;IACpF,gBAAgB,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,GAAG,QAAQ,GAAG,SAAS,CAAC;IACtE,2FAA2F;IAC3F,cAAc,CAAC,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IACvD,iDAAiD;IACjD,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACjD,8BAA8B;IAC9B,UAAU,CAAC,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAC5C,6DAA6D;IAC7D,iBAAiB,CAAC,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAC1D,kDAAkD;IAClD,MAAM,CAAC,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACzC,2FAA2F;IAC3F,UAAU,CAAC,IAAI,OAAO,CAAC;CACxB;AAED,2BAA2B;AAC3B,MAAM,MAAM,oBAAoB;AAC9B,4DAA4D;AAC1D;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE;AAClB,+EAA+E;GAC7E;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,WAAW,EAAE,OAAO,CAAC,gBAAgB,EAAE;QAAE,IAAI,EAAE,cAAc,CAAA;KAAE,CAAC,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE;AAC1I,qFAAqF;GACnF;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtF;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC,gBAAgB,EAAE;IAAE,IAAI,EAAE,YAAY,CAAA;CAAE,CAAC,EAAE,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAYvH;AA+BD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,iBAAiB,EAAE,cAAc,CAAC,GAAG,MAAM,EAAE,CAMxG;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,gBAAgB,EAAE;IAAE,IAAI,EAAE,YAAY,CAAA;CAAE,CAAC,EAAE,IAAI,EAAE,iBAAiB,GAAG,MAAM,EAAE,CAY9I;AAgBD;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,OAAO,CAAC,gBAAgB,EAAE;IAAE,IAAI,EAAE,YAAY,CAAA;CAAE,CAAC,EACvD,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,oBAAoB,CAAC,CA8C/B"}
@@ -23,6 +23,10 @@ export const PRIVATE_REPLY_ACTIONS = {
23
23
  REDIRECTED: 'connector.private_output.redirected',
24
24
  /** The reply was held: no owner DM to move it to */
25
25
  HELD: 'connector.private_output.held',
26
+ /** The owner said to share it: posted to the shared place with `--share` */
27
+ SHARED: 'connector.private_output.shared',
28
+ /** The owner kept a held reply in their DM (the card's Keep private) */
29
+ KEPT: 'connector.private_output.kept',
26
30
  };
27
31
  /**
28
32
  * Whether a resolved destination is a place other people can read.
@@ -81,21 +85,67 @@ function namesOf(people, deps) {
81
85
  return `${names.slice(0, -1).join(', ')} and ${names[names.length - 1]}`;
82
86
  }
83
87
  /**
84
- * Check whether a reply may go where the resolver sent it.
88
+ * The people (other than the owner) whose grants the session read recently.
85
89
  *
86
90
  * @param session - Agent session
87
- * @param dest - The resolved destination
88
91
  * @param deps - Lookups
89
- * @returns The verdict (never throws)
92
+ * @returns Person ids; empty when none or when the tracker fails
90
93
  */
91
- export async function checkReplyAudience(session, dest, deps) {
92
- let people;
94
+ export function privatePeopleOf(session, deps) {
93
95
  try {
94
- people = deps.recentPeople(session).filter((p) => p && p !== PEOPLE_CONSTANTS.OWNER_ID);
96
+ return deps.recentPeople(session).filter((p) => p && p !== PEOPLE_CONSTANTS.OWNER_ID);
95
97
  }
96
98
  catch {
97
- return { kind: 'open' };
99
+ return [];
98
100
  }
101
+ }
102
+ /**
103
+ * Note that the owner had a private-sourced reply posted to a shared place
104
+ * (`reply --share` after the owner said so in the agent's DM).
105
+ *
106
+ * @param session - Agent session
107
+ * @param dest - Where it goes
108
+ * @param deps - Lookups
109
+ * @returns The people the reply draws on (empty: nothing private, nothing logged)
110
+ */
111
+ export function recordPrivateShare(session, dest, deps) {
112
+ const people = privatePeopleOf(session, deps);
113
+ if (people.length === 0 || !isSharedPlace(dest, deps))
114
+ return [];
115
+ const place = placeOf(dest, deps);
116
+ (deps.record ?? recordActivity)({
117
+ actor: { type: 'agent', id: session },
118
+ action: PRIVATE_REPLY_ACTIONS.SHARED,
119
+ target: dest.kind === 'conversation' ? { type: 'conversation', id: dest.conversationId } : { type: 'reply', id: session },
120
+ after: { people, sharedTo: place },
121
+ note: `${session} posted a reply drawing on ${namesOf(people, deps)}'s data to ${place} after the owner said to share it`,
122
+ });
123
+ return people;
124
+ }
125
+ /**
126
+ * Whether a share card follows the DM copy (never throws).
127
+ *
128
+ * @param deps - Lookups
129
+ * @returns True when the card is offered
130
+ */
131
+ function offersCard(deps) {
132
+ try {
133
+ return deps.offersCard?.() === true;
134
+ }
135
+ catch {
136
+ return false;
137
+ }
138
+ }
139
+ /**
140
+ * Check whether a reply may go where the resolver sent it.
141
+ *
142
+ * @param session - Agent session
143
+ * @param dest - The resolved destination
144
+ * @param deps - Lookups
145
+ * @returns The verdict (never throws)
146
+ */
147
+ export async function checkReplyAudience(session, dest, deps) {
148
+ const people = privatePeopleOf(session, deps);
99
149
  if (people.length === 0)
100
150
  return { kind: 'open' };
101
151
  if (!isSharedPlace(dest, deps))
@@ -115,7 +165,7 @@ export async function checkReplyAudience(session, dest, deps) {
115
165
  return {
116
166
  kind: 'held',
117
167
  reason: `it draws on ${who}'s data (read through their connection in the last minutes) and ${heldFrom} has other members`,
118
- fix: `send it to the owner's DM (ask your team lead to open one), or ask the owner to share ${who}'s connection with the room first`,
168
+ fix: `send it to the owner's DM (ask your team lead to open one); once the owner says to share it there, run the same reply with --share`,
119
169
  people,
120
170
  heldFrom,
121
171
  };
@@ -135,7 +185,9 @@ export async function checkReplyAudience(session, dest, deps) {
135
185
  source: 'owner-dm',
136
186
  reason: `held from ${heldFrom}: it draws on ${who}'s data`,
137
187
  },
138
- note: `_Held from ${heldFrom}: this draws on ${who}'s data, which only you and they may see. Say "share it" and I will post it there._`,
188
+ note: offersCard(deps)
189
+ ? `_Held from ${heldFrom}: this draws on ${who}'s data, which only you and they may see. Tap *Share* on the card below, or say "share it" here, and I will post it there._`
190
+ : `_Held from ${heldFrom}: this draws on ${who}'s data, which only you and they may see. Say "share it" here and I will post it there._`,
139
191
  people,
140
192
  heldFrom,
141
193
  };
@@ -1 +1 @@
1
- {"version":3,"file":"reply-audience.js","sourceRoot":"","sources":["../../../../../../backend/src/services/orc/reply-audience.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,cAAc,EAA2B,MAAM,qCAAqC,CAAC;AAC9F,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAGzD,iDAAiD;AACjD,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,0CAA0C;IAC1C,UAAU,EAAE,qCAAqC;IACjD,oDAAoD;IACpD,IAAI,EAAE,+BAA+B;CAC7B,CAAC;AA6BX;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,IAAuD,EAAE,IAAuB;IAC5G,IAAI,IAAI,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;QACjC,IAAI,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,IAAI;YAAE,OAAO,KAAK,CAAC;QACtE,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,IAAI,CAAC;QACjE,IAAI,KAAK,IAAI,SAAS,CAAC,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QAC5C,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC;IAC3B,sEAAsE;IACtE,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO;QAAE,OAAO,KAAK,CAAC;IACrC,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO,IAAI,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAC;IAC5D,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;GAMG;AACH,SAAS,OAAO,CAAC,IAAuD,EAAE,IAAuB;IAC/F,IAAI,IAAI,CAAC,IAAI,KAAK,cAAc;QAAE,OAAO,IAAI,CAAC,iBAAiB,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,gBAAgB,IAAI,CAAC,cAAc,EAAE,CAAC;IAChI,MAAM,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC;IAC3B,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO;QAAE,OAAO,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,MAAM,EAAE,CAAC;IACjG,IAAI,CAAC,CAAC,IAAI,KAAK,eAAe;QAAE,OAAO,OAAO,CAAC,CAAC,QAAQ,gBAAgB,CAAC;IACzE,IAAI,CAAC,CAAC,IAAI,KAAK,eAAe;QAAE,OAAO,kBAAkB,CAAC;IAC1D,OAAO,YAAY,CAAC;AACtB,CAAC;AAED;;;;;;GAMG;AACH,SAAS,OAAO,CAAC,MAAgB,EAAE,IAAuB;IACxD,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAC3D,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC7C,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC;AAC3E,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,OAAe,EACf,IAAuD,EACvD,IAAuB;IAEvB,IAAI,MAAgB,CAAC;IACrB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAC1F,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAC1B,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IACjD,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAExD,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACrC,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAClC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,cAAc,CAAC;IAC7C,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IAC9D,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,CAAC;YACL,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE;YACrC,MAAM,EAAE,qBAAqB,CAAC,IAAI;YAClC,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE;YACtC,KAAK,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE;YAC3B,IAAI,EAAE,GAAG,OAAO,eAAe,QAAQ,0BAA0B,GAAG,gDAAgD;SACrH,CAAC,CAAC;QACH,OAAO;YACL,IAAI,EAAE,MAAM;YACZ,MAAM,EAAE,eAAe,GAAG,mEAAmE,QAAQ,oBAAoB;YACzH,GAAG,EAAE,yFAAyF,GAAG,mCAAmC;YACpI,MAAM;YACN,QAAQ;SACT,CAAC;IACJ,CAAC;IACD,MAAM,CAAC;QACL,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE;QACrC,MAAM,EAAE,qBAAqB,CAAC,UAAU;QACxC,MAAM,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,EAAE,OAAO,EAAE;QAC7C,KAAK,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE;QAC3B,IAAI,EAAE,GAAG,OAAO,eAAe,QAAQ,8CAA8C,GAAG,SAAS;KAClG,CAAC,CAAC;IACH,OAAO;QACL,IAAI,EAAE,UAAU;QAChB,WAAW,EAAE;YACX,IAAI,EAAE,cAAc;YACpB,cAAc,EAAE,OAAO;YACvB,MAAM,EAAE,UAAU;YAClB,MAAM,EAAE,aAAa,QAAQ,iBAAiB,GAAG,SAAS;SAC3D;QACD,IAAI,EAAE,cAAc,QAAQ,mBAAmB,GAAG,qFAAqF;QACvI,MAAM;QACN,QAAQ;KACT,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"reply-audience.js","sourceRoot":"","sources":["../../../../../../backend/src/services/orc/reply-audience.ts"],"names":[],"mappings":"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"}
@@ -12,6 +12,7 @@ import { type WorkDestinationDeps } from './work-item-destination.wiring.js';
12
12
  import { type MessageRoute, type RouteCheckOutcome } from './message-route.js';
13
13
  import { type TurnTrigger } from '../trace/turn-trigger.js';
14
14
  import { type ReplyAudienceDeps } from './reply-audience.js';
15
+ import { type HeldReply, type HeldReplyPost } from './private-share-decisions.js';
15
16
  /** Forget recent deliveries (tests). */
16
17
  export declare function resetReplyDeliveryGuardForTesting(): void;
17
18
  /** Delivery into a chat-v2 conversation (chat.controller `deliverAgentReplyToConversation`). */
@@ -93,6 +94,12 @@ export interface ReplyDeliveryDeps {
93
94
  * place. Omitted: no check.
94
95
  */
95
96
  audience?: ReplyAudienceDeps;
97
+ /**
98
+ * A reply was moved to the owner DM: raise the Share / Keep private card
99
+ * under it (crewly#969). Called after the DM copy landed; a failure is
100
+ * logged, the DM copy stands.
101
+ */
102
+ privateShareCard?: (held: HeldReply) => Promise<unknown>;
96
103
  }
97
104
  /** What a delivery did. */
98
105
  export type ReplyDelivery = {
@@ -107,6 +114,8 @@ export type ReplyDelivery = {
107
114
  messageTs?: string;
108
115
  /** The agent an internal message went to (work with an agent origin, crewly#1357) */
109
116
  agentSession?: string;
117
+ /** The shared place the reply was held from when it went to the owner DM instead (crewly#969) */
118
+ heldFrom?: string;
110
119
  } | {
111
120
  ok: false;
112
121
  error: string;
@@ -123,6 +132,12 @@ export interface DeliverReplyInput {
123
132
  noOwnerDm?: boolean;
124
133
  /** Post even when a colleague already answered the owner here (`--adds-new`) */
125
134
  addsNew?: boolean;
135
+ /**
136
+ * The owner said in the agent's DM to share a private-sourced reply in the
137
+ * shared place it was held from (`--share`, crewly#969). Honoured only
138
+ * while the owner's message in that DM is recent.
139
+ */
140
+ share?: boolean;
126
141
  }
127
142
  /**
128
143
  * Resolve and deliver an agent's message. Never guesses: a destination that
@@ -226,6 +241,17 @@ export declare function notDelivered(why: string, fix: string): string;
226
241
  * @returns Deps
227
242
  */
228
243
  export declare function defaultReplyDeliveryDeps(): Promise<ReplyDeliveryDeps>;
244
+ /**
245
+ * Post a reply the audience check held, where it was going, as written: the
246
+ * owner tapped Share on its card (crewly#969). The audience check is not run
247
+ * again (the owner's tap is the approval); the share itself is logged by the
248
+ * card handler.
249
+ *
250
+ * @param held - The held reply
251
+ * @param deps - Delivery deps (default: the real ones)
252
+ * @returns What happened
253
+ */
254
+ export declare function postHeldReply(held: HeldReply, deps?: ReplyDeliveryDeps): Promise<HeldReplyPost>;
229
255
  /** The chat-v2 lookups {@link chatConversationPlace} and {@link ownerWroteInThreadRecently} use. */
230
256
  interface ChatChannelLookup {
231
257
  getChannelForBridge(id: string): {
@@ -1 +1 @@
1
- {"version":3,"file":"reply-destination.wiring.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/orc/reply-destination.wiring.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AASH,OAAO,EAIL,KAAK,gBAAgB,EACrB,KAAK,UAAU,EACf,KAAK,cAAc,EAEnB,KAAK,iBAAiB,EACvB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAA8B,KAAK,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AAC7G,OAAO,EAAwD,KAAK,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAEnI,OAAO,EAAuD,KAAK,YAAY,EAAkB,KAAK,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAKpJ,OAAO,EAAyB,KAAK,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAInF,OAAO,EAAsB,KAAK,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAOjF,wCAAwC;AACxC,wBAAgB,iCAAiC,IAAI,IAAI,CAExD;AAID,gGAAgG;AAChG,MAAM,MAAM,mBAAmB,GAAG,CAAC,KAAK,EAAE;IACxC,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;AAE7B,6CAA6C;AAC7C,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,qBAAqB,EAAE,mBAAmB,CAAC;IAC3C,eAAe,EAAE,MAAM,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACpD;;;;OAIG;IACH,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,cAAc,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IAChJ;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,CAAC,cAAc,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC5F;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,WAAW,GAAG,IAAI,CAAC;IACtD,6GAA6G;IAC7G,kBAAkB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,KAAK,OAAO,CAAC;IAC1E;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,KAAK,OAAO,CAAC;IACzE;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC;IACzE;;;OAGG;IACH,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,WAAW,GAAG,IAAI,CAAC;IACxD,yDAAyD;IACzD,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IAClD,oGAAoG;IACpG,iBAAiB,CAAC,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IAC9D;;;;OAIG;IACH,WAAW,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACzF;;;OAGG;IACH,kBAAkB,CAAC,EAAE,sBAAsB,CAAC;IAC5C;;;;OAIG;IACH,QAAQ,CAAC,EAAE,iBAAiB,CAAC;CAC9B;AAED,2BAA2B;AAC3B,MAAM,MAAM,aAAa,GACrB;IACE,EAAE,EAAE,IAAI,CAAC;IACT,WAAW,EAAE,OAAO,CAAC,gBAAgB,EAAE;QAAE,IAAI,EAAE,YAAY,CAAA;KAAE,CAAC,CAAC;IAC/D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qFAAqF;IACrF,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,GACD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,gBAAgB,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAEhF,qCAAqC;AACrC,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,cAAc,CAAC;IAC3B,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gFAAgF;IAChF,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,YAAY,CAAC,KAAK,EAAE,iBAAiB,EAAE,IAAI,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,aAAa,CAAC,CAwB7G;AAKD;;;;GAIG;AACH,wBAAgB,kBAAkB,IAAI,QAAQ,CAAC,MAAM,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC,CAEhF;AAED,2CAA2C;AAC3C,wBAAgB,8BAA8B,IAAI,IAAI,CAIrD;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,iBAAiB,EAAE,QAAQ,EAAE,OAAO,CAAC,aAAa,EAAE;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,CAAC,EAAE,IAAI,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CA2B5K;AA2YD;;;;;;;;;GASG;AACH,wBAAsB,sBAAsB,CAC1C,KAAK,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,EACvG,IAAI,CAAC,EAAE,IAAI,CAAC,iBAAiB,EAAE,UAAU,GAAG,aAAa,GAAG,oBAAoB,GAAG,mBAAmB,GAAG,oBAAoB,GAAG,cAAc,GAAG,mBAAmB,CAAC,GACpK,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAAC,CAUrE;AA4FD;;;;;;;;;;;GAWG;AACH,wBAAsB,0BAA0B,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAWpH;AAED;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,IAAI,CAAC,iBAAiB,EAAE,SAAS,GAAG,SAAS,CAAC,EACrD,IAAI,CAAC,EAAE,iBAAiB,GACvB,OAAO,CAAC;IAAE,cAAc,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,gBAAgB,CAAA;CAAE,GAAG,IAAI,CAAC,CA4CvI;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAE7D;AAsDD;;;;GAIG;AACH,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAoK3E;AAqCD,oGAAoG;AACpG,UAAU,iBAAiB;IACzB,mBAAmB,CAAC,EAAE,EAAE,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC/F,mBAAmB,CAAC,CAAC,EAAE,EAAE,MAAM,GAAG;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC9F,mBAAmB,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACtF,mBAAmB,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC3G;AAED;;;;;;;;;GASG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,GAAE,MAAmB,GAAG,OAAO,CAapJ;AAgBD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,iBAAiB,GAAG,IAAI,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAS3G;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAOlF"}
1
+ {"version":3,"file":"reply-destination.wiring.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/orc/reply-destination.wiring.ts"],"names":[],"mappings":"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"}
@@ -25,7 +25,8 @@ import { getTurnTriggerTracker } from '../trace/turn-trigger.js';
25
25
  import { triggeredByMetadata, triggeredByPhrase, withTriggeredByLine } from './triggered-by.js';
26
26
  import { stripOwnerTextIds } from '../../utils/owner-text-ids.utils.js';
27
27
  import { memberNameFromSession } from '../../utils/member-session-name.utils.js';
28
- import { checkReplyAudience } from './reply-audience.js';
28
+ import { checkReplyAudience, recordPrivateShare } from './reply-audience.js';
29
+ import { getPrivateShareDecisions } from './private-share-decisions.js';
29
30
  /** How long an identical reply from one agent counts as a duplicate send. */
30
31
  const REPLY_DUPLICATE_WINDOW_MS = 120_000;
31
32
  /** Deliveries that landed recently, by agent + text hash. */
@@ -184,19 +185,40 @@ async function deliverReplyUntraced(input, deps) {
184
185
  }
185
186
  // crewly#969: what the agent read through a person's grant is that person's
186
187
  // data; a reply drawing on it does not go where other people read.
188
+ let heldFrom;
189
+ let held;
187
190
  if (d.audience) {
188
- const verdict = await checkReplyAudience(input.session, dest, { ...d.audience, ...(d.conversationPlace ? { conversationPlace: d.conversationPlace } : {}) });
189
- if (verdict.kind === 'held') {
190
- logger.warn('Agent reply held: it draws on private data and the place is shared', { session: input.session, heldFrom: verdict.heldFrom, people: verdict.people });
191
- return { ok: false, destination: dest, error: notDelivered(verdict.reason, verdict.fix), held: true };
191
+ const audience = { ...d.audience, ...(d.conversationPlace ? { conversationPlace: d.conversationPlace } : {}) };
192
+ const shared = input.share === true && (await ownerSaidShare(input.session, d)) ? recordPrivateShare(input.session, dest, audience) : [];
193
+ if (shared.length > 0) {
194
+ logger.info('Agent posts a private-sourced reply to a shared place: the owner said to share it', { session: input.session, people: shared });
192
195
  }
193
- if (verdict.kind === 'redirect') {
194
- logger.info('Agent reply moved to the owner DM: it draws on private data', { session: input.session, heldFrom: verdict.heldFrom, people: verdict.people });
195
- dest = verdict.destination;
196
- input = { ...input, content: `${verdict.note}\n\n${input.content}` };
196
+ else {
197
+ const verdict = await checkReplyAudience(input.session, dest, audience);
198
+ if (input.share === true && verdict.kind !== 'open') {
199
+ logger.warn('--share ignored: the owner did not say so in the agent DM recently', { session: input.session, heldFrom: verdict.heldFrom });
200
+ }
201
+ if (verdict.kind === 'held') {
202
+ logger.warn('Agent reply held: it draws on private data and the place is shared', { session: input.session, heldFrom: verdict.heldFrom, people: verdict.people });
203
+ return { ok: false, destination: dest, error: notDelivered(verdict.reason, verdict.fix), held: true };
204
+ }
205
+ if (verdict.kind === 'redirect') {
206
+ logger.info('Agent reply moved to the owner DM: it draws on private data', { session: input.session, heldFrom: verdict.heldFrom, people: verdict.people });
207
+ held = { session: input.session, content: input.content, destination: dest, heldFrom: verdict.heldFrom, people: verdict.people, ownerDm: verdict.destination.conversationId };
208
+ dest = verdict.destination;
209
+ heldFrom = verdict.heldFrom;
210
+ input = { ...input, content: `${verdict.note}\n\n${input.content}` };
211
+ }
197
212
  }
198
213
  }
199
214
  let result = await attempt(input, dest, prompt, d);
215
+ if (result.ok && heldFrom) {
216
+ result = { ...result, heldFrom };
217
+ if (held && d.privateShareCard) {
218
+ const card = held;
219
+ void d.privateShareCard(card).catch((err) => logger.warn('Share card not raised for a held reply', { session: card.session, heldFrom: card.heldFrom, error: err instanceof Error ? err.message : String(err) }));
220
+ }
221
+ }
200
222
  if (result.ok || ('held' in result && result.held))
201
223
  return result;
202
224
  // Work handed over from the owner's DM with another agent (a lead's
@@ -932,8 +954,42 @@ export async function defaultReplyDeliveryDeps() {
932
954
  currentTrace: (session) => getTraceContext().currentTrace(session),
933
955
  conversationPlace: (id) => chatConversationPlace(chatLookup, id),
934
956
  audience: await defaultAudienceDeps(resolver, chatLookup),
957
+ privateShareCard: (held) => getPrivateShareDecisions()?.onHeld(held) ?? Promise.resolve(null),
935
958
  };
936
959
  }
960
+ /**
961
+ * Post a reply the audience check held, where it was going, as written: the
962
+ * owner tapped Share on its card (crewly#969). The audience check is not run
963
+ * again (the owner's tap is the approval); the share itself is logged by the
964
+ * card handler.
965
+ *
966
+ * @param held - The held reply
967
+ * @param deps - Delivery deps (default: the real ones)
968
+ * @returns What happened
969
+ */
970
+ export async function postHeldReply(held, deps) {
971
+ const d = deps ?? (await defaultReplyDeliveryDeps());
972
+ const place = (held.destination.kind === 'conversation' ? d.conversationPlace?.(held.destination.conversationId) : null) ?? held.heldFrom;
973
+ const result = await attempt({ session: held.session, content: held.content }, held.destination, undefined, d);
974
+ if (!result.ok)
975
+ return { ok: false, error: result.error };
976
+ logger.info('Held reply posted where it was going: the owner tapped Share', { session: held.session, place });
977
+ return { ok: true, place };
978
+ }
979
+ /**
980
+ * Whether the owner wrote to the agent in its owner DM recently — the
981
+ * approval `reply --share` stands on (crewly#969).
982
+ *
983
+ * @param session - Agent session
984
+ * @param d - Delivery deps
985
+ * @returns True when the owner DM exists and the owner asked there within the window
986
+ */
987
+ async function ownerSaidShare(session, d) {
988
+ if (!d.audience || !d.ownerAskedRecently)
989
+ return false;
990
+ const dm = await d.audience.ownerDm(session).catch(() => null);
991
+ return !!dm && d.ownerAskedRecently(session, dm) === true;
992
+ }
937
993
  /**
938
994
  * The real audience-check lookups (crewly#969): the private-source tracker,
939
995
  * chat-v2 conversation kinds and the people directory.
@@ -960,6 +1016,7 @@ async function defaultAudienceDeps(resolver, chatLookup) {
960
1016
  },
961
1017
  slackChannelOf: (id) => resolver.slackChannelOfConversation(id),
962
1018
  ownerDm: (session) => resolver.ownerDm(session),
1019
+ offersCard: () => getPrivateShareDecisions()?.offersCard() ?? false,
963
1020
  personName: (id) => {
964
1021
  try {
965
1022
  return getPeopleDirectory().get(id)?.name ?? undefined;