@neuroverseos/governance 0.10.0 → 0.12.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/dist/adapters/autoresearch.cjs +19 -1
- package/dist/adapters/autoresearch.d.cts +1 -1
- package/dist/adapters/autoresearch.d.ts +1 -1
- package/dist/adapters/autoresearch.js +2 -2
- package/dist/adapters/deep-agents.cjs +19 -1
- package/dist/adapters/deep-agents.d.cts +2 -2
- package/dist/adapters/deep-agents.d.ts +2 -2
- package/dist/adapters/deep-agents.js +2 -2
- package/dist/adapters/express.cjs +19 -1
- package/dist/adapters/express.d.cts +1 -1
- package/dist/adapters/express.d.ts +1 -1
- package/dist/adapters/express.js +2 -2
- package/dist/adapters/github.cjs +19 -1
- package/dist/adapters/github.d.cts +2 -2
- package/dist/adapters/github.d.ts +2 -2
- package/dist/adapters/github.js +2 -2
- package/dist/adapters/index.cjs +19 -1
- package/dist/adapters/index.d.cts +2 -2
- package/dist/adapters/index.d.ts +2 -2
- package/dist/adapters/index.js +8 -8
- package/dist/adapters/langchain.cjs +19 -1
- package/dist/adapters/langchain.d.cts +2 -2
- package/dist/adapters/langchain.d.ts +2 -2
- package/dist/adapters/langchain.js +2 -2
- package/dist/adapters/mentraos.cjs +19 -1
- package/dist/adapters/mentraos.d.cts +2 -2
- package/dist/adapters/mentraos.d.ts +2 -2
- package/dist/adapters/mentraos.js +2 -2
- package/dist/adapters/openai.cjs +19 -1
- package/dist/adapters/openai.d.cts +2 -2
- package/dist/adapters/openai.d.ts +2 -2
- package/dist/adapters/openai.js +2 -2
- package/dist/adapters/openclaw.cjs +19 -1
- package/dist/adapters/openclaw.d.cts +2 -2
- package/dist/adapters/openclaw.d.ts +2 -2
- package/dist/adapters/openclaw.js +2 -2
- package/dist/admin/index.cjs +19 -1
- package/dist/admin/index.js +1 -1
- package/dist/audit-JYNN3MOQ.js +98 -0
- package/dist/audit-behavior-C62FdRAC.d.cts +100 -0
- package/dist/audit-behavior-DFy7LeYv.d.ts +100 -0
- package/dist/{behavioral-SPWPGYXL.js → behavioral-4TKMHZQZ.js} +2 -2
- package/dist/{chunk-OQU65525.js → chunk-24YW7BHC.js} +1 -1
- package/dist/{chunk-BZYQHJDM.js → chunk-2KTPIE57.js} +25 -5
- package/dist/{chunk-TJ5L2UTE.js → chunk-5K3LATTM.js} +1 -1
- package/dist/{chunk-HDNDL6D5.js → chunk-5LDBYOSJ.js} +1 -1
- package/dist/{chunk-FDPPZLSQ.js → chunk-5ZWKM7MO.js} +1 -1
- package/dist/{chunk-B3IIPTY3.js → chunk-6MB6TMAG.js} +1 -1
- package/dist/{chunk-IOVXB6QN.js → chunk-GXTAHCND.js} +1 -1
- package/dist/{chunk-FKQCPRKI.js → chunk-MAOIHKFO.js} +1 -1
- package/dist/{chunk-ZAF6JH23.js → chunk-MBOW6YXN.js} +19 -1
- package/dist/{chunk-A2UZTLRV.js → chunk-MLXKSX3L.js} +1 -1
- package/dist/{chunk-7FL3U7Z5.js → chunk-MWGEXHOD.js} +1 -1
- package/dist/{chunk-6CV4XG3J.js → chunk-QFDFAWZ6.js} +1 -1
- package/dist/{chunk-2VAWP6FI.js → chunk-RAS62JXV.js} +1 -1
- package/dist/{chunk-OTZU76DH.js → chunk-XAF3CYCW.js} +1 -1
- package/dist/{chunk-T6GMRZWC.js → chunk-XTYQCTDD.js} +1 -1
- package/dist/{chunk-TIXVEPS2.js → chunk-YN7OI5ZV.js} +1 -1
- package/dist/cli/neuroverse.cjs +229 -93
- package/dist/cli/neuroverse.js +16 -12
- package/dist/cli/plan.cjs +18 -0
- package/dist/cli/radiant.cjs +42 -4
- package/dist/cli/radiant.js +3 -3
- package/dist/cli/run.cjs +18 -0
- package/dist/cli/run.js +4 -4
- package/dist/{decision-flow-IJPNMVQK.js → decision-flow-5VI5YG6A.js} +2 -2
- package/dist/{demo-6W3YXLAX.js → demo-GYX6CYHC.js} +2 -2
- package/dist/engine/guard-engine.cjs +19 -1
- package/dist/engine/guard-engine.d.cts +21 -1
- package/dist/engine/guard-engine.d.ts +21 -1
- package/dist/engine/guard-engine.js +1 -1
- package/dist/{equity-penalties-CCO3GVHS.js → equity-penalties-NOM46NEO.js} +2 -2
- package/dist/{guard-IHJEKHL2.js → guard-PQ3SYV4Y.js} +3 -3
- package/dist/{guard-contract-ddiIPlOg.d.cts → guard-contract-Oznf-Kgq.d.cts} +32 -0
- package/dist/{guard-contract-q6HJAq3Q.d.ts → guard-contract-w_i_6gh-.d.ts} +32 -0
- package/dist/{impact-WIAM66IH.js → impact-LDJLTVRU.js} +3 -3
- package/dist/index.cjs +62 -1
- package/dist/index.d.cts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +49 -8
- package/dist/{mcp-server-CKYBHXWK.js → mcp-server-W3MWSKD7.js} +2 -2
- package/dist/{playground-3TTBN7XD.js → playground-SSZRNUAF.js} +1 -1
- package/dist/radiant/index.cjs +450 -5
- package/dist/radiant/index.d.cts +151 -1
- package/dist/radiant/index.d.ts +151 -1
- package/dist/radiant/index.js +405 -2
- package/dist/{redteam-W644UMWN.js → redteam-KCULS7EW.js} +1 -1
- package/dist/{server-EI5JCIBU.js → server-EGRGGSM2.js} +2 -2
- package/dist/{session-FMAROEIE.js → session-PZLTL22G.js} +2 -2
- package/dist/{shared-PpalGKxc.d.cts → shared-BC8mOpt0.d.cts} +1 -1
- package/dist/{shared-DAzdfWtU.d.ts → shared-CP63gNNW.d.ts} +1 -1
- package/dist/{test-XDB2DH3L.js → test-LIHGWHBA.js} +1 -1
- package/dist/{trace-2YDNAXMK.js → trace-DC3D7XPD.js} +2 -2
- package/package.json +1 -1
- /package/dist/{doctor-XEMLO6UA.js → doctor-SIWQGTAO.js} +0 -0
package/dist/radiant/index.js
CHANGED
|
@@ -63,7 +63,7 @@ import {
|
|
|
63
63
|
think,
|
|
64
64
|
updateKnowledge,
|
|
65
65
|
writeRead
|
|
66
|
-
} from "../chunk-
|
|
66
|
+
} from "../chunk-2KTPIE57.js";
|
|
67
67
|
import {
|
|
68
68
|
LENSES,
|
|
69
69
|
aukiBuilderLens,
|
|
@@ -72,10 +72,409 @@ import {
|
|
|
72
72
|
sovereignConduitLens
|
|
73
73
|
} from "../chunk-TCGGED4G.js";
|
|
74
74
|
import "../chunk-I4RTIMLX.js";
|
|
75
|
-
import "../chunk-
|
|
75
|
+
import "../chunk-MBOW6YXN.js";
|
|
76
76
|
import "../chunk-QLPTHTVB.js";
|
|
77
77
|
import "../chunk-QWGCMQQD.js";
|
|
78
78
|
|
|
79
|
+
// src/radiant/adapters/google-workspace.ts
|
|
80
|
+
async function fetchGoogleWorkspaceActivity(options) {
|
|
81
|
+
const windowDays = options.windowDays ?? 14;
|
|
82
|
+
const maxEmails = options.maxEmails ?? 100;
|
|
83
|
+
const maxEvents = options.maxEvents ?? 100;
|
|
84
|
+
const leaderEmail = options.leaderEmail?.toLowerCase();
|
|
85
|
+
const since = new Date(Date.now() - windowDays * 24 * 60 * 60 * 1e3);
|
|
86
|
+
const [emailEvents, emailSignals] = await fetchGmailSent(
|
|
87
|
+
options.accessToken,
|
|
88
|
+
since,
|
|
89
|
+
maxEmails,
|
|
90
|
+
leaderEmail
|
|
91
|
+
);
|
|
92
|
+
const [calendarEvents, calendarSignals] = await fetchCalendarEvents(
|
|
93
|
+
options.accessToken,
|
|
94
|
+
since,
|
|
95
|
+
maxEvents,
|
|
96
|
+
leaderEmail
|
|
97
|
+
);
|
|
98
|
+
const events = [...emailEvents, ...calendarEvents].sort(
|
|
99
|
+
(a, b) => Date.parse(a.timestamp) - Date.parse(b.timestamp)
|
|
100
|
+
);
|
|
101
|
+
return {
|
|
102
|
+
events,
|
|
103
|
+
signals: {
|
|
104
|
+
...emailSignals,
|
|
105
|
+
...calendarSignals
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
function formatGoogleWorkspaceSignalsForPrompt(signals) {
|
|
110
|
+
if (signals.emailsSent === 0 && signals.meetingsHeld === 0) return "";
|
|
111
|
+
const lines = [
|
|
112
|
+
"## Google Workspace Activity (external coordination + meeting load)",
|
|
113
|
+
""
|
|
114
|
+
];
|
|
115
|
+
if (signals.emailsSent > 0) {
|
|
116
|
+
lines.push(
|
|
117
|
+
`${signals.emailsSent} emails sent in window, to ${signals.uniqueRecipients} unique recipients.`
|
|
118
|
+
);
|
|
119
|
+
if (signals.topRecipients.length > 0) {
|
|
120
|
+
lines.push(`Most-emailed: ${signals.topRecipients.slice(0, 5).join(", ")}.`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
if (signals.meetingsHeld > 0) {
|
|
124
|
+
const hours = Math.round(signals.totalMeetingMinutes / 60 * 10) / 10;
|
|
125
|
+
lines.push(
|
|
126
|
+
`${signals.meetingsHeld} meetings held (${signals.meetingsOrganized} organized by the leader), ${hours}h total.`
|
|
127
|
+
);
|
|
128
|
+
if (signals.avgMeetingAttendees !== null) {
|
|
129
|
+
lines.push(
|
|
130
|
+
`Average ${signals.avgMeetingAttendees} attendees per meeting, ${signals.uniqueAttendees} unique attendees total.`
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
lines.push("");
|
|
135
|
+
lines.push(
|
|
136
|
+
"Gmail sent volume + Calendar meeting load reveal a leader's external coordination shape."
|
|
137
|
+
);
|
|
138
|
+
lines.push(
|
|
139
|
+
"Compare against shipped work (GitHub, Linear) to find the stated-strategy-vs-actual-time gap."
|
|
140
|
+
);
|
|
141
|
+
return lines.join("\n");
|
|
142
|
+
}
|
|
143
|
+
async function fetchGmailSent(token, since, maxEmails, leaderEmail) {
|
|
144
|
+
const sinceUnix = Math.floor(since.getTime() / 1e3);
|
|
145
|
+
const listUrl = new URL("https://gmail.googleapis.com/gmail/v1/users/me/messages");
|
|
146
|
+
listUrl.searchParams.set("q", `in:sent after:${sinceUnix}`);
|
|
147
|
+
listUrl.searchParams.set("maxResults", String(Math.min(maxEmails, 100)));
|
|
148
|
+
const listRes = await fetch(listUrl.toString(), {
|
|
149
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
150
|
+
});
|
|
151
|
+
if (!listRes.ok) {
|
|
152
|
+
throw new Error(`Gmail list failed ${listRes.status}: ${(await listRes.text()).slice(0, 200)}`);
|
|
153
|
+
}
|
|
154
|
+
const listJson = await listRes.json();
|
|
155
|
+
const ids = (listJson.messages ?? []).slice(0, maxEmails);
|
|
156
|
+
const events = [];
|
|
157
|
+
const recipientCounts = /* @__PURE__ */ new Map();
|
|
158
|
+
const PARALLEL = 5;
|
|
159
|
+
for (let i = 0; i < ids.length; i += PARALLEL) {
|
|
160
|
+
const chunk = ids.slice(i, i + PARALLEL);
|
|
161
|
+
const results = await Promise.all(
|
|
162
|
+
chunk.map(
|
|
163
|
+
(m) => fetch(
|
|
164
|
+
`https://gmail.googleapis.com/gmail/v1/users/me/messages/${m.id}?format=metadata&metadataHeaders=From&metadataHeaders=To&metadataHeaders=Subject&metadataHeaders=Date`,
|
|
165
|
+
{ headers: { Authorization: `Bearer ${token}` } }
|
|
166
|
+
).then((r) => r.ok ? r.json() : null).catch(() => null)
|
|
167
|
+
)
|
|
168
|
+
);
|
|
169
|
+
for (const msg of results) {
|
|
170
|
+
if (!msg) continue;
|
|
171
|
+
const headers = msg.payload?.headers || [];
|
|
172
|
+
const header = (n) => headers.find((h) => h.name.toLowerCase() === n.toLowerCase())?.value ?? "";
|
|
173
|
+
const subject = header("Subject") || "(no subject)";
|
|
174
|
+
const to = header("To");
|
|
175
|
+
const dateHdr = header("Date");
|
|
176
|
+
const timestamp = dateHdr ? new Date(dateHdr).toISOString() : (/* @__PURE__ */ new Date()).toISOString();
|
|
177
|
+
const snippet = msg.snippet ?? "";
|
|
178
|
+
const recipients = parseAddressList(to);
|
|
179
|
+
for (const r of recipients) {
|
|
180
|
+
recipientCounts.set(r, (recipientCounts.get(r) ?? 0) + 1);
|
|
181
|
+
}
|
|
182
|
+
events.push({
|
|
183
|
+
id: `gmail-${msg.id}`,
|
|
184
|
+
timestamp,
|
|
185
|
+
actor: {
|
|
186
|
+
id: leaderEmail ?? "leader",
|
|
187
|
+
kind: "human",
|
|
188
|
+
name: leaderEmail ?? "Leader"
|
|
189
|
+
},
|
|
190
|
+
kind: "email_sent",
|
|
191
|
+
content: `${subject} \u2014 ${snippet.slice(0, 200)}`,
|
|
192
|
+
metadata: {
|
|
193
|
+
to: recipients.slice(0, 5),
|
|
194
|
+
subject
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
const topRecipients = [...recipientCounts.entries()].sort((a, b) => b[1] - a[1]).slice(0, 10).map(([addr]) => addr);
|
|
200
|
+
return [
|
|
201
|
+
events,
|
|
202
|
+
{
|
|
203
|
+
emailsSent: events.length,
|
|
204
|
+
uniqueRecipients: recipientCounts.size,
|
|
205
|
+
topRecipients
|
|
206
|
+
}
|
|
207
|
+
];
|
|
208
|
+
}
|
|
209
|
+
function parseAddressList(raw) {
|
|
210
|
+
if (!raw) return [];
|
|
211
|
+
return raw.split(",").map((a) => {
|
|
212
|
+
const match = a.match(/<([^>]+)>/);
|
|
213
|
+
const addr = (match ? match[1] : a).trim().toLowerCase();
|
|
214
|
+
return addr;
|
|
215
|
+
}).filter((a) => a.includes("@") && a.length < 100);
|
|
216
|
+
}
|
|
217
|
+
async function fetchCalendarEvents(token, since, maxEvents, leaderEmail) {
|
|
218
|
+
const timeMin = since.toISOString();
|
|
219
|
+
const timeMax = (/* @__PURE__ */ new Date()).toISOString();
|
|
220
|
+
const url = new URL("https://www.googleapis.com/calendar/v3/calendars/primary/events");
|
|
221
|
+
url.searchParams.set("timeMin", timeMin);
|
|
222
|
+
url.searchParams.set("timeMax", timeMax);
|
|
223
|
+
url.searchParams.set("singleEvents", "true");
|
|
224
|
+
url.searchParams.set("orderBy", "startTime");
|
|
225
|
+
url.searchParams.set("maxResults", String(Math.min(maxEvents, 250)));
|
|
226
|
+
const res = await fetch(url.toString(), {
|
|
227
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
228
|
+
});
|
|
229
|
+
if (!res.ok) {
|
|
230
|
+
throw new Error(`Calendar list failed ${res.status}: ${(await res.text()).slice(0, 200)}`);
|
|
231
|
+
}
|
|
232
|
+
const json = await res.json();
|
|
233
|
+
const events = [];
|
|
234
|
+
const attendeeSet = /* @__PURE__ */ new Set();
|
|
235
|
+
let totalMinutes = 0;
|
|
236
|
+
let meetingsOrganized = 0;
|
|
237
|
+
const attendeeCounts = [];
|
|
238
|
+
for (const ev of json.items ?? []) {
|
|
239
|
+
if (ev.status === "cancelled") continue;
|
|
240
|
+
const start = ev.start?.dateTime || ev.start?.date;
|
|
241
|
+
const end = ev.end?.dateTime || ev.end?.date;
|
|
242
|
+
if (!start) continue;
|
|
243
|
+
const startMs = new Date(start).getTime();
|
|
244
|
+
const endMs = end ? new Date(end).getTime() : startMs;
|
|
245
|
+
const minutes = Math.max(0, Math.round((endMs - startMs) / 6e4));
|
|
246
|
+
totalMinutes += minutes;
|
|
247
|
+
const attendees = (ev.attendees ?? []).map((a) => a.email?.toLowerCase()).filter((e) => !!e && e.includes("@"));
|
|
248
|
+
for (const a of attendees) attendeeSet.add(a);
|
|
249
|
+
attendeeCounts.push(attendees.length);
|
|
250
|
+
const organizedByLeader = leaderEmail && ev.organizer?.email?.toLowerCase() === leaderEmail;
|
|
251
|
+
if (organizedByLeader) meetingsOrganized++;
|
|
252
|
+
events.push({
|
|
253
|
+
id: `gcal-${ev.id}`,
|
|
254
|
+
timestamp: start,
|
|
255
|
+
actor: {
|
|
256
|
+
id: leaderEmail ?? "leader",
|
|
257
|
+
kind: "human",
|
|
258
|
+
name: leaderEmail ?? "Leader"
|
|
259
|
+
},
|
|
260
|
+
kind: organizedByLeader ? "meeting_organized" : "meeting_attended",
|
|
261
|
+
content: `${ev.summary ?? "(no title)"} \u2014 ${minutes}min, ${attendees.length} attendees`,
|
|
262
|
+
metadata: {
|
|
263
|
+
attendees: attendees.slice(0, 10),
|
|
264
|
+
minutes,
|
|
265
|
+
organizer: ev.organizer?.email
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
const avgAttendees = attendeeCounts.length > 0 ? Math.round(
|
|
270
|
+
attendeeCounts.reduce((a, b) => a + b, 0) / attendeeCounts.length
|
|
271
|
+
) : null;
|
|
272
|
+
return [
|
|
273
|
+
events,
|
|
274
|
+
{
|
|
275
|
+
meetingsHeld: events.length,
|
|
276
|
+
meetingsOrganized,
|
|
277
|
+
uniqueAttendees: attendeeSet.size,
|
|
278
|
+
totalMeetingMinutes: totalMinutes,
|
|
279
|
+
avgMeetingAttendees: avgAttendees
|
|
280
|
+
}
|
|
281
|
+
];
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// src/radiant/adapters/salesforce.ts
|
|
285
|
+
async function fetchSalesforceActivity(options) {
|
|
286
|
+
const windowDays = options.windowDays ?? 14;
|
|
287
|
+
const maxRecords = Math.min(options.maxRecords ?? 200, 200);
|
|
288
|
+
const since = new Date(Date.now() - windowDays * 24 * 60 * 60 * 1e3);
|
|
289
|
+
const sinceSoql = since.toISOString();
|
|
290
|
+
const events = [];
|
|
291
|
+
const signals = {
|
|
292
|
+
opportunitiesMoved: 0,
|
|
293
|
+
stageTransitions: 0,
|
|
294
|
+
amountChanges: 0,
|
|
295
|
+
closedWon: 0,
|
|
296
|
+
closedLost: 0,
|
|
297
|
+
tasksLogged: 0,
|
|
298
|
+
callsLogged: 0,
|
|
299
|
+
feedPostsByLeader: 0,
|
|
300
|
+
totalPipelineAmount: 0,
|
|
301
|
+
topStages: []
|
|
302
|
+
};
|
|
303
|
+
const opps = await soqlQuery(
|
|
304
|
+
options,
|
|
305
|
+
`SELECT Id, Name, StageName, Amount, CloseDate, IsClosed, IsWon, LastModifiedDate, Owner.Name
|
|
306
|
+
FROM Opportunity
|
|
307
|
+
WHERE LastModifiedDate >= ${sinceSoql}
|
|
308
|
+
ORDER BY LastModifiedDate DESC
|
|
309
|
+
LIMIT ${maxRecords}`
|
|
310
|
+
);
|
|
311
|
+
const stageCounts = /* @__PURE__ */ new Map();
|
|
312
|
+
for (const opp of opps) {
|
|
313
|
+
signals.opportunitiesMoved++;
|
|
314
|
+
signals.totalPipelineAmount += opp.Amount ?? 0;
|
|
315
|
+
stageCounts.set(opp.StageName, (stageCounts.get(opp.StageName) ?? 0) + 1);
|
|
316
|
+
if (opp.IsClosed && opp.IsWon) signals.closedWon++;
|
|
317
|
+
if (opp.IsClosed && !opp.IsWon) signals.closedLost++;
|
|
318
|
+
events.push({
|
|
319
|
+
id: `sf-opp-${opp.Id}`,
|
|
320
|
+
timestamp: opp.LastModifiedDate,
|
|
321
|
+
actor: {
|
|
322
|
+
id: opp.Owner?.Name ?? "unknown",
|
|
323
|
+
kind: "human",
|
|
324
|
+
name: opp.Owner?.Name ?? "unknown"
|
|
325
|
+
},
|
|
326
|
+
kind: opp.IsClosed ? opp.IsWon ? "deal_won" : "deal_lost" : "deal_updated",
|
|
327
|
+
content: `${opp.Name} \u2014 ${opp.StageName}${opp.Amount ? ` \xB7 $${Math.round(opp.Amount).toLocaleString()}` : ""} \xB7 close ${opp.CloseDate}`,
|
|
328
|
+
metadata: {
|
|
329
|
+
opportunityId: opp.Id,
|
|
330
|
+
stage: opp.StageName,
|
|
331
|
+
amount: opp.Amount,
|
|
332
|
+
closeDate: opp.CloseDate
|
|
333
|
+
}
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
signals.topStages = [...stageCounts.entries()].sort((a, b) => b[1] - a[1]).slice(0, 5).map(([stage, count]) => ({ stage, count }));
|
|
337
|
+
const history = await soqlQuery(
|
|
338
|
+
options,
|
|
339
|
+
`SELECT Id, OpportunityId, Field, OldValue, NewValue, CreatedDate, CreatedBy.Name
|
|
340
|
+
FROM OpportunityFieldHistory
|
|
341
|
+
WHERE CreatedDate >= ${sinceSoql} AND Field IN ('StageName', 'Amount', 'CloseDate')
|
|
342
|
+
ORDER BY CreatedDate DESC
|
|
343
|
+
LIMIT ${maxRecords}`
|
|
344
|
+
).catch(() => []);
|
|
345
|
+
for (const h of history) {
|
|
346
|
+
if (h.Field === "StageName") signals.stageTransitions++;
|
|
347
|
+
if (h.Field === "Amount") signals.amountChanges++;
|
|
348
|
+
events.push({
|
|
349
|
+
id: `sf-hist-${h.Id}`,
|
|
350
|
+
timestamp: h.CreatedDate,
|
|
351
|
+
actor: {
|
|
352
|
+
id: h.CreatedBy?.Name ?? "unknown",
|
|
353
|
+
kind: "human",
|
|
354
|
+
name: h.CreatedBy?.Name ?? "unknown"
|
|
355
|
+
},
|
|
356
|
+
kind: `deal_${h.Field.toLowerCase()}_changed`,
|
|
357
|
+
content: `${h.Field}: ${String(h.OldValue)} \u2192 ${String(h.NewValue)}`,
|
|
358
|
+
metadata: {
|
|
359
|
+
opportunityId: h.OpportunityId,
|
|
360
|
+
field: h.Field
|
|
361
|
+
}
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
const tasks = await soqlQuery(
|
|
365
|
+
options,
|
|
366
|
+
`SELECT Id, Subject, Status, Type, CreatedDate, Owner.Name
|
|
367
|
+
FROM Task
|
|
368
|
+
WHERE CreatedDate >= ${sinceSoql}
|
|
369
|
+
ORDER BY CreatedDate DESC
|
|
370
|
+
LIMIT ${maxRecords}`
|
|
371
|
+
).catch(() => []);
|
|
372
|
+
for (const t of tasks) {
|
|
373
|
+
signals.tasksLogged++;
|
|
374
|
+
if (t.Type === "Call" || (t.Subject || "").toLowerCase().includes("call")) {
|
|
375
|
+
signals.callsLogged++;
|
|
376
|
+
}
|
|
377
|
+
events.push({
|
|
378
|
+
id: `sf-task-${t.Id}`,
|
|
379
|
+
timestamp: t.CreatedDate,
|
|
380
|
+
actor: {
|
|
381
|
+
id: t.Owner?.Name ?? "unknown",
|
|
382
|
+
kind: "human",
|
|
383
|
+
name: t.Owner?.Name ?? "unknown"
|
|
384
|
+
},
|
|
385
|
+
kind: t.Type === "Call" ? "call_logged" : "task_logged",
|
|
386
|
+
content: `${t.Subject} \u2014 ${t.Status}`,
|
|
387
|
+
metadata: { taskId: t.Id, type: t.Type, status: t.Status }
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
if (options.leaderName) {
|
|
391
|
+
const feed = await soqlQuery(
|
|
392
|
+
options,
|
|
393
|
+
`SELECT Id, Body, CreatedDate, CreatedBy.Name, ParentId
|
|
394
|
+
FROM FeedItem
|
|
395
|
+
WHERE CreatedDate >= ${sinceSoql} AND CreatedBy.Name = '${escapeSoql(options.leaderName)}'
|
|
396
|
+
ORDER BY CreatedDate DESC
|
|
397
|
+
LIMIT ${Math.min(maxRecords, 50)}`
|
|
398
|
+
).catch(() => []);
|
|
399
|
+
for (const f of feed) {
|
|
400
|
+
signals.feedPostsByLeader++;
|
|
401
|
+
events.push({
|
|
402
|
+
id: `sf-feed-${f.Id}`,
|
|
403
|
+
timestamp: f.CreatedDate,
|
|
404
|
+
actor: {
|
|
405
|
+
id: f.CreatedBy?.Name ?? "unknown",
|
|
406
|
+
kind: "human",
|
|
407
|
+
name: f.CreatedBy?.Name ?? "unknown"
|
|
408
|
+
},
|
|
409
|
+
kind: "feed_post",
|
|
410
|
+
content: (f.Body || "").slice(0, 280),
|
|
411
|
+
metadata: { feedId: f.Id, parent: f.ParentId }
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
events.sort((a, b) => Date.parse(a.timestamp) - Date.parse(b.timestamp));
|
|
416
|
+
return { events, signals };
|
|
417
|
+
}
|
|
418
|
+
function formatSalesforceSignalsForPrompt(signals) {
|
|
419
|
+
if (signals.opportunitiesMoved === 0 && signals.tasksLogged === 0 && signals.stageTransitions === 0) {
|
|
420
|
+
return "";
|
|
421
|
+
}
|
|
422
|
+
const lines = [
|
|
423
|
+
"## Salesforce Activity (stated pipeline vs observed motion)",
|
|
424
|
+
""
|
|
425
|
+
];
|
|
426
|
+
if (signals.opportunitiesMoved > 0) {
|
|
427
|
+
const pipelineM = Math.round(signals.totalPipelineAmount / 1e4) / 100;
|
|
428
|
+
lines.push(
|
|
429
|
+
`${signals.opportunitiesMoved} opportunities touched in window ($${pipelineM}M total pipeline represented).`
|
|
430
|
+
);
|
|
431
|
+
lines.push(
|
|
432
|
+
`${signals.stageTransitions} stage changes, ${signals.amountChanges} amount changes.`
|
|
433
|
+
);
|
|
434
|
+
if (signals.closedWon + signals.closedLost > 0) {
|
|
435
|
+
lines.push(`${signals.closedWon} closed won, ${signals.closedLost} closed lost.`);
|
|
436
|
+
}
|
|
437
|
+
if (signals.topStages.length > 0) {
|
|
438
|
+
lines.push(
|
|
439
|
+
`Most active stages: ${signals.topStages.map((s) => `${s.stage} (${s.count})`).join(", ")}.`
|
|
440
|
+
);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
if (signals.tasksLogged > 0) {
|
|
444
|
+
lines.push(
|
|
445
|
+
`${signals.tasksLogged} tasks logged (${signals.callsLogged} calls).`
|
|
446
|
+
);
|
|
447
|
+
}
|
|
448
|
+
if (signals.feedPostsByLeader > 0) {
|
|
449
|
+
lines.push(`${signals.feedPostsByLeader} feed posts by the leader.`);
|
|
450
|
+
}
|
|
451
|
+
lines.push("");
|
|
452
|
+
lines.push(
|
|
453
|
+
"Salesforce shows what the team said would happen (stages, forecast) vs. what is actually happening (movement, activity, close)."
|
|
454
|
+
);
|
|
455
|
+
lines.push(
|
|
456
|
+
"Compare stage transitions against stated strategy \u2014 are the deals the leader said would close actually moving, or is the pipeline drifting?"
|
|
457
|
+
);
|
|
458
|
+
return lines.join("\n");
|
|
459
|
+
}
|
|
460
|
+
async function soqlQuery(opts, query) {
|
|
461
|
+
const url = new URL(`${opts.instanceUrl}/services/data/v59.0/query`);
|
|
462
|
+
url.searchParams.set("q", query);
|
|
463
|
+
const res = await fetch(url.toString(), {
|
|
464
|
+
headers: { Authorization: `Bearer ${opts.accessToken}` }
|
|
465
|
+
});
|
|
466
|
+
if (!res.ok) {
|
|
467
|
+
throw new Error(
|
|
468
|
+
`Salesforce SOQL ${res.status}: ${(await res.text()).slice(0, 200)}`
|
|
469
|
+
);
|
|
470
|
+
}
|
|
471
|
+
const json = await res.json();
|
|
472
|
+
return json.records ?? [];
|
|
473
|
+
}
|
|
474
|
+
function escapeSoql(raw) {
|
|
475
|
+
return raw.replace(/['\\]/g, "");
|
|
476
|
+
}
|
|
477
|
+
|
|
79
478
|
// src/radiant/index.ts
|
|
80
479
|
var RADIANT_PACKAGE_VERSION = "0.0.0";
|
|
81
480
|
export {
|
|
@@ -105,16 +504,20 @@ export {
|
|
|
105
504
|
fetchDiscordActivity,
|
|
106
505
|
fetchGitHubActivity,
|
|
107
506
|
fetchGitHubOrgActivity,
|
|
507
|
+
fetchGoogleWorkspaceActivity,
|
|
108
508
|
fetchLinearActivity,
|
|
109
509
|
fetchNotionActivity,
|
|
510
|
+
fetchSalesforceActivity,
|
|
110
511
|
fetchSlackActivity,
|
|
111
512
|
filterEventsByUser,
|
|
112
513
|
formatActiveWorlds,
|
|
113
514
|
formatDiscordSignalsForPrompt,
|
|
114
515
|
formatExocortexForPrompt,
|
|
516
|
+
formatGoogleWorkspaceSignalsForPrompt,
|
|
115
517
|
formatLinearSignalsForPrompt,
|
|
116
518
|
formatNotionSignalsForPrompt,
|
|
117
519
|
formatPriorReadsForPrompt,
|
|
520
|
+
formatSalesforceSignalsForPrompt,
|
|
118
521
|
formatScope,
|
|
119
522
|
formatSlackSignalsForPrompt,
|
|
120
523
|
formatTeamExocorticesForPrompt,
|
|
@@ -3,10 +3,10 @@ import {
|
|
|
3
3
|
emergent,
|
|
4
4
|
parseRepoScope,
|
|
5
5
|
think
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-2KTPIE57.js";
|
|
7
7
|
import "./chunk-TCGGED4G.js";
|
|
8
8
|
import "./chunk-I4RTIMLX.js";
|
|
9
|
-
import "./chunk-
|
|
9
|
+
import "./chunk-MBOW6YXN.js";
|
|
10
10
|
import "./chunk-QLPTHTVB.js";
|
|
11
11
|
import "./chunk-QWGCMQQD.js";
|
|
12
12
|
|
|
@@ -2,10 +2,10 @@ import {
|
|
|
2
2
|
SessionManager,
|
|
3
3
|
runInteractiveMode,
|
|
4
4
|
runPipeMode
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-XAF3CYCW.js";
|
|
6
6
|
import "./chunk-D2UCV5AK.js";
|
|
7
7
|
import "./chunk-I4RTIMLX.js";
|
|
8
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-MBOW6YXN.js";
|
|
9
9
|
import "./chunk-QLPTHTVB.js";
|
|
10
10
|
import "./chunk-QWGCMQQD.js";
|
|
11
11
|
export {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { G as GuardVerdict, P as PlanDefinition, c as PlanProgress, b as GuardEngineOptions, a as GuardEvent } from './guard-contract-
|
|
1
|
+
import { G as GuardVerdict, P as PlanDefinition, c as PlanProgress, b as GuardEngineOptions, a as GuardEvent } from './guard-contract-Oznf-Kgq.cjs';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Shared Adapter Utilities
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { G as GuardVerdict, P as PlanDefinition, c as PlanProgress, b as GuardEngineOptions, a as GuardEvent } from './guard-contract-
|
|
1
|
+
import { G as GuardVerdict, P as PlanDefinition, c as PlanProgress, b as GuardEngineOptions, a as GuardEvent } from './guard-contract-w_i_6gh-.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Shared Adapter Utilities
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@neuroverseos/governance",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "Deterministic governance engine for AI agents — enforce worlds (permanent rules) and plans (mission constraints) with full audit trace",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
File without changes
|