mcp-scraper 0.85.0 → 0.86.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -1
- package/README.md +2 -2
- package/dist/{analytics-repository-4VZQ4TKW.js → analytics-repository-GGJJCVVP.js} +9 -1
- package/dist/bin/api-server.js +3 -3
- package/dist/bin/mcp-scraper-cli.js +1 -1
- package/dist/bin/mcp-scraper-core.js +5 -5
- package/dist/bin/mcp-scraper-install.js +2 -2
- package/dist/bin/mcp-stdio-server.js +5 -5
- package/dist/{chunk-RHAOKXQK.js → chunk-36EAKRR6.js} +1 -1
- package/dist/{chunk-WN7N4ESQ.js → chunk-7523VOQT.js} +1 -1
- package/dist/{chunk-W4IY6CB4.js → chunk-FBB6DEUV.js} +5688 -4
- package/dist/{chunk-C7OKENCR.js → chunk-KQWVJOVR.js} +1 -1
- package/dist/{chunk-X5HRAAQM.js → chunk-NKRO2SUO.js} +3 -3
- package/dist/{chunk-2ZDYUTOZ.js → chunk-QKWNEMGH.js} +3 -3
- package/dist/{chunk-W3SGF7GX.js → chunk-WFGAR4BZ.js} +1 -1
- package/dist/{chunk-TLRJV4SL.js → chunk-X623GTBV.js} +427 -155
- package/dist/{extract-bundle-NSMGHEG6.js → extract-bundle-FALNLKYY.js} +2 -2
- package/dist/{gmail-service-BTRAHGJS.js → gmail-service-BUSU4BVX.js} +2 -2
- package/dist/{server-EOPETL7Q.js → server-OZBTZIDZ.js} +1320 -645
- package/dist/{site-extract-repository-DWU52BRQ.js → site-extract-repository-S5FYNFDY.js} +2 -2
- package/dist/{worker-5A375BGN.js → worker-OQSFSLNG.js} +1 -1
- package/package.json +15 -4
|
@@ -43,7 +43,7 @@ import {
|
|
|
43
43
|
setExtractJobTotal,
|
|
44
44
|
settleExtractJob,
|
|
45
45
|
terminalExtractJobStatus
|
|
46
|
-
} from "./chunk-
|
|
46
|
+
} from "./chunk-KQWVJOVR.js";
|
|
47
47
|
import {
|
|
48
48
|
REQUIRED_LOCATION_STATE_CODES,
|
|
49
49
|
importHostedCensusPlacesCsv,
|
|
@@ -105,7 +105,7 @@ import {
|
|
|
105
105
|
probeNangoConnectionDirect,
|
|
106
106
|
recordNangoConnectionCost,
|
|
107
107
|
settleConnectedUsage
|
|
108
|
-
} from "./chunk-
|
|
108
|
+
} from "./chunk-WFGAR4BZ.js";
|
|
109
109
|
import {
|
|
110
110
|
ANALYTICS_ATTRIBUTION_MODELS,
|
|
111
111
|
ANALYTICS_CONTENT_SORTS,
|
|
@@ -134,6 +134,7 @@ import {
|
|
|
134
134
|
claimAnalyticsCrmImportRows,
|
|
135
135
|
claimAnalyticsFormDeliveryJobs,
|
|
136
136
|
completeAnalyticsCrmImportRow,
|
|
137
|
+
completeAnalyticsFormBridgeDelivery,
|
|
137
138
|
completeAnalyticsFormDelivery,
|
|
138
139
|
consumeAnalyticsSurveyInvite,
|
|
139
140
|
createAnalyticsActivationDestination,
|
|
@@ -148,6 +149,7 @@ import {
|
|
|
148
149
|
deferAnalyticsCrmImportRow,
|
|
149
150
|
deferAnalyticsFormDelivery,
|
|
150
151
|
deleteAnalyticsSite,
|
|
152
|
+
deterministicAnalyticsCrmEntityId,
|
|
151
153
|
encryptAnalyticsRestricted,
|
|
152
154
|
enrichAnalyticsExistingCrmIdentity,
|
|
153
155
|
getAnalyticsActivationDestinationConnectionRef,
|
|
@@ -172,9 +174,8 @@ import {
|
|
|
172
174
|
normalizeProviderReceipt,
|
|
173
175
|
pollAnalyticsActivationDiagnostics,
|
|
174
176
|
prepareAnalyticsLinkerIssue,
|
|
175
|
-
|
|
177
|
+
queueAnalyticsFormBridgeTransaction,
|
|
176
178
|
readImmutableConfirmedAttributionEvidence,
|
|
177
|
-
recordAnalyticsFormSubmission,
|
|
178
179
|
redeemAnalyticsLinkerRecord,
|
|
179
180
|
refreshAnalyticsDailyRollupsIfDue,
|
|
180
181
|
requireAnalyticsAccess,
|
|
@@ -193,7 +194,7 @@ import {
|
|
|
193
194
|
upsertAnalyticsAdSpend,
|
|
194
195
|
upsertAnalyticsHostGroup,
|
|
195
196
|
verifyAnalyticsWebhookSignature
|
|
196
|
-
} from "./chunk-
|
|
197
|
+
} from "./chunk-X623GTBV.js";
|
|
197
198
|
import {
|
|
198
199
|
claimServiceConnectionAction,
|
|
199
200
|
ensureServiceConnectionsSchema,
|
|
@@ -387,7 +388,7 @@ import {
|
|
|
387
388
|
transcribeMediaUrl,
|
|
388
389
|
transitionAnalyticsExperiment,
|
|
389
390
|
validateAnalyticsRestResponseForRequest
|
|
390
|
-
} from "./chunk-
|
|
391
|
+
} from "./chunk-FBB6DEUV.js";
|
|
391
392
|
import {
|
|
392
393
|
auditImageUrls,
|
|
393
394
|
auditImages,
|
|
@@ -458,7 +459,7 @@ import {
|
|
|
458
459
|
tierChangeLeavesPrivateOffer,
|
|
459
460
|
tierCreditsPerInterval,
|
|
460
461
|
vendorCostUsdToMc
|
|
461
|
-
} from "./chunk-
|
|
462
|
+
} from "./chunk-NKRO2SUO.js";
|
|
462
463
|
import {
|
|
463
464
|
browserServiceApiKey,
|
|
464
465
|
browserServiceProfileName,
|
|
@@ -508,7 +509,7 @@ import {
|
|
|
508
509
|
} from "./chunk-GGZEC22A.js";
|
|
509
510
|
import {
|
|
510
511
|
PACKAGE_VERSION
|
|
511
|
-
} from "./chunk-
|
|
512
|
+
} from "./chunk-36EAKRR6.js";
|
|
512
513
|
import {
|
|
513
514
|
CaptchaError,
|
|
514
515
|
MapsSearchIncompletePageError,
|
|
@@ -3971,7 +3972,7 @@ async function generateOgImage(post) {
|
|
|
3971
3972
|
|
|
3972
3973
|
// src/api/server.ts
|
|
3973
3974
|
import { Resend as Resend3 } from "resend";
|
|
3974
|
-
import { createHash as
|
|
3975
|
+
import { createHash as createHash104, randomUUID as randomUUID69 } from "crypto";
|
|
3975
3976
|
|
|
3976
3977
|
// src/api/kpo-extractor.ts
|
|
3977
3978
|
import TurndownService from "turndown";
|
|
@@ -7321,7 +7322,7 @@ async function extractSite(opts) {
|
|
|
7321
7322
|
}
|
|
7322
7323
|
|
|
7323
7324
|
// src/api/server.ts
|
|
7324
|
-
import { Hono as
|
|
7325
|
+
import { Hono as Hono49 } from "hono";
|
|
7325
7326
|
import { serve as serveInngest } from "inngest/hono";
|
|
7326
7327
|
|
|
7327
7328
|
// src/inngest/client.ts
|
|
@@ -9763,7 +9764,7 @@ var siteExtractFn = inngest.createFunction(
|
|
|
9763
9764
|
});
|
|
9764
9765
|
}) : null;
|
|
9765
9766
|
const finalized = await step.run("finalize", async () => {
|
|
9766
|
-
const { assembleExtractArtifacts } = await import("./extract-bundle-
|
|
9767
|
+
const { assembleExtractArtifacts } = await import("./extract-bundle-FALNLKYY.js");
|
|
9767
9768
|
const current = await getExtractJob(jobId2);
|
|
9768
9769
|
if (!current) throw new Error("extract job disappeared before finalization");
|
|
9769
9770
|
const stored = await assembleExtractArtifacts(current, { branding, imageAudit });
|
|
@@ -35418,17 +35419,17 @@ async function discoverAnalyticsCrmEffectiveProfile(input) {
|
|
|
35418
35419
|
const publicProfile = getAnalyticsCrmProviderProfile(provider);
|
|
35419
35420
|
const payload = provider === "highlevel" ? { locationId: input.discoveryContext?.locationId } : provider === "zoho" ? { module: input.discoveryContext?.zohoModules?.[0] ?? "Contacts" } : {};
|
|
35420
35421
|
if (provider === "highlevel" && !safeString(payload.locationId, 128)) throw new Error("analytics_crm_highlevel_location_required");
|
|
35421
|
-
const
|
|
35422
|
+
const call2 = (actionPayload, suffix2) => input.dependencies.callAction({
|
|
35422
35423
|
connectionId: input.connectionId,
|
|
35423
35424
|
action: ANALYTICS_CRM_NANGO_ACTIONS.discoverSchema,
|
|
35424
35425
|
payload: actionPayload,
|
|
35425
35426
|
idempotencyKey: stableId("crmdiscover", { provider, connectionId: input.connectionId, actionPayload, suffix: suffix2 })
|
|
35426
35427
|
});
|
|
35427
|
-
let raw = await
|
|
35428
|
+
let raw = await call2(payload);
|
|
35428
35429
|
if (provider === "zoho") {
|
|
35429
35430
|
const modules = [...new Set(input.discoveryContext?.zohoModules ?? ["Contacts", "Deals"])];
|
|
35430
35431
|
const results = [raw];
|
|
35431
|
-
for (const module of modules.slice(1)) results.push(await
|
|
35432
|
+
for (const module of modules.slice(1)) results.push(await call2({ module }, module));
|
|
35432
35433
|
raw = { moduleResults: results };
|
|
35433
35434
|
}
|
|
35434
35435
|
const normalized = normalizeProviderSchema(provider, raw);
|
|
@@ -39772,7 +39773,7 @@ loadChannels();
|
|
|
39772
39773
|
|
|
39773
39774
|
// src/api/vault-routes.ts
|
|
39774
39775
|
import { Hono as Hono30 } from "hono";
|
|
39775
|
-
var VAULTS = ["People", "Organizations", "Deals", "Projects", "Tasks", "Communications", "Calendar"];
|
|
39776
|
+
var VAULTS = ["People", "Organizations", "CRM People", "CRM Organizations", "Deals", "Projects", "Tasks", "Communications", "Calendar"];
|
|
39776
39777
|
var PROJECT_TYPES = ["codebase", "personal", "work", "client"];
|
|
39777
39778
|
var PROJECT_KIND_BY_TYPE = {
|
|
39778
39779
|
codebase: "codebase",
|
|
@@ -39856,6 +39857,8 @@ function normalizeRelationshipProps(vault, props) {
|
|
|
39856
39857
|
}
|
|
39857
39858
|
function defaultType(vault) {
|
|
39858
39859
|
if (vault === "People" || vault === "Communications") return "unclassified";
|
|
39860
|
+
if (vault === "CRM People") return "person";
|
|
39861
|
+
if (vault === "CRM Organizations") return "organization";
|
|
39859
39862
|
if (vault === "Organizations") return "organization";
|
|
39860
39863
|
if (vault === "Deals") return "deal";
|
|
39861
39864
|
if (vault === "Projects") return "project";
|
|
@@ -39864,7 +39867,7 @@ function defaultType(vault) {
|
|
|
39864
39867
|
return "unclassified";
|
|
39865
39868
|
}
|
|
39866
39869
|
function defaultStatus(vault) {
|
|
39867
|
-
if (vault === "People" || vault === "Organizations") return "active";
|
|
39870
|
+
if (vault === "People" || vault === "Organizations" || vault === "CRM People" || vault === "CRM Organizations") return "active";
|
|
39868
39871
|
if (vault === "Deals") return "lead";
|
|
39869
39872
|
if (vault === "Projects") return "active";
|
|
39870
39873
|
if (vault === "Tasks") return "to_do";
|
|
@@ -39939,7 +39942,7 @@ async function mapWithConcurrency3(items, limit, map) {
|
|
|
39939
39942
|
await Promise.all(Array.from({ length: Math.min(limit, items.length) }, () => worker()));
|
|
39940
39943
|
return values;
|
|
39941
39944
|
}
|
|
39942
|
-
async function
|
|
39945
|
+
async function readLegacyVault(vault, token7) {
|
|
39943
39946
|
const list = await readMemory("listTool", { vault }, token7);
|
|
39944
39947
|
if (!list.ok) throw new Error(list.error ?? `unable to read ${vault}`);
|
|
39945
39948
|
const noteRefs = (list.notes ?? []).slice(0, MAX_VAULT_RECORDS);
|
|
@@ -39952,6 +39955,28 @@ async function readVault(vault, token7) {
|
|
|
39952
39955
|
if (failed && !failed.ok) throw new Error(failed.error ?? `unable to read ${vault} record`);
|
|
39953
39956
|
return notes.filter((result3) => result3.ok && !!result3.note).map((result3) => workspaceRecord(vault, result3.note));
|
|
39954
39957
|
}
|
|
39958
|
+
async function readVault(vault, token7) {
|
|
39959
|
+
const tool = vault === "People" ? "researchPersonSearchTool" : vault === "Organizations" ? "researchOrganizationSearchTool" : vault === "CRM People" ? "crmPersonSearchTool" : vault === "CRM Organizations" ? "crmOrganizationSearchTool" : null;
|
|
39960
|
+
if (!tool) return readLegacyVault(vault, token7);
|
|
39961
|
+
const result3 = await memoryCall(tool, { limit: MAX_VAULT_RECORDS }, token7);
|
|
39962
|
+
if (!result3.ok) throw new Error(result3.error ?? `unable to read ${vault}`);
|
|
39963
|
+
return (result3.items ?? []).map((item) => workspaceRecord(vault, {
|
|
39964
|
+
path: item.entityId,
|
|
39965
|
+
title: item.displayName,
|
|
39966
|
+
content: item.content,
|
|
39967
|
+
kind: vault.startsWith("CRM ") ? "crm" : "research",
|
|
39968
|
+
updatedAt: item.updatedAt,
|
|
39969
|
+
capturedAt: item.createdAt,
|
|
39970
|
+
revision: item.revision,
|
|
39971
|
+
props: {
|
|
39972
|
+
...item.props,
|
|
39973
|
+
type: vault === "People" || vault === "CRM People" ? "person" : "organization",
|
|
39974
|
+
relationship_status: item.relationshipStatus,
|
|
39975
|
+
relationship_types: item.relationshipTypes,
|
|
39976
|
+
commercial_lifecycle: item.commercialLifecycle
|
|
39977
|
+
}
|
|
39978
|
+
}));
|
|
39979
|
+
}
|
|
39955
39980
|
vaultApp.get("/api/workspace", async (c) => {
|
|
39956
39981
|
const token7 = c.req.query("token");
|
|
39957
39982
|
if (!validToken(token7)) return c.json({ ok: false, error: "missing or malformed Vault App link" }, 401);
|
|
@@ -39976,6 +40001,9 @@ vaultApp.post("/api/records", async (c) => {
|
|
|
39976
40001
|
const content = typeof body3.content === "string" && body3.content.length <= 1e5 ? body3.content : "";
|
|
39977
40002
|
const props = propsValue(body3.props) ?? {};
|
|
39978
40003
|
if (!isVault(vault) || !path5 || !title) return c.json({ ok: false, error: "vault, path, and title are required" }, 400);
|
|
40004
|
+
if (["People", "Organizations", "CRM People", "CRM Organizations"].includes(vault)) {
|
|
40005
|
+
return c.json({ ok: false, error: "Governed Research and CRM records must be created through the native Research or CRM workflow." }, 409);
|
|
40006
|
+
}
|
|
39979
40007
|
const normalizedProps = normalizeRelationshipProps(vault, props);
|
|
39980
40008
|
const validationError2 = validateNewRecord(vault, normalizedProps);
|
|
39981
40009
|
if (validationError2) return c.json({ ok: false, error: validationError2 }, 400);
|
|
@@ -45170,10 +45198,10 @@ function mergeArticleSections(left, right) {
|
|
|
45170
45198
|
categories: uniqueStrings([...left.categories, ...right.categories]).slice(0, 50)
|
|
45171
45199
|
};
|
|
45172
45200
|
}
|
|
45173
|
-
function mergeUniqueRecords(items,
|
|
45201
|
+
function mergeUniqueRecords(items, keyFor2) {
|
|
45174
45202
|
const map = /* @__PURE__ */ new Map();
|
|
45175
45203
|
for (const item of items) {
|
|
45176
|
-
const key3 =
|
|
45204
|
+
const key3 = keyFor2(item).toLowerCase().replace(/\s+/g, " ").trim();
|
|
45177
45205
|
map.set(key3, { ...map.get(key3), ...item });
|
|
45178
45206
|
}
|
|
45179
45207
|
return [...map.values()];
|
|
@@ -46637,10 +46665,11 @@ function previewAnalyticsManualImport(input) {
|
|
|
46637
46665
|
continue;
|
|
46638
46666
|
}
|
|
46639
46667
|
identities.add(identityKey2);
|
|
46640
|
-
const digest23 = createHash31("sha256").update(`${parsedInput.sourceSystem}:${stableIdentity}`).digest("hex")
|
|
46668
|
+
const digest23 = createHash31("sha256").update(`${parsedInput.sourceSystem}:${stableIdentity}`).digest("hex");
|
|
46669
|
+
const crmEntityId = `${digest23.slice(0, 8)}-${digest23.slice(8, 12)}-5${digest23.slice(13, 16)}-${(Number.parseInt(digest23.slice(16, 18), 16) & 63 | 128).toString(16)}${digest23.slice(18, 20)}-${digest23.slice(20, 32)}`;
|
|
46641
46670
|
rows.push({
|
|
46642
46671
|
row: rowNumber,
|
|
46643
|
-
crmPersonRef:
|
|
46672
|
+
crmPersonRef: crmEntityId,
|
|
46644
46673
|
...displayName ? { displayName } : {},
|
|
46645
46674
|
...firstName ? { firstName } : {},
|
|
46646
46675
|
...lastName ? { lastName } : {},
|
|
@@ -48410,9 +48439,9 @@ function sanitizeNangoToolDescription(body3, tool) {
|
|
|
48410
48439
|
true
|
|
48411
48440
|
);
|
|
48412
48441
|
}
|
|
48413
|
-
let
|
|
48442
|
+
let serializedBytes2 = Number.POSITIVE_INFINITY;
|
|
48414
48443
|
try {
|
|
48415
|
-
|
|
48444
|
+
serializedBytes2 = Buffer.byteLength(JSON.stringify(rawTool), "utf8");
|
|
48416
48445
|
} catch {
|
|
48417
48446
|
}
|
|
48418
48447
|
const name = cleanString3(rawTool.name, 200);
|
|
@@ -48427,7 +48456,7 @@ function sanitizeNangoToolDescription(body3, tool) {
|
|
|
48427
48456
|
const outputSchema = outputSchemaValue === void 0 ? void 0 : sanitizeToolSchema(outputSchemaValue);
|
|
48428
48457
|
const blockedReasonValue = rawTool.blockedReason ?? rawTool.blocked_reason;
|
|
48429
48458
|
const blockedReason = blockedReasonValue === null || blockedReasonValue === void 0 ? null : blockedReasonValue === "actions_disabled" || blockedReasonValue === "inactive_connection" || blockedReasonValue === "missing_permission" || blockedReasonValue === "missing_app_feature" || blockedReasonValue === "permission_policy_missing" || blockedReasonValue === "permission_verification_unavailable" ? blockedReasonValue : void 0;
|
|
48430
|
-
if (
|
|
48459
|
+
if (serializedBytes2 > 256 * 1024 || !name || name !== tool || classification !== "read" && classification !== "action" || typeof rawTool.callable !== "boolean" || blockedReason === void 0 || transport !== "nango" && transport !== "remote_mcp" || !providerConfigKey || schemaSource !== "live_tools_list" || !upstreamSchemaHash || !/^[a-f0-9]{64}$/i.test(upstreamSchemaHash) || !fetchedAt || Number.isNaN(Date.parse(fetchedAt)) || !inputSchema || outputSchemaValue !== void 0 && !outputSchema) {
|
|
48431
48460
|
throw new NangoControlError(
|
|
48432
48461
|
"The connection service returned an invalid live tool description.",
|
|
48433
48462
|
502,
|
|
@@ -48567,7 +48596,7 @@ async function callMainOwnedExportPage(identity, input) {
|
|
|
48567
48596
|
});
|
|
48568
48597
|
}
|
|
48569
48598
|
if (connection.providerConfigKey === "google-mail" && input.dataset === "emails") {
|
|
48570
|
-
const { GmailService: GmailService2 } = await import("./gmail-service-
|
|
48599
|
+
const { GmailService: GmailService2 } = await import("./gmail-service-BUSU4BVX.js");
|
|
48571
48600
|
const service = new GmailService2();
|
|
48572
48601
|
const ownerId3 = createHash32("sha256").update(identity.toLowerCase()).digest("hex").slice(0, 24);
|
|
48573
48602
|
const after = Math.floor(Date.parse(input.from) / 1e3);
|
|
@@ -51927,7 +51956,15 @@ var ANALYTICS_PRIVACY_FIELD_REGISTRY = Object.freeze([
|
|
|
51927
51956
|
{
|
|
51928
51957
|
dataClass: "pseudonymous_identity",
|
|
51929
51958
|
purpose: "site_analytics",
|
|
51930
|
-
fields: [
|
|
51959
|
+
fields: [
|
|
51960
|
+
"identity.value_hmac",
|
|
51961
|
+
"identity.assignment_person_id",
|
|
51962
|
+
"identity.assignment_crm_entity_id",
|
|
51963
|
+
"identity.conflict_person_ids",
|
|
51964
|
+
"session.visitor_hmac",
|
|
51965
|
+
"session.session_hmac",
|
|
51966
|
+
"person.public_ref"
|
|
51967
|
+
],
|
|
51931
51968
|
storage: "pseudonymous",
|
|
51932
51969
|
defaultRetentionDays: 395,
|
|
51933
51970
|
readSurface: "privacy_export",
|
|
@@ -51981,7 +52018,14 @@ var ANALYTICS_PRIVACY_FIELD_REGISTRY = Object.freeze([
|
|
|
51981
52018
|
{
|
|
51982
52019
|
dataClass: "normalized_receipts",
|
|
51983
52020
|
purpose: "necessary",
|
|
51984
|
-
fields: [
|
|
52021
|
+
fields: [
|
|
52022
|
+
"ingestion.reason_codes",
|
|
52023
|
+
"webhook.signature_status",
|
|
52024
|
+
"activation.safe_error_category",
|
|
52025
|
+
"crm.safe_error_code",
|
|
52026
|
+
"form_bridge.opaque_entity_id",
|
|
52027
|
+
"form_bridge.safe_error_code"
|
|
52028
|
+
],
|
|
51985
52029
|
storage: "ordinary",
|
|
51986
52030
|
defaultRetentionDays: 30,
|
|
51987
52031
|
readSurface: "privacy_export",
|
|
@@ -52062,7 +52106,7 @@ var ANALYTICS_PRIVACY_RELATION_REGISTRY = Object.freeze([
|
|
|
52062
52106
|
`),
|
|
52063
52107
|
...relationPolicies("candidate_evidence", false, "expire", `analytics_runtime_rule_health`),
|
|
52064
52108
|
...relationPolicies("pseudonymous_identity", true, "delete", `
|
|
52065
|
-
analytics_people analytics_identity_nodes analytics_identity_edges
|
|
52109
|
+
analytics_people analytics_identity_nodes analytics_identity_edges analytics_identity_assignments
|
|
52066
52110
|
analytics_crm_person_mappings analytics_consent_current_state analytics_consent_receipts analytics_provider_customer_bindings
|
|
52067
52111
|
`),
|
|
52068
52112
|
...relationPolicies("pseudonymous_identity", true, "retain_legal", `analytics_identity_tombstones`),
|
|
@@ -52083,12 +52127,13 @@ var ANALYTICS_PRIVACY_RELATION_REGISTRY = Object.freeze([
|
|
|
52083
52127
|
analytics_connections analytics_webhook_receipts analytics_linker_tokens analytics_thorbit_connect_states
|
|
52084
52128
|
`),
|
|
52085
52129
|
...relationPolicies("access_audit", true, "anonymize", `
|
|
52086
|
-
analytics_identity_profile_access_audits
|
|
52130
|
+
analytics_identity_profile_access_audits analytics_identity_assignment_conflicts
|
|
52087
52131
|
`),
|
|
52088
52132
|
...relationPolicies("normalized_receipts", true, "anonymize", `
|
|
52089
52133
|
analytics_ingestion_receipts analytics_exports analytics_activation_destination_tests analytics_activation_delivery_attempts
|
|
52090
52134
|
analytics_crm_provisioning_receipts analytics_crm_sync_receipts analytics_crm_outbound_attempts
|
|
52091
52135
|
analytics_crm_outbound_receipts analytics_product_milestones analytics_identity_promotion_receipts
|
|
52136
|
+
analytics_form_bridge_receipts
|
|
52092
52137
|
analytics_runtime_manifest_publications analytics_experiment_receipts
|
|
52093
52138
|
analytics_revenue_setup_receipts
|
|
52094
52139
|
`),
|
|
@@ -52563,6 +52608,14 @@ async function drainAnalyticsPrivacyLifecycle(input = {}) {
|
|
|
52563
52608
|
WHERE id IN (SELECT id FROM analytics_identity_profile_access_audits a WHERE ${policyCutoff("a", "created_at")}
|
|
52564
52609
|
AND (a.person_id IS NOT NULL OR a.subject_ref_hmac <> md5('retained-audit:'||a.id::text))
|
|
52565
52610
|
ORDER BY a.created_at LIMIT $4) RETURNING id`);
|
|
52611
|
+
await run("identityAssignmentConflicts", "access_audit", `UPDATE analytics_identity_assignment_conflicts c
|
|
52612
|
+
SET identity_node_id=NULL,active_person_id=NULL,attempted_person_id=NULL,
|
|
52613
|
+
active_crm_entity_id=NULL,attempted_crm_entity_id=NULL,
|
|
52614
|
+
evidence_kind='retained_audit',resolved_at=COALESCE(c.resolved_at,$1)
|
|
52615
|
+
WHERE id IN (SELECT id FROM analytics_identity_assignment_conflicts c
|
|
52616
|
+
WHERE c.status <> 'pending' AND ${policyCutoff("c", "observed_at")}
|
|
52617
|
+
AND (c.identity_node_id IS NOT NULL OR c.active_person_id IS NOT NULL OR c.attempted_person_id IS NOT NULL)
|
|
52618
|
+
ORDER BY c.observed_at LIMIT $4) RETURNING id`);
|
|
52566
52619
|
await run("webhookPayloads", "provider_secrets", `UPDATE analytics_webhook_receipts SET payload_ciphertext=NULL
|
|
52567
52620
|
WHERE id IN (SELECT id FROM analytics_webhook_receipts WHERE payload_ciphertext IS NOT NULL AND payload_expires_at <= $1 AND $2::text IS NOT NULL AND $3::int > 0 ORDER BY payload_expires_at LIMIT $4) RETURNING id`);
|
|
52568
52621
|
await run("linkerTokens", "provider_secrets", `DELETE FROM analytics_linker_tokens l WHERE id IN
|
|
@@ -52574,6 +52627,9 @@ async function drainAnalyticsPrivacyLifecycle(input = {}) {
|
|
|
52574
52627
|
ORDER BY r.created_at LIMIT $4) RETURNING id`);
|
|
52575
52628
|
await run("productMilestones", "normalized_receipts", `DELETE FROM analytics_product_milestones m WHERE id IN
|
|
52576
52629
|
(SELECT id FROM analytics_product_milestones m WHERE ${policyCutoff("m", "occurred_at")} ORDER BY m.occurred_at LIMIT $4) RETURNING id`);
|
|
52630
|
+
await run("formBridgeReceipts", "normalized_receipts", `DELETE FROM analytics_form_bridge_receipts r WHERE id IN
|
|
52631
|
+
(SELECT r.id FROM analytics_form_bridge_receipts r JOIN analytics_form_submissions f ON f.id=r.submission_id
|
|
52632
|
+
WHERE ${joinedPolicyCutoff("r.occurred_at", "f.site_id")} ORDER BY r.occurred_at LIMIT $4) RETURNING id`);
|
|
52577
52633
|
await run("crmSyncRuns", "delivery_jobs", `DELETE FROM analytics_crm_sync_runs r WHERE sync_id IN
|
|
52578
52634
|
(SELECT sync_id FROM analytics_crm_sync_runs r WHERE r.state IN ('completed','degraded','cancelled','webhook_only')
|
|
52579
52635
|
AND ${policyCutoff("r", "created_at")} ORDER BY r.created_at LIMIT $4) RETURNING sync_id`);
|
|
@@ -53497,6 +53553,7 @@ var FormSubmissionSchema = z43.object({
|
|
|
53497
53553
|
medium: z43.string().trim().max(180).optional(),
|
|
53498
53554
|
campaign: z43.string().trim().max(240).optional(),
|
|
53499
53555
|
clickIds: z43.record(z43.string(), z43.string().trim().max(500)).optional(),
|
|
53556
|
+
idempotencyKey: z43.string().trim().min(8).max(200).optional(),
|
|
53500
53557
|
placementUrl: z43.string().url().max(3e3),
|
|
53501
53558
|
website: z43.string().max(0).optional()
|
|
53502
53559
|
}).strict();
|
|
@@ -53805,7 +53862,7 @@ function renderPublicForm(form, placementUrl) {
|
|
|
53805
53862
|
return `<label${field.type === "checkbox" ? ' class="check"' : ""}><span>${escapeHtml7(field.label)}${field.required ? " *" : ""}</span>${control}</label>`;
|
|
53806
53863
|
}).join("");
|
|
53807
53864
|
const brand = form.brand;
|
|
53808
|
-
return `<!doctype html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><style>:root{font-family:ui-sans-serif,system-ui;color:${escapeHtml7(brand.textColor)};background:${escapeHtml7(brand.backgroundColor)}}*{box-sizing:border-box}body{margin:0;padding:18px}form{display:grid;gap:14px}label{display:grid;gap:6px;font-size:13px;font-weight:650}.check{grid-template-columns:auto 1fr;align-items:center}.check span{grid-column:2}.check input{grid-column:1;grid-row:1}input,textarea,select{width:100%;min-height:44px;padding:10px 12px;border:1px solid #ccd3df;border-radius:${brand.radius}px;background:white;color:inherit;font:inherit}textarea{min-height:110px;resize:vertical}button{min-height:46px;border:0;border-radius:${brand.radius}px;color:white;background:${escapeHtml7(brand.primaryColor)};font:inherit;font-weight:750;cursor:pointer}.consent{margin:0;color:#667085;font-size:11px;line-height:1.45}.notice{display:none;padding:12px;border-radius:${brand.radius}px;background:#edf8f2;color:#17613c}.hp{position:absolute!important;left:-9999px!important}</style></head><body><form id="mcp-form">${fields}<label class="hp">Website<input name="website" autocomplete="off" tabindex="-1"></label>${form.consent_text ? `<p class="consent">${escapeHtml7(form.consent_text)}</p>` : ""}<button>${escapeHtml7(form.submit_label)}</button><div class="notice" role="status"></div></form><script>(()=>{const form=document.querySelector('#mcp-form'),notice=form.querySelector('.notice'),q=new URLSearchParams(location.search);form.addEventListener('submit',async event=>{event.preventDefault();const button=form.querySelector('button');button.disabled=true;const raw=Object.fromEntries(new FormData(form).entries()),website=String(raw.website||''),clickIds={};delete raw.website;for(const k of ['fbclid','gclid','gbraid','wbraid','ttclid','rdt_cid','msclkid']){const v=q.get(k);if(v)clickIds[k]=v}try{const response=await fetch('/analytics/forms/${escapeHtml7(form.public_id)}/submissions',{method:'POST',headers:{'content-type':'application/json'},body:JSON.stringify({data:raw,website,placementUrl:${JSON.stringify(placementUrl)},visitorId:q.get('visitor')||undefined,sessionId:q.get('session')||undefined,source:q.get('source')||undefined,medium:q.get('medium')||undefined,campaign:q.get('campaign')||undefined,clickIds})});if(!response.ok)throw new Error('submit');notice.textContent=${JSON.stringify(form.success_message)};notice.style.display='block';form.reset();${form.redirect_url ? `setTimeout(()=>{top.location.href=${JSON.stringify(form.redirect_url)}},700);` : ""}}catch{notice.textContent='Your response could not be submitted. Please try again.';notice.style.display='block'}finally{button.disabled=false}})})()</script></body></html>`;
|
|
53865
|
+
return `<!doctype html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><style>:root{font-family:ui-sans-serif,system-ui;color:${escapeHtml7(brand.textColor)};background:${escapeHtml7(brand.backgroundColor)}}*{box-sizing:border-box}body{margin:0;padding:18px}form{display:grid;gap:14px}label{display:grid;gap:6px;font-size:13px;font-weight:650}.check{grid-template-columns:auto 1fr;align-items:center}.check span{grid-column:2}.check input{grid-column:1;grid-row:1}input,textarea,select{width:100%;min-height:44px;padding:10px 12px;border:1px solid #ccd3df;border-radius:${brand.radius}px;background:white;color:inherit;font:inherit}textarea{min-height:110px;resize:vertical}button{min-height:46px;border:0;border-radius:${brand.radius}px;color:white;background:${escapeHtml7(brand.primaryColor)};font:inherit;font-weight:750;cursor:pointer}.consent{margin:0;color:#667085;font-size:11px;line-height:1.45}.notice{display:none;padding:12px;border-radius:${brand.radius}px;background:#edf8f2;color:#17613c}.hp{position:absolute!important;left:-9999px!important}</style></head><body><form id="mcp-form">${fields}<label class="hp">Website<input name="website" autocomplete="off" tabindex="-1"></label>${form.consent_text ? `<p class="consent">${escapeHtml7(form.consent_text)}</p>` : ""}<button>${escapeHtml7(form.submit_label)}</button><div class="notice" role="status"></div></form><script>(()=>{const form=document.querySelector('#mcp-form'),notice=form.querySelector('.notice'),q=new URLSearchParams(location.search),id=()=>crypto.randomUUID?crypto.randomUUID():'form_'+Date.now().toString(36)+Math.random().toString(36).slice(2);let pendingKey=null;form.addEventListener('submit',async event=>{event.preventDefault();const button=form.querySelector('button');button.disabled=true;pendingKey=pendingKey||id();const raw=Object.fromEntries(new FormData(form).entries()),website=String(raw.website||''),clickIds={};delete raw.website;for(const k of ['fbclid','gclid','gbraid','wbraid','ttclid','rdt_cid','msclkid']){const v=q.get(k);if(v)clickIds[k]=v}try{const response=await fetch('/analytics/forms/${escapeHtml7(form.public_id)}/submissions',{method:'POST',headers:{'content-type':'application/json'},body:JSON.stringify({data:raw,website,idempotencyKey:pendingKey,placementUrl:${JSON.stringify(placementUrl)},visitorId:q.get('visitor')||undefined,sessionId:q.get('session')||undefined,source:q.get('source')||undefined,medium:q.get('medium')||undefined,campaign:q.get('campaign')||undefined,clickIds})});if(!response.ok)throw new Error('submit');pendingKey=null;notice.textContent=${JSON.stringify(form.success_message)};notice.style.display='block';form.reset();${form.redirect_url ? `setTimeout(()=>{top.location.href=${JSON.stringify(form.redirect_url)}},700);` : ""}}catch{notice.textContent='Your response could not be submitted. Please try again.';notice.style.display='block'}finally{button.disabled=false}})})()</script></body></html>`;
|
|
53809
53866
|
}
|
|
53810
53867
|
analyticsApp.get(
|
|
53811
53868
|
"/health/live",
|
|
@@ -54212,163 +54269,64 @@ analyticsApp.post("/forms/:publicId/submissions", async (c) => {
|
|
|
54212
54269
|
for (const field of allowed.values())
|
|
54213
54270
|
if (field.required && (parsed.data.data[field.id] === void 0 || parsed.data.data[field.id] === ""))
|
|
54214
54271
|
return c.json({ ok: false, error: `${field.label} is required.` }, 400);
|
|
54215
|
-
const user = await getUserById(form.owner_user_id);
|
|
54216
|
-
if (!user)
|
|
54217
|
-
return c.json({ ok: false, error: "Form owner unavailable." }, 503);
|
|
54218
54272
|
const data = parsed.data.data;
|
|
54219
54273
|
const email = typeof data.email === "string" ? data.email.trim().toLowerCase() : "";
|
|
54220
54274
|
const phone = typeof data.phone === "string" ? data.phone.trim() : "";
|
|
54221
54275
|
const firstName = typeof data.first_name === "string" ? data.first_name.trim() : "";
|
|
54222
54276
|
const lastName = typeof data.last_name === "string" ? data.last_name.trim() : "";
|
|
54223
|
-
const fullName = [firstName, lastName].filter(Boolean).join(" ") || (typeof data.name === "string" ? data.name.trim() : "") ||
|
|
54224
|
-
const
|
|
54225
|
-
const
|
|
54226
|
-
const
|
|
54227
|
-
const
|
|
54228
|
-
const
|
|
54229
|
-
const existing = memoryKey ? await memoryCall("getTool", { vault: "People", path: path5 }, memoryKey) : { ok: false, error: memoryKeyError || "memory_credential_unavailable" };
|
|
54230
|
-
const props = {
|
|
54231
|
-
...existing.note?.props ?? {},
|
|
54232
|
-
type: "person",
|
|
54233
|
-
status: "active",
|
|
54234
|
-
person_name: fullName,
|
|
54235
|
-
...firstName ? { first_name: firstName } : {},
|
|
54236
|
-
...lastName ? { last_name: lastName } : {},
|
|
54237
|
-
...email ? { email } : {},
|
|
54238
|
-
...typeof data.phone === "string" && data.phone.trim() ? { phone: data.phone.trim(), text_phone: data.phone.trim() } : {},
|
|
54239
|
-
...typeof data.company === "string" && data.company.trim() ? { company: data.company.trim() } : {},
|
|
54240
|
-
attribution_site_id: form.site_id,
|
|
54241
|
-
attribution_form_id: form.id,
|
|
54242
|
-
attribution_form_name: form.name,
|
|
54243
|
-
attributed_source: parsed.data.source || "(direct)",
|
|
54244
|
-
attributed_medium: parsed.data.medium || "(none)",
|
|
54245
|
-
attributed_campaign: parsed.data.campaign || "(none)",
|
|
54246
|
-
form_fields: data,
|
|
54247
|
-
source_type: "analytics_form",
|
|
54248
|
-
source_ref: `form:${form.public_id}`,
|
|
54249
|
-
summary: `Website lead from ${form.name}`,
|
|
54250
|
-
embedding_summary: `${fullName} submitted ${form.name}`,
|
|
54251
|
-
related: [],
|
|
54252
|
-
related_vault_notes: [],
|
|
54253
|
-
embed: true,
|
|
54254
|
-
embed_priority: "normal"
|
|
54255
|
-
};
|
|
54256
|
-
const crmPayload = {
|
|
54257
|
-
vault: "People",
|
|
54258
|
-
path: path5,
|
|
54259
|
-
title: fullName,
|
|
54260
|
-
content: existing.note?.content || `# ${fullName}
|
|
54261
|
-
|
|
54262
|
-
## Identity
|
|
54263
|
-
Website lead captured through ${form.name}.
|
|
54264
|
-
|
|
54265
|
-
## Relationship
|
|
54266
|
-
Attribution is linked to Site Analytics.
|
|
54267
|
-
|
|
54268
|
-
## Known Context
|
|
54269
|
-
Submitted the published form.
|
|
54270
|
-
|
|
54271
|
-
## Interaction History
|
|
54272
|
-
- ${(/* @__PURE__ */ new Date()).toISOString()}: Form submitted.
|
|
54273
|
-
|
|
54274
|
-
## Open Loops
|
|
54275
|
-
- Review and follow up.`,
|
|
54276
|
-
props,
|
|
54277
|
-
...existing.note ? { baseRevision: existing.note.revision } : {}
|
|
54278
|
-
};
|
|
54279
|
-
const saved = memoryKey ? await memoryCall(
|
|
54280
|
-
"putTool",
|
|
54281
|
-
crmPayload,
|
|
54282
|
-
memoryKey
|
|
54283
|
-
) : { ok: false, error: memoryKeyError || "memory_credential_unavailable" };
|
|
54284
|
-
const crmDeliveryStatus = saved.ok ? "delivered" : "pending";
|
|
54285
|
-
const receipt4 = await recordAnalyticsFormSubmission({
|
|
54277
|
+
const fullName = [firstName, lastName].filter(Boolean).join(" ") || (typeof data.name === "string" ? data.name.trim() : "") || "Website visitor";
|
|
54278
|
+
const idempotencyKey4 = parsed.data.idempotencyKey ?? randomUUID38();
|
|
54279
|
+
const identitySeed = email || phone.replace(/\D/g, "") || parsed.data.visitorId || parsed.data.sessionId || idempotencyKey4;
|
|
54280
|
+
const crmEntityId = deterministicAnalyticsCrmEntityId(form.site_id, identitySeed);
|
|
54281
|
+
const observedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
54282
|
+
const bridge = await queueAnalyticsFormBridgeTransaction({
|
|
54286
54283
|
form,
|
|
54284
|
+
ownerUserId: form.owner_user_id,
|
|
54285
|
+
idempotencyKey: idempotencyKey4,
|
|
54286
|
+
crmEntityId,
|
|
54287
54287
|
visitorId: parsed.data.visitorId,
|
|
54288
54288
|
sessionId: parsed.data.sessionId,
|
|
54289
|
-
crmPersonRef,
|
|
54290
|
-
crmDeliveryStatus,
|
|
54291
54289
|
source: parsed.data.source,
|
|
54292
54290
|
medium: parsed.data.medium,
|
|
54293
54291
|
campaign: parsed.data.campaign,
|
|
54294
|
-
clickIds: parsed.data.clickIds
|
|
54295
|
-
|
|
54296
|
-
|
|
54297
|
-
|
|
54298
|
-
|
|
54299
|
-
|
|
54300
|
-
|
|
54301
|
-
|
|
54302
|
-
|
|
54303
|
-
|
|
54304
|
-
|
|
54305
|
-
|
|
54306
|
-
|
|
54307
|
-
|
|
54308
|
-
|
|
54309
|
-
|
|
54310
|
-
|
|
54311
|
-
|
|
54312
|
-
|
|
54313
|
-
|
|
54314
|
-
});
|
|
54315
|
-
}
|
|
54316
|
-
const match = {
|
|
54317
|
-
...email ? { emailSha256: createHash43("sha256").update(email).digest("hex") } : {},
|
|
54318
|
-
...phone ? {
|
|
54319
|
-
phoneSha256: createHash43("sha256").update(phone.replace(/\D/g, "")).digest("hex")
|
|
54320
|
-
} : {}
|
|
54321
|
-
};
|
|
54322
|
-
const conversionOccurredAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
54323
|
-
const activationIdentity = await resolveAnalyticsConfirmedActivationIdentity(getAnalyticsPool(), {
|
|
54324
|
-
siteId: form.site_id,
|
|
54325
|
-
subjectRef: parsed.data.visitorId,
|
|
54326
|
-
personId: identityGraph.personId
|
|
54327
|
-
});
|
|
54328
|
-
const conversion = await createAnalyticsConversion({
|
|
54329
|
-
userId: form.owner_user_id,
|
|
54330
|
-
siteId: form.site_id,
|
|
54331
|
-
pixelId: form.pixel_id,
|
|
54332
|
-
sessionId: parsed.data.sessionId,
|
|
54333
|
-
sourceEventId: `form:${receipt4.submissionId}`,
|
|
54334
|
-
conversionKind: "form_submitted",
|
|
54335
|
-
occurredAt: conversionOccurredAt,
|
|
54336
|
-
personId: activationIdentity.personId ?? void 0,
|
|
54337
|
-
activationPayloadCiphertext: activationIdentity.activationEligible && activationIdentity.personId ? encryptAnalyticsRestricted(
|
|
54338
|
-
JSON.stringify({
|
|
54339
|
-
eventId: `form:${receipt4.submissionId}`,
|
|
54340
|
-
eventName: "form_submitted",
|
|
54341
|
-
eventTime: conversionOccurredAt,
|
|
54342
|
-
actionSource: "website",
|
|
54343
|
-
sourceUrl: parsed.data.placementUrl,
|
|
54344
|
-
match,
|
|
54345
|
-
clickIds: parsed.data.clickIds ?? {},
|
|
54346
|
-
personId: activationIdentity.personId,
|
|
54347
|
-
identityTier: "confirmed",
|
|
54348
|
-
consent: { advertisingMeasurement: true },
|
|
54349
|
-
attribution: {
|
|
54350
|
-
source: parsed.data.source,
|
|
54351
|
-
medium: parsed.data.medium,
|
|
54352
|
-
campaign: parsed.data.campaign
|
|
54353
|
-
}
|
|
54354
|
-
}),
|
|
54355
|
-
"activation-payload"
|
|
54356
|
-
) : void 0
|
|
54292
|
+
clickIds: parsed.data.clickIds,
|
|
54293
|
+
occurredAt: observedAt,
|
|
54294
|
+
payloadCiphertext: encryptMemoryKey(JSON.stringify({
|
|
54295
|
+
displayName: fullName,
|
|
54296
|
+
relationshipTypes: ["prospect"],
|
|
54297
|
+
email: email || void 0,
|
|
54298
|
+
phone: phone || void 0,
|
|
54299
|
+
organizationName: typeof data.company === "string" && data.company.trim() ? data.company.trim() : void 0,
|
|
54300
|
+
submittedFields: data,
|
|
54301
|
+
visitorId: parsed.data.visitorId,
|
|
54302
|
+
sessionId: parsed.data.sessionId,
|
|
54303
|
+
clickIds: parsed.data.clickIds ?? {},
|
|
54304
|
+
placementUrl: parsed.data.placementUrl,
|
|
54305
|
+
source: {
|
|
54306
|
+
kind: "xray_form",
|
|
54307
|
+
siteId: form.site_id,
|
|
54308
|
+
formId: form.id,
|
|
54309
|
+
observedAt
|
|
54310
|
+
}
|
|
54311
|
+
}))
|
|
54357
54312
|
});
|
|
54358
54313
|
return c.json(
|
|
54359
54314
|
{
|
|
54360
54315
|
ok: true,
|
|
54361
|
-
submissionId:
|
|
54362
|
-
crmDeliveryStatus,
|
|
54363
|
-
|
|
54364
|
-
|
|
54365
|
-
|
|
54316
|
+
submissionId: bridge.submissionId,
|
|
54317
|
+
crmDeliveryStatus: "pending",
|
|
54318
|
+
bridge: {
|
|
54319
|
+
runId: bridge.bridgeRunId,
|
|
54320
|
+
crmEntityId: bridge.crmEntityId,
|
|
54321
|
+
analyticsStatus: "delivered",
|
|
54322
|
+
crmStatus: "pending"
|
|
54366
54323
|
},
|
|
54367
|
-
|
|
54324
|
+
conversion: { id: bridge.conversionId, status: "recorded" },
|
|
54325
|
+
activation: { status: "pending_identity_delivery" },
|
|
54368
54326
|
message: form.success_message,
|
|
54369
54327
|
redirectUrl: form.redirect_url
|
|
54370
54328
|
},
|
|
54371
|
-
|
|
54329
|
+
202
|
|
54372
54330
|
);
|
|
54373
54331
|
});
|
|
54374
54332
|
analyticsApp.get("/l/:shortCode", async (c) => {
|
|
@@ -56579,6 +56537,13 @@ analyticsApp.post("/sites/:siteId/identity-namespaces/:namespaceId/candidates/:a
|
|
|
56579
56537
|
});
|
|
56580
56538
|
return c.json({ ok: true, promotion }, 200, noStore);
|
|
56581
56539
|
});
|
|
56540
|
+
analyticsApp.use("/sites/:siteId/crm/*", auth4, async (c) => c.json({
|
|
56541
|
+
ok: false,
|
|
56542
|
+
error: {
|
|
56543
|
+
code: "crm_provider_unavailable",
|
|
56544
|
+
message: "External CRM provider setup and synchronization are unavailable. Use the provider-neutral /crm workspace and GET /crm/connections."
|
|
56545
|
+
}
|
|
56546
|
+
}, 410));
|
|
56582
56547
|
analyticsApp.get("/sites/:siteId/crm/capabilities", auth4, async (c) => {
|
|
56583
56548
|
await requireSite(c);
|
|
56584
56549
|
const providers = ANALYTICS_PUBLIC_CRM_PROVIDER_IDS.map((provider) => ({
|
|
@@ -57486,6 +57451,634 @@ analyticsApp.onError((error, c) => {
|
|
|
57486
57451
|
);
|
|
57487
57452
|
});
|
|
57488
57453
|
|
|
57454
|
+
// src/api/governed-relationship-routes.ts
|
|
57455
|
+
import { randomUUID as randomUUID39 } from "crypto";
|
|
57456
|
+
import { Hono as Hono37 } from "hono";
|
|
57457
|
+
import { z as z45 } from "zod";
|
|
57458
|
+
|
|
57459
|
+
// src/api/entity-domain-contract.ts
|
|
57460
|
+
var DOMAIN_VAULT_NAMES = Object.freeze({
|
|
57461
|
+
research_person: "People",
|
|
57462
|
+
research_organization: "Organizations",
|
|
57463
|
+
crm_person: "CRM People",
|
|
57464
|
+
crm_organization: "CRM Organizations"
|
|
57465
|
+
});
|
|
57466
|
+
var RESEARCH_FORBIDDEN_FIELDS = Object.freeze([
|
|
57467
|
+
"relationshipTypes",
|
|
57468
|
+
"relationship_types",
|
|
57469
|
+
"commercialLifecycle",
|
|
57470
|
+
"commercial_lifecycle",
|
|
57471
|
+
"relationshipStatus",
|
|
57472
|
+
"relationship_status",
|
|
57473
|
+
"ownerId",
|
|
57474
|
+
"owner_id",
|
|
57475
|
+
"consentState",
|
|
57476
|
+
"consent_state",
|
|
57477
|
+
"outreachState",
|
|
57478
|
+
"outreach_state",
|
|
57479
|
+
"pipelineId",
|
|
57480
|
+
"pipeline_id",
|
|
57481
|
+
"dealIds",
|
|
57482
|
+
"deal_ids",
|
|
57483
|
+
"taskIds",
|
|
57484
|
+
"task_ids",
|
|
57485
|
+
"nextTaskId",
|
|
57486
|
+
"next_task_id",
|
|
57487
|
+
"openDealValue",
|
|
57488
|
+
"open_deal_value"
|
|
57489
|
+
]);
|
|
57490
|
+
var CRM_FORBIDDEN_FIELDS = Object.freeze([
|
|
57491
|
+
"claims",
|
|
57492
|
+
"citations",
|
|
57493
|
+
"sourceEvidence",
|
|
57494
|
+
"source_evidence",
|
|
57495
|
+
"researchRoles",
|
|
57496
|
+
"research_roles",
|
|
57497
|
+
"timePeriod",
|
|
57498
|
+
"time_period",
|
|
57499
|
+
"topics",
|
|
57500
|
+
"researchSummary",
|
|
57501
|
+
"research_summary"
|
|
57502
|
+
]);
|
|
57503
|
+
var GovernedContractError = class extends Error {
|
|
57504
|
+
constructor(code, message, status = 422, details = {}) {
|
|
57505
|
+
super(message);
|
|
57506
|
+
this.code = code;
|
|
57507
|
+
this.status = status;
|
|
57508
|
+
this.details = details;
|
|
57509
|
+
this.name = "GovernedContractError";
|
|
57510
|
+
}
|
|
57511
|
+
code;
|
|
57512
|
+
status;
|
|
57513
|
+
details;
|
|
57514
|
+
};
|
|
57515
|
+
var EMAIL_ONLY = /^[^\s@]+@[^\s@]+\.[^\s@]+$/u;
|
|
57516
|
+
var VAULT_REFERENCE = /^(?:[A-Za-z][A-Za-z ]{1,80})::\S+/u;
|
|
57517
|
+
var FILE_EXTENSION = /\.(?:md|mdx|txt|json|csv|pdf|docx?|html?|ya?ml)$/iu;
|
|
57518
|
+
var WINDOWS_PATH = /^(?:[A-Za-z]:\\|\\\\)/u;
|
|
57519
|
+
var POSIX_PATH = /^(?:\.{0,2}\/|\/|~\/)/u;
|
|
57520
|
+
function displayNameIssue(value) {
|
|
57521
|
+
if (typeof value !== "string" || value.trim().length === 0) return "empty";
|
|
57522
|
+
const name = value.trim();
|
|
57523
|
+
if (EMAIL_ONLY.test(name)) return "email";
|
|
57524
|
+
if (VAULT_REFERENCE.test(name)) return "vault_reference";
|
|
57525
|
+
if (WINDOWS_PATH.test(name) || POSIX_PATH.test(name) || name.includes("/")) return "path";
|
|
57526
|
+
if (FILE_EXTENSION.test(name)) return "filename";
|
|
57527
|
+
return null;
|
|
57528
|
+
}
|
|
57529
|
+
function requireHumanDisplayName(value) {
|
|
57530
|
+
const issue = displayNameIssue(value);
|
|
57531
|
+
if (issue) {
|
|
57532
|
+
throw new GovernedContractError(
|
|
57533
|
+
issue === "empty" ? "entity_display_name_required" : "entity_display_name_invalid",
|
|
57534
|
+
issue === "empty" ? "A human display name is required." : `A ${issue.replace("_", " ")} may be retained as a locator, but cannot be the display name.`,
|
|
57535
|
+
422,
|
|
57536
|
+
{ issue }
|
|
57537
|
+
);
|
|
57538
|
+
}
|
|
57539
|
+
return value.trim();
|
|
57540
|
+
}
|
|
57541
|
+
|
|
57542
|
+
// src/api/crm-contract.ts
|
|
57543
|
+
var XRAY_ATTRIBUTION_MODELS = [
|
|
57544
|
+
"first_touch",
|
|
57545
|
+
"last_touch",
|
|
57546
|
+
"last_non_direct",
|
|
57547
|
+
"linear",
|
|
57548
|
+
"time_decay",
|
|
57549
|
+
"position_based",
|
|
57550
|
+
"custom_weighted"
|
|
57551
|
+
];
|
|
57552
|
+
var DEFAULT_XRAY_ATTRIBUTION = Object.freeze({
|
|
57553
|
+
model: "position_based",
|
|
57554
|
+
firstWeight: 0.4,
|
|
57555
|
+
middleWeight: 0.2,
|
|
57556
|
+
lastWeight: 0.4
|
|
57557
|
+
});
|
|
57558
|
+
|
|
57559
|
+
// src/api/crm-import-service.ts
|
|
57560
|
+
import { z as z44 } from "zod";
|
|
57561
|
+
var MAX_IMPORT_BYTES = 20 * 1024 * 1024;
|
|
57562
|
+
var ImportRowSchema = z44.object({
|
|
57563
|
+
rowNumber: z44.number().int().min(1),
|
|
57564
|
+
domain: z44.enum(["crm_person", "crm_organization"]),
|
|
57565
|
+
values: z44.record(z44.string().min(1).max(120), z44.unknown())
|
|
57566
|
+
}).strict();
|
|
57567
|
+
var CrmImportPreviewSchema = z44.object({
|
|
57568
|
+
idempotencyKey: z44.string().min(8).max(200),
|
|
57569
|
+
ttlMinutes: z44.number().int().min(5).max(1440).default(60),
|
|
57570
|
+
mapping: z44.record(z44.string().min(1).max(120), z44.string().min(1).max(120)),
|
|
57571
|
+
rows: z44.array(ImportRowSchema).min(1).max(5e4)
|
|
57572
|
+
}).strict();
|
|
57573
|
+
var CrmImportApplySchema = z44.object({
|
|
57574
|
+
planHandle: z44.string().min(1).max(4096),
|
|
57575
|
+
digest: z44.string().regex(/^[a-f0-9]{64}$/iu),
|
|
57576
|
+
confirmationToken: z44.string().min(8).max(500),
|
|
57577
|
+
idempotencyKey: z44.string().min(8).max(200)
|
|
57578
|
+
}).strict();
|
|
57579
|
+
function serializedBytes(value) {
|
|
57580
|
+
return Buffer.byteLength(JSON.stringify(value), "utf8");
|
|
57581
|
+
}
|
|
57582
|
+
function parseCrmImportPreview(value) {
|
|
57583
|
+
if (serializedBytes(value) > MAX_IMPORT_BYTES) {
|
|
57584
|
+
return { ok: false, code: "crm_import_too_large", message: "The import exceeds the 20 MiB preview limit." };
|
|
57585
|
+
}
|
|
57586
|
+
const parsed = CrmImportPreviewSchema.safeParse(value);
|
|
57587
|
+
if (!parsed.success) {
|
|
57588
|
+
return { ok: false, code: "crm_import_invalid", message: "Import rows must use the strict CRM People or CRM Organizations preview contract." };
|
|
57589
|
+
}
|
|
57590
|
+
return { ok: true, input: parsed.data };
|
|
57591
|
+
}
|
|
57592
|
+
function parseCrmImportApply(value) {
|
|
57593
|
+
const parsed = CrmImportApplySchema.safeParse(value);
|
|
57594
|
+
if (!parsed.success) {
|
|
57595
|
+
return { ok: false, code: "crm_import_confirmation_invalid", message: "Import apply requires the exact preview handle, digest, confirmation token, and idempotency key." };
|
|
57596
|
+
}
|
|
57597
|
+
return { ok: true, input: parsed.data };
|
|
57598
|
+
}
|
|
57599
|
+
|
|
57600
|
+
// src/api/governed-relationship-routes.ts
|
|
57601
|
+
var UuidSchema = z45.string().uuid();
|
|
57602
|
+
var ObjectSchema = z45.enum(["people", "organizations"]);
|
|
57603
|
+
var QuerySchema = z45.object({
|
|
57604
|
+
query: z45.string().trim().max(300).optional(),
|
|
57605
|
+
cursor: z45.string().max(2e3).optional(),
|
|
57606
|
+
limit: z45.coerce.number().int().min(1).max(100).default(25)
|
|
57607
|
+
}).passthrough();
|
|
57608
|
+
var MutationSchema = z45.object({
|
|
57609
|
+
idempotencyKey: z45.string().min(8).max(200),
|
|
57610
|
+
baseRevision: z45.number().int().min(0)
|
|
57611
|
+
}).passthrough();
|
|
57612
|
+
var WorkPageSchema = z45.object({ cursor: z45.string().max(2048).optional(), limit: z45.coerce.number().int().min(1).max(100).default(25) }).passthrough();
|
|
57613
|
+
var DealQuerySchema = WorkPageSchema.extend({
|
|
57614
|
+
pipelineId: z45.string().uuid().optional(),
|
|
57615
|
+
stageId: z45.string().uuid().optional(),
|
|
57616
|
+
minValue: z45.coerce.number().nonnegative().optional(),
|
|
57617
|
+
maxValue: z45.coerce.number().nonnegative().optional()
|
|
57618
|
+
});
|
|
57619
|
+
var TaskQuerySchema = WorkPageSchema.extend({
|
|
57620
|
+
query: z45.string().trim().max(300).optional(),
|
|
57621
|
+
personEntityId: z45.string().uuid().optional(),
|
|
57622
|
+
organizationEntityId: z45.string().uuid().optional(),
|
|
57623
|
+
dealId: z45.string().uuid().optional(),
|
|
57624
|
+
due: z45.enum(["overdue", "today", "week", "unscheduled"]).optional(),
|
|
57625
|
+
ownerId: z45.string().trim().max(200).optional(),
|
|
57626
|
+
status: z45.enum(["todo", "in_progress", "blocked", "done", "cancelled"]).optional()
|
|
57627
|
+
});
|
|
57628
|
+
var PipelineMutationSchema = z45.object({
|
|
57629
|
+
pipelineId: z45.string().uuid().optional(),
|
|
57630
|
+
label: z45.string().trim().min(1).max(120),
|
|
57631
|
+
baseVersion: z45.number().int().min(0),
|
|
57632
|
+
isDefault: z45.boolean().default(false),
|
|
57633
|
+
stages: z45.array(z45.object({
|
|
57634
|
+
stageId: z45.string().uuid().optional(),
|
|
57635
|
+
label: z45.string().trim().min(1).max(120),
|
|
57636
|
+
outcome: z45.enum(["open", "won", "lost"]),
|
|
57637
|
+
probability: z45.number().min(0).max(1),
|
|
57638
|
+
requiredFields: z45.array(z45.string().trim().min(1).max(120)).max(100).default([]),
|
|
57639
|
+
allowedNextStageIds: z45.array(z45.string().uuid()).max(100).default([])
|
|
57640
|
+
}).strict()).min(2).max(100)
|
|
57641
|
+
}).strict();
|
|
57642
|
+
var researchTools = {
|
|
57643
|
+
people: { search: "researchPersonSearchTool", get: "researchPersonGetTool", write: "researchPersonCaptureTool" },
|
|
57644
|
+
organizations: { search: "researchOrganizationSearchTool", get: "researchOrganizationGetTool", write: "researchOrganizationCaptureTool" }
|
|
57645
|
+
};
|
|
57646
|
+
var crmTools = {
|
|
57647
|
+
people: { search: "crmPersonSearchTool", get: "crmPersonGetTool", write: "crmUpsertPersonTool" },
|
|
57648
|
+
organizations: { search: "crmOrganizationSearchTool", get: "crmOrganizationGetTool", write: "crmUpsertOrganizationTool" }
|
|
57649
|
+
};
|
|
57650
|
+
function safeFailure2(message, code = "relationship_unavailable") {
|
|
57651
|
+
return { ok: false, error: { code, message, requestId: randomUUID39(), retryable: code === "relationship_unavailable" } };
|
|
57652
|
+
}
|
|
57653
|
+
function resultStatus(result3) {
|
|
57654
|
+
const code = String(result3.code ?? "");
|
|
57655
|
+
if (/permission|owner_confirmation/iu.test(code)) return 403;
|
|
57656
|
+
if (/not_found/iu.test(code)) return 404;
|
|
57657
|
+
if (/conflict|digest_mismatch/iu.test(code)) return 409;
|
|
57658
|
+
if (/expired/iu.test(code)) return 410;
|
|
57659
|
+
if (/invalid|forbidden|mismatch|required/iu.test(code)) return 422;
|
|
57660
|
+
return 502;
|
|
57661
|
+
}
|
|
57662
|
+
async function keyFor(c) {
|
|
57663
|
+
const { key: key3, error } = await getOrCreateUserMemoryKey(c.get("user"));
|
|
57664
|
+
if (!key3) return c.json(safeFailure2(error ?? "Memory is unavailable."), 503);
|
|
57665
|
+
return key3;
|
|
57666
|
+
}
|
|
57667
|
+
async function call(c, tool, input, success = 200) {
|
|
57668
|
+
const key3 = await keyFor(c);
|
|
57669
|
+
if (typeof key3 !== "string") return key3;
|
|
57670
|
+
const result3 = await memoryCall(tool, input, key3);
|
|
57671
|
+
c.header("Cache-Control", "private, no-store");
|
|
57672
|
+
if (!result3.ok) {
|
|
57673
|
+
const status = resultStatus(result3);
|
|
57674
|
+
return c.json(safeFailure2(
|
|
57675
|
+
status === 502 ? "The governed relationship service is temporarily unavailable." : String(result3.message ?? result3.error ?? "The request was rejected."),
|
|
57676
|
+
typeof result3.code === "string" ? result3.code : "relationship_unavailable"
|
|
57677
|
+
), status);
|
|
57678
|
+
}
|
|
57679
|
+
return c.json(result3, success);
|
|
57680
|
+
}
|
|
57681
|
+
async function readResult(c, tool, input) {
|
|
57682
|
+
const key3 = await keyFor(c);
|
|
57683
|
+
if (typeof key3 !== "string") return key3;
|
|
57684
|
+
const result3 = await memoryCall(tool, input, key3);
|
|
57685
|
+
c.header("Cache-Control", "private, no-store");
|
|
57686
|
+
if (!result3.ok) {
|
|
57687
|
+
const status = resultStatus(result3);
|
|
57688
|
+
return c.json(safeFailure2(status === 502 ? "The governed relationship service is temporarily unavailable." : String(result3.message ?? result3.error ?? "The request was rejected."), typeof result3.code === "string" ? result3.code : "relationship_unavailable"), status);
|
|
57689
|
+
}
|
|
57690
|
+
return result3;
|
|
57691
|
+
}
|
|
57692
|
+
function workItems(result3) {
|
|
57693
|
+
return (Array.isArray(result3.items) ? result3.items : []).filter((item) => Boolean(item && typeof item === "object" && typeof item.workId === "string"));
|
|
57694
|
+
}
|
|
57695
|
+
function pageInfo(result3) {
|
|
57696
|
+
const page3 = result3.pageInfo && typeof result3.pageInfo === "object" ? result3.pageInfo : {};
|
|
57697
|
+
return { endCursor: typeof page3.endCursor === "string" ? page3.endCursor : null, hasNextPage: page3.hasNextPage === true };
|
|
57698
|
+
}
|
|
57699
|
+
function stringProp(props, key3) {
|
|
57700
|
+
const value = props[key3];
|
|
57701
|
+
return typeof value === "string" && value.trim() ? value : null;
|
|
57702
|
+
}
|
|
57703
|
+
function numberProp(props, key3) {
|
|
57704
|
+
const value = props[key3];
|
|
57705
|
+
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
57706
|
+
}
|
|
57707
|
+
function dealView(item) {
|
|
57708
|
+
const fields = item.dealState?.fields ?? item.props;
|
|
57709
|
+
const partyId = stringProp(fields, "party") ?? item.entities[0]?.entityId ?? "";
|
|
57710
|
+
const party = item.entities.find((entity) => entity.entityId === partyId) ?? item.entities[0];
|
|
57711
|
+
return {
|
|
57712
|
+
dealId: item.workId,
|
|
57713
|
+
title: item.title,
|
|
57714
|
+
pipelineId: item.dealState?.pipelineId ?? stringProp(item.props, "pipeline_id") ?? "",
|
|
57715
|
+
stageId: item.dealState?.stageId ?? stringProp(item.props, "stage_id") ?? "",
|
|
57716
|
+
revision: item.revision,
|
|
57717
|
+
probability: item.dealState?.probability ?? numberProp(item.props, "probability") ?? 0,
|
|
57718
|
+
value: numberProp(item.props, "value"),
|
|
57719
|
+
currency: stringProp(item.props, "currency"),
|
|
57720
|
+
party: { entityId: party?.entityId ?? partyId, kind: party?.domain.endsWith("_organization") ? "organization" : "person", label: party?.displayName ?? partyId },
|
|
57721
|
+
enteredAt: stringProp(fields, "entered_at") ?? item.createdAt,
|
|
57722
|
+
lastActivityAt: stringProp(item.props, "last_activity_at"),
|
|
57723
|
+
nextTask: null,
|
|
57724
|
+
influencedSource: stringProp(item.props, "influenced_source") ? { label: stringProp(item.props, "influenced_source"), evidenceRef: stringProp(item.props, "influenced_evidence_ref") } : null,
|
|
57725
|
+
fields
|
|
57726
|
+
};
|
|
57727
|
+
}
|
|
57728
|
+
function taskView(item) {
|
|
57729
|
+
const person = item.entities.find((entity) => entity.domain === "crm_person");
|
|
57730
|
+
const organization = item.entities.find((entity) => entity.domain === "crm_organization");
|
|
57731
|
+
const dealId = stringProp(item.props, "deal_id");
|
|
57732
|
+
return {
|
|
57733
|
+
taskId: item.workId,
|
|
57734
|
+
title: item.title,
|
|
57735
|
+
status: stringProp(item.props, "status") ?? "todo",
|
|
57736
|
+
dueAt: stringProp(item.props, "due"),
|
|
57737
|
+
ownerId: stringProp(item.props, "owner_id"),
|
|
57738
|
+
canonicalHref: stringProp(item.props, "canonical_href"),
|
|
57739
|
+
person: person ? { entityId: person.entityId, label: person.displayName } : null,
|
|
57740
|
+
organization: organization ? { entityId: organization.entityId, label: organization.displayName } : null,
|
|
57741
|
+
deal: dealId ? { dealId, title: stringProp(item.props, "deal_title") ?? dealId } : null,
|
|
57742
|
+
sourceLabel: stringProp(item.props, "source_label") ?? "Canonical Tasks",
|
|
57743
|
+
updatedAt: item.updatedAt
|
|
57744
|
+
};
|
|
57745
|
+
}
|
|
57746
|
+
function parsedObject(c) {
|
|
57747
|
+
const parsed = ObjectSchema.safeParse(c.req.param("object"));
|
|
57748
|
+
return parsed.success ? parsed.data : null;
|
|
57749
|
+
}
|
|
57750
|
+
var researchApp = new Hono37();
|
|
57751
|
+
researchApp.use("*", createApiKeyAuth());
|
|
57752
|
+
for (const object2 of ["people", "organizations"]) {
|
|
57753
|
+
researchApp.get(`/${object2}`, async (c) => {
|
|
57754
|
+
const query = QuerySchema.safeParse(c.req.query());
|
|
57755
|
+
if (!query.success) return c.json(safeFailure2("The Research filters are invalid.", "invalid_request"), 400);
|
|
57756
|
+
return call(c, researchTools[object2].search, query.data);
|
|
57757
|
+
});
|
|
57758
|
+
researchApp.post(`/${object2}`, async (c) => {
|
|
57759
|
+
const body3 = MutationSchema.safeParse(await c.req.json().catch(() => null));
|
|
57760
|
+
if (!body3.success) return c.json(safeFailure2("Research capture requires revision and idempotency.", "invalid_request"), 400);
|
|
57761
|
+
try {
|
|
57762
|
+
requireHumanDisplayName(body3.data.displayName);
|
|
57763
|
+
} catch (error) {
|
|
57764
|
+
return c.json(safeFailure2(error.message, "entity_display_name_invalid"), 422);
|
|
57765
|
+
}
|
|
57766
|
+
return call(c, researchTools[object2].write, body3.data, 201);
|
|
57767
|
+
});
|
|
57768
|
+
}
|
|
57769
|
+
researchApp.get("/:object/:entityId", async (c) => {
|
|
57770
|
+
const object2 = parsedObject(c);
|
|
57771
|
+
const entityId = UuidSchema.safeParse(c.req.param("entityId"));
|
|
57772
|
+
if (!object2 || !entityId.success) return c.json(safeFailure2("The Research record reference is invalid.", "invalid_request"), 400);
|
|
57773
|
+
return call(c, researchTools[object2].get, { entityId: entityId.data });
|
|
57774
|
+
});
|
|
57775
|
+
var crmApp = new Hono37();
|
|
57776
|
+
crmApp.use("*", createApiKeyAuth());
|
|
57777
|
+
crmApp.get("/summary", async (c) => {
|
|
57778
|
+
const generatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
57779
|
+
const [activityResult, taskResult, dealResult, peopleResult, organizationResult] = await Promise.all([
|
|
57780
|
+
readResult(c, "crmWorkSearchTool", { objectKind: "activity", limit: 25 }),
|
|
57781
|
+
readResult(c, "crmWorkSearchTool", { objectKind: "task", limit: 100 }),
|
|
57782
|
+
readResult(c, "crmWorkSearchTool", { objectKind: "deal", limit: 100 }),
|
|
57783
|
+
readResult(c, "crmPersonSearchTool", { limit: 100 }),
|
|
57784
|
+
readResult(c, "crmOrganizationSearchTool", { limit: 100 })
|
|
57785
|
+
]);
|
|
57786
|
+
const failed = [activityResult, taskResult, dealResult, peopleResult, organizationResult].find((result3) => result3 instanceof Response);
|
|
57787
|
+
if (failed instanceof Response) return failed;
|
|
57788
|
+
const activities = workItems(activityResult);
|
|
57789
|
+
const tasks = workItems(taskResult);
|
|
57790
|
+
const dealItems = workItems(dealResult);
|
|
57791
|
+
const deals = dealItems.map(dealView);
|
|
57792
|
+
const people = Array.isArray(peopleResult.items) ? peopleResult.items : [];
|
|
57793
|
+
const organizations = Array.isArray(organizationResult.items) ? organizationResult.items : [];
|
|
57794
|
+
const dueNow = Date.now();
|
|
57795
|
+
const recentActivity = Object.values(activities.reduce((groups, item) => {
|
|
57796
|
+
const occurredAt = stringProp(item.props, "occurred_at") ?? item.updatedAt;
|
|
57797
|
+
const date2 = occurredAt.slice(0, 10);
|
|
57798
|
+
groups[date2] ??= { date: date2, items: [] };
|
|
57799
|
+
const rawKind = stringProp(item.props, "activity_type") ?? "note";
|
|
57800
|
+
const kind = rawKind === "form_submission" ? "form" : rawKind === "calendar_event" ? "calendar" : rawKind === "conversion" ? "conversion" : "communication";
|
|
57801
|
+
groups[date2].items.push({ activityId: item.workId, kind, occurredAt, summary: item.title, sourceLabel: stringProp(item.props, "source_label") ?? "Native CRM", xrayEvidenceRef: stringProp(item.props, "xray_evidence_ref") });
|
|
57802
|
+
return groups;
|
|
57803
|
+
}, {}));
|
|
57804
|
+
return c.json({
|
|
57805
|
+
ok: true,
|
|
57806
|
+
kpis: [
|
|
57807
|
+
{ key: "active_relationships", label: "Active relationships", value: people.length + organizations.length, unit: "count" },
|
|
57808
|
+
{ key: "open_pipeline", label: "Open pipeline", value: dealItems.filter((deal) => deal.dealState?.outcome === "open").reduce((sum2, deal) => sum2 + (numberProp(deal.props, "value") ?? 0), 0), unit: "currency" },
|
|
57809
|
+
{ key: "followups_due", label: "Follow-ups due", value: tasks.filter((task) => {
|
|
57810
|
+
const due = stringProp(task.props, "due");
|
|
57811
|
+
return Boolean(due && Date.parse(due) <= dueNow && !["done", "cancelled"].includes(stringProp(task.props, "status") ?? "todo"));
|
|
57812
|
+
}).length, unit: "count" },
|
|
57813
|
+
{ key: "xray_revenue", label: "X-Ray revenue", value: 0, unit: "currency" }
|
|
57814
|
+
],
|
|
57815
|
+
visuals: [
|
|
57816
|
+
{ key: "source_revenue", model: DEFAULT_XRAY_ATTRIBUTION.model, evidenceClass: "observed", unit: "currency", rows: [] },
|
|
57817
|
+
{ key: "pipeline_velocity", model: null, evidenceClass: null, unit: "days", rows: [] },
|
|
57818
|
+
{ key: "lifecycle_movement", model: null, evidenceClass: null, unit: "count", rows: [] },
|
|
57819
|
+
{ key: "data_health", model: null, evidenceClass: null, unit: "count", rows: [] }
|
|
57820
|
+
],
|
|
57821
|
+
qualityCounts: {},
|
|
57822
|
+
recentActivity,
|
|
57823
|
+
activityPageInfo: pageInfo(activityResult),
|
|
57824
|
+
freshness: { generatedAt, sourceRevision: "memory-live", xrayObservedAt: null },
|
|
57825
|
+
xray: { state: "unavailable", reason: "No X-Ray site context was selected. CRM remains available." }
|
|
57826
|
+
});
|
|
57827
|
+
});
|
|
57828
|
+
for (const object2 of ["people", "organizations"]) {
|
|
57829
|
+
crmApp.get(`/${object2}`, async (c) => {
|
|
57830
|
+
const query = QuerySchema.safeParse(c.req.query());
|
|
57831
|
+
if (!query.success) return c.json(safeFailure2("The CRM filters are invalid.", "invalid_request"), 400);
|
|
57832
|
+
return call(c, crmTools[object2].search, query.data);
|
|
57833
|
+
});
|
|
57834
|
+
crmApp.post(`/${object2}`, async (c) => {
|
|
57835
|
+
const body3 = MutationSchema.safeParse(await c.req.json().catch(() => null));
|
|
57836
|
+
if (!body3.success) return c.json(safeFailure2("CRM creation requires revision and idempotency.", "invalid_request"), 400);
|
|
57837
|
+
try {
|
|
57838
|
+
requireHumanDisplayName(body3.data.displayName);
|
|
57839
|
+
} catch (error) {
|
|
57840
|
+
return c.json(safeFailure2(error.message, "entity_display_name_invalid"), 422);
|
|
57841
|
+
}
|
|
57842
|
+
if (!Array.isArray(body3.data.relationshipTypes) || body3.data.relationshipTypes.length === 0) {
|
|
57843
|
+
return c.json(safeFailure2("At least one relationship type is required.", "crm_relationship_type_required"), 422);
|
|
57844
|
+
}
|
|
57845
|
+
return call(c, crmTools[object2].write, body3.data, 201);
|
|
57846
|
+
});
|
|
57847
|
+
}
|
|
57848
|
+
crmApp.get("/connections", (c) => {
|
|
57849
|
+
c.header("Cache-Control", "private, no-store");
|
|
57850
|
+
return c.json({
|
|
57851
|
+
ok: true,
|
|
57852
|
+
capabilities: [
|
|
57853
|
+
{ capabilityId: "external_crm_sync", state: "unavailable", reason: "No external CRM provider has passed the release readiness contract.", providerMutationAvailable: false, publicTools: [] },
|
|
57854
|
+
{ capabilityId: "payment_enrichment", state: "unproven", reason: "Stripe is not part of the native CRM release.", providerMutationAvailable: false, publicTools: [] }
|
|
57855
|
+
],
|
|
57856
|
+
freshness: { generatedAt: (/* @__PURE__ */ new Date()).toISOString(), sourceRevision: "provider-neutral-v1", xrayObservedAt: null }
|
|
57857
|
+
});
|
|
57858
|
+
});
|
|
57859
|
+
crmApp.get("/deals", async (c) => {
|
|
57860
|
+
const query = DealQuerySchema.safeParse(c.req.query());
|
|
57861
|
+
if (!query.success || query.data.minValue != null && query.data.maxValue != null && query.data.minValue > query.data.maxValue) return c.json(safeFailure2("The deal filters are invalid.", "invalid_request"), 400);
|
|
57862
|
+
const result3 = await readResult(c, "crmWorkSearchTool", {
|
|
57863
|
+
objectKind: "deal",
|
|
57864
|
+
cursor: query.data.cursor,
|
|
57865
|
+
limit: query.data.limit,
|
|
57866
|
+
pipelineId: query.data.pipelineId,
|
|
57867
|
+
stageIds: query.data.stageId ? [query.data.stageId] : void 0,
|
|
57868
|
+
minValue: query.data.minValue,
|
|
57869
|
+
maxValue: query.data.maxValue
|
|
57870
|
+
});
|
|
57871
|
+
if (result3 instanceof Response) return result3;
|
|
57872
|
+
const pipelines = await readResult(c, "crmPipelineListTool", {});
|
|
57873
|
+
if (pipelines instanceof Response) return pipelines;
|
|
57874
|
+
return c.json({ ok: true, items: workItems(result3).map(dealView), pipelines: Array.isArray(pipelines.pipelines) ? pipelines.pipelines : [], pageInfo: pageInfo(result3), freshness: { generatedAt: (/* @__PURE__ */ new Date()).toISOString(), sourceRevision: "memory-live" } });
|
|
57875
|
+
});
|
|
57876
|
+
crmApp.get("/deals/:dealId", async (c) => {
|
|
57877
|
+
const dealId = UuidSchema.safeParse(c.req.param("dealId"));
|
|
57878
|
+
if (!dealId.success) return c.json(safeFailure2("The deal reference is invalid.", "invalid_request"), 400);
|
|
57879
|
+
const result3 = await readResult(c, "crmWorkSearchTool", { objectKind: "deal", workId: dealId.data, limit: 1 });
|
|
57880
|
+
if (result3 instanceof Response) return result3;
|
|
57881
|
+
const item = workItems(result3)[0];
|
|
57882
|
+
if (!item) return c.json(safeFailure2("The governed deal was not found.", "entity_not_found"), 404);
|
|
57883
|
+
const pipelines = await readResult(c, "crmPipelineListTool", {});
|
|
57884
|
+
if (pipelines instanceof Response) return pipelines;
|
|
57885
|
+
const pipeline = (Array.isArray(pipelines.pipelines) ? pipelines.pipelines : []).find((value) => Boolean(value && typeof value === "object" && value.pipelineId === item.dealState?.pipelineId));
|
|
57886
|
+
if (!pipeline) return c.json(safeFailure2("The governed pipeline for this deal was not found.", "pipeline_not_found"), 404);
|
|
57887
|
+
const partyId = stringProp(item.dealState?.fields ?? item.props, "party");
|
|
57888
|
+
const [activityResult, taskResult] = await Promise.all([
|
|
57889
|
+
readResult(c, "crmWorkSearchTool", { objectKind: "activity", ...partyId ? { entityId: partyId } : {}, limit: 100 }),
|
|
57890
|
+
readResult(c, "crmWorkSearchTool", { objectKind: "task", dealId: dealId.data, limit: 100 })
|
|
57891
|
+
]);
|
|
57892
|
+
if (activityResult instanceof Response) return activityResult;
|
|
57893
|
+
if (taskResult instanceof Response) return taskResult;
|
|
57894
|
+
const activity = workItems(activityResult).map((activityItem) => ({
|
|
57895
|
+
activityId: activityItem.workId,
|
|
57896
|
+
occurredAt: stringProp(activityItem.props, "occurred_at") ?? activityItem.updatedAt,
|
|
57897
|
+
summary: activityItem.title,
|
|
57898
|
+
sourceLabel: stringProp(activityItem.props, "source_label") ?? "Native CRM"
|
|
57899
|
+
}));
|
|
57900
|
+
const tasks = workItems(taskResult).map(taskView).map((task) => ({ taskId: task.taskId, title: task.title, status: task.status, dueAt: task.dueAt, canonicalHref: task.canonicalHref }));
|
|
57901
|
+
return c.json({ ok: true, deal: dealView(item), pipeline, activity, tasks });
|
|
57902
|
+
});
|
|
57903
|
+
crmApp.get("/tasks", async (c) => {
|
|
57904
|
+
const query = TaskQuerySchema.safeParse(c.req.query());
|
|
57905
|
+
if (!query.success) return c.json(safeFailure2("The task filters are invalid.", "invalid_request"), 400);
|
|
57906
|
+
const now = /* @__PURE__ */ new Date();
|
|
57907
|
+
const startToday = new Date(now);
|
|
57908
|
+
startToday.setHours(0, 0, 0, 0);
|
|
57909
|
+
const endToday = new Date(startToday);
|
|
57910
|
+
endToday.setDate(endToday.getDate() + 1);
|
|
57911
|
+
const endWeek = new Date(startToday);
|
|
57912
|
+
endWeek.setDate(endWeek.getDate() + 7);
|
|
57913
|
+
const dueAfter = query.data.due === "today" || query.data.due === "week" ? startToday.toISOString() : void 0;
|
|
57914
|
+
const dueBefore = query.data.due === "overdue" ? startToday.toISOString() : query.data.due === "today" ? endToday.toISOString() : query.data.due === "week" ? endWeek.toISOString() : void 0;
|
|
57915
|
+
const entityIds = [query.data.personEntityId, query.data.organizationEntityId].filter((value) => Boolean(value));
|
|
57916
|
+
const result3 = await readResult(c, "crmWorkSearchTool", {
|
|
57917
|
+
objectKind: "task",
|
|
57918
|
+
cursor: query.data.cursor,
|
|
57919
|
+
limit: query.data.limit,
|
|
57920
|
+
query: query.data.query || void 0,
|
|
57921
|
+
entityIds: entityIds.length ? entityIds : void 0,
|
|
57922
|
+
dealId: query.data.dealId,
|
|
57923
|
+
taskOwnerId: query.data.ownerId || void 0,
|
|
57924
|
+
taskStatuses: query.data.status ? [query.data.status] : void 0,
|
|
57925
|
+
dueAfter,
|
|
57926
|
+
dueBefore,
|
|
57927
|
+
dueUnscheduled: query.data.due === "unscheduled" || void 0
|
|
57928
|
+
});
|
|
57929
|
+
if (result3 instanceof Response) return result3;
|
|
57930
|
+
return c.json({ ok: true, items: workItems(result3).map(taskView), pageInfo: pageInfo(result3), facets: {}, authority: "canonical_tasks", freshness: { generatedAt: (/* @__PURE__ */ new Date()).toISOString(), sourceRevision: "memory-live" } });
|
|
57931
|
+
});
|
|
57932
|
+
crmApp.get("/quality/:queue?", (c) => call(c, "crmQualityListTool", { ...c.req.param("queue") ? { queue: c.req.param("queue") } : {} }));
|
|
57933
|
+
crmApp.get("/audit", (c) => {
|
|
57934
|
+
c.header("Cache-Control", "private, no-store");
|
|
57935
|
+
return c.json({ ok: true, items: [], pageInfo: { endCursor: null, hasNextPage: false }, facets: {}, freshness: { generatedAt: (/* @__PURE__ */ new Date()).toISOString(), sourceRevision: "memory-live", xrayObservedAt: null } });
|
|
57936
|
+
});
|
|
57937
|
+
crmApp.get("/pipelines", async (c) => {
|
|
57938
|
+
const result3 = await readResult(c, "crmPipelineListTool", {});
|
|
57939
|
+
if (result3 instanceof Response) return result3;
|
|
57940
|
+
return c.json({ ...result3, freshness: { generatedAt: (/* @__PURE__ */ new Date()).toISOString(), sourceRevision: "memory-live", xrayObservedAt: null } });
|
|
57941
|
+
});
|
|
57942
|
+
crmApp.post("/pipelines", async (c) => {
|
|
57943
|
+
const body3 = PipelineMutationSchema.safeParse(await c.req.json().catch(() => null));
|
|
57944
|
+
if (!body3.success) return c.json(safeFailure2("The native CRM pipeline configuration is invalid.", "invalid_request"), 400);
|
|
57945
|
+
return call(c, "crmPipelineUpsertTool", body3.data, 201);
|
|
57946
|
+
});
|
|
57947
|
+
crmApp.get("/:object/:entityId", async (c) => {
|
|
57948
|
+
const object2 = parsedObject(c);
|
|
57949
|
+
const entityId = UuidSchema.safeParse(c.req.param("entityId"));
|
|
57950
|
+
if (!object2 || !entityId.success) return c.json(safeFailure2("The CRM record reference is invalid.", "invalid_request"), 400);
|
|
57951
|
+
return call(c, crmTools[object2].get, { entityId: entityId.data });
|
|
57952
|
+
});
|
|
57953
|
+
crmApp.patch("/:object/:entityId", async (c) => {
|
|
57954
|
+
const object2 = parsedObject(c);
|
|
57955
|
+
const entityId = UuidSchema.safeParse(c.req.param("entityId"));
|
|
57956
|
+
const body3 = MutationSchema.safeParse(await c.req.json().catch(() => null));
|
|
57957
|
+
if (!object2 || !entityId.success || !body3.success) return c.json(safeFailure2("The CRM update is invalid.", "invalid_request"), 400);
|
|
57958
|
+
return call(c, crmTools[object2].write, { ...body3.data, entityId: entityId.data });
|
|
57959
|
+
});
|
|
57960
|
+
crmApp.get("/people/:entityId/activity", async (c) => {
|
|
57961
|
+
const entityId = UuidSchema.safeParse(c.req.param("entityId"));
|
|
57962
|
+
if (!entityId.success) return c.json(safeFailure2("The CRM record reference is invalid.", "invalid_request"), 400);
|
|
57963
|
+
const query = WorkPageSchema.safeParse(c.req.query());
|
|
57964
|
+
if (!query.success) return c.json(safeFailure2("The CRM activity filters are invalid.", "invalid_request"), 400);
|
|
57965
|
+
const result3 = await readResult(c, "crmWorkSearchTool", { objectKind: "activity", entityId: entityId.data, cursor: query.data.cursor, limit: query.data.limit });
|
|
57966
|
+
if (result3 instanceof Response) return result3;
|
|
57967
|
+
return c.json({ ok: true, items: workItems(result3).map((item) => ({ activityId: item.workId, occurredAt: stringProp(item.props, "occurred_at") ?? item.updatedAt, summary: item.title, sourceLabel: stringProp(item.props, "source_label") ?? "Native CRM", content: item.content })), pageInfo: pageInfo(result3), facets: {}, freshness: { generatedAt: (/* @__PURE__ */ new Date()).toISOString(), sourceRevision: "memory-live" } });
|
|
57968
|
+
});
|
|
57969
|
+
crmApp.get("/people/:entityId/attribution", (c) => {
|
|
57970
|
+
const entityId = UuidSchema.safeParse(c.req.param("entityId"));
|
|
57971
|
+
if (!entityId.success) return c.json(safeFailure2("The CRM record reference is invalid.", "invalid_request"), 400);
|
|
57972
|
+
c.header("Cache-Control", "private, no-store");
|
|
57973
|
+
return c.json({ ok: true, entityId: entityId.data, selectedModel: DEFAULT_XRAY_ATTRIBUTION.model, availableModels: XRAY_ATTRIBUTION_MODELS, observed: [], reported: [], exactPaths: [], originalTouch: null, latestTouch: null, xray: { state: "unavailable", reason: "No stable X-Ray evidence is linked to this CRM record." } });
|
|
57974
|
+
});
|
|
57975
|
+
crmApp.post("/imports/preview", async (c) => {
|
|
57976
|
+
const body3 = parseCrmImportPreview(await c.req.json().catch(() => null));
|
|
57977
|
+
if (!body3.ok) return c.json(safeFailure2(body3.message, body3.code), body3.code === "crm_import_too_large" ? 413 : 400);
|
|
57978
|
+
return call(c, "crmImportPreviewTool", body3.input, 201);
|
|
57979
|
+
});
|
|
57980
|
+
crmApp.post("/imports/:importId/confirm", async (c) => {
|
|
57981
|
+
const importId = UuidSchema.safeParse(c.req.param("importId"));
|
|
57982
|
+
const body3 = parseCrmImportApply(await c.req.json().catch(() => null));
|
|
57983
|
+
if (!importId.success || !body3.ok) return c.json(safeFailure2(body3.ok ? "The import identifier is invalid." : body3.message, body3.ok ? "invalid_request" : body3.code), 400);
|
|
57984
|
+
return call(c, "crmImportApplyTool", { ...body3.input, importId: importId.data });
|
|
57985
|
+
});
|
|
57986
|
+
crmApp.get("/imports/:importId", (c) => c.json({ ok: false, error: { code: "import_status_use_receipt", message: "Use the immutable preview/apply receipt returned by the governed import.", requestId: randomUUID39(), retryable: false } }, 404));
|
|
57987
|
+
crmApp.post("/counterparts/preview", async (c) => {
|
|
57988
|
+
const body3 = MutationSchema.omit({ baseRevision: true }).safeParse(await c.req.json().catch(() => null));
|
|
57989
|
+
if (!body3.success) return c.json(safeFailure2("The counterpart preview is invalid.", "invalid_request"), 400);
|
|
57990
|
+
return call(c, "crmCounterpartPreviewTool", body3.data, 201);
|
|
57991
|
+
});
|
|
57992
|
+
crmApp.post("/counterparts/:planId/apply", async (c) => {
|
|
57993
|
+
const body3 = MutationSchema.omit({ baseRevision: true }).safeParse(await c.req.json().catch(() => null));
|
|
57994
|
+
if (!body3.success) return c.json(safeFailure2("The counterpart apply request is invalid.", "invalid_request"), 400);
|
|
57995
|
+
return call(c, "crmCounterpartApplyTool", { ...body3.data, planId: c.req.param("planId") });
|
|
57996
|
+
});
|
|
57997
|
+
crmApp.post("/merges/preview", async (c) => {
|
|
57998
|
+
const body3 = MutationSchema.omit({ baseRevision: true }).safeParse(await c.req.json().catch(() => null));
|
|
57999
|
+
if (!body3.success) return c.json(safeFailure2("The merge preview is invalid.", "invalid_request"), 400);
|
|
58000
|
+
return call(c, "crmMergePreviewTool", body3.data, 201);
|
|
58001
|
+
});
|
|
58002
|
+
crmApp.post("/merges/:mergeId/apply", (c) => c.json(safeFailure2("Merge apply is disabled until owner authorization Q-004 is recorded.", "crm_owner_confirmation_required"), 403));
|
|
58003
|
+
crmApp.post("/deals/:dealId/transitions", async (c) => {
|
|
58004
|
+
const body3 = MutationSchema.safeParse(await c.req.json().catch(() => null));
|
|
58005
|
+
if (!body3.success) return c.json(safeFailure2("The deal transition is invalid.", "invalid_request"), 400);
|
|
58006
|
+
return call(c, "crmDealTransitionTool", { ...body3.data, dealId: c.req.param("dealId") });
|
|
58007
|
+
});
|
|
58008
|
+
|
|
58009
|
+
// src/api/crm-bridge-service.ts
|
|
58010
|
+
import { createHash as createHash44 } from "crypto";
|
|
58011
|
+
var CrmBridgeError = class extends Error {
|
|
58012
|
+
constructor(code, message) {
|
|
58013
|
+
super(message);
|
|
58014
|
+
this.code = code;
|
|
58015
|
+
this.name = "CrmBridgeError";
|
|
58016
|
+
}
|
|
58017
|
+
code;
|
|
58018
|
+
};
|
|
58019
|
+
function stableChildId(parentId, suffix2) {
|
|
58020
|
+
const bytes2 = Buffer.from(createHash44("sha256").update(`${parentId}:${suffix2}`).digest().subarray(0, 16));
|
|
58021
|
+
bytes2[6] = bytes2[6] & 15 | 80;
|
|
58022
|
+
bytes2[8] = bytes2[8] & 63 | 128;
|
|
58023
|
+
const hex = bytes2.toString("hex");
|
|
58024
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
58025
|
+
}
|
|
58026
|
+
function validateCrmFormBridgePayload(payload) {
|
|
58027
|
+
if (!payload.bridgeRunId || !payload.crmEntityId)
|
|
58028
|
+
throw new CrmBridgeError("bridge_identity_required", "Bridge run and CRM entity IDs are required.");
|
|
58029
|
+
requireHumanDisplayName(payload.displayName);
|
|
58030
|
+
if (payload.relationshipTypes.length === 0)
|
|
58031
|
+
throw new CrmBridgeError("relationship_type_required", "A managed relationship type is required.");
|
|
58032
|
+
if (payload.source.kind !== "xray_form" || !payload.source.siteId || !payload.source.formId || !payload.source.submissionId)
|
|
58033
|
+
throw new CrmBridgeError("bridge_source_invalid", "The X-Ray form source receipt is incomplete.");
|
|
58034
|
+
return payload;
|
|
58035
|
+
}
|
|
58036
|
+
async function applyCrmFormBridge(rawPayload, writer) {
|
|
58037
|
+
const payload = validateCrmFormBridgePayload(rawPayload);
|
|
58038
|
+
const person = await writer.upsertPerson({
|
|
58039
|
+
entityId: payload.crmEntityId,
|
|
58040
|
+
idempotencyKey: `${payload.bridgeRunId}:person`,
|
|
58041
|
+
displayName: payload.displayName,
|
|
58042
|
+
relationshipTypes: [...payload.relationshipTypes],
|
|
58043
|
+
email: payload.email,
|
|
58044
|
+
phone: payload.phone,
|
|
58045
|
+
organizationName: payload.organizationName,
|
|
58046
|
+
source: payload.source
|
|
58047
|
+
});
|
|
58048
|
+
if (person.entityId !== payload.crmEntityId)
|
|
58049
|
+
throw new CrmBridgeError("crm_entity_identity_mismatch", "CRM returned a different entity identity.");
|
|
58050
|
+
const requestedCommunicationId = stableChildId(payload.bridgeRunId, "communication");
|
|
58051
|
+
const communication = await writer.appendCommunication({
|
|
58052
|
+
entityId: requestedCommunicationId,
|
|
58053
|
+
personEntityId: person.entityId,
|
|
58054
|
+
idempotencyKey: `${payload.bridgeRunId}:communication`,
|
|
58055
|
+
kind: "form_submission",
|
|
58056
|
+
occurredAt: payload.source.observedAt,
|
|
58057
|
+
submittedFields: payload.submittedFields,
|
|
58058
|
+
source: payload.source
|
|
58059
|
+
});
|
|
58060
|
+
let task = null;
|
|
58061
|
+
if (payload.followUp) {
|
|
58062
|
+
task = await writer.upsertTask({
|
|
58063
|
+
entityId: stableChildId(payload.bridgeRunId, "task"),
|
|
58064
|
+
personEntityId: person.entityId,
|
|
58065
|
+
communicationEntityId: communication.entityId,
|
|
58066
|
+
idempotencyKey: `${payload.bridgeRunId}:task`,
|
|
58067
|
+
title: payload.followUp.title,
|
|
58068
|
+
dueAt: payload.followUp.dueAt,
|
|
58069
|
+
source: payload.source
|
|
58070
|
+
});
|
|
58071
|
+
}
|
|
58072
|
+
return {
|
|
58073
|
+
crmEntityId: person.entityId,
|
|
58074
|
+
personReceiptId: person.receiptId,
|
|
58075
|
+
communicationEntityId: communication.entityId,
|
|
58076
|
+
communicationReceiptId: communication.receiptId,
|
|
58077
|
+
taskEntityId: task?.entityId ?? null,
|
|
58078
|
+
taskReceiptId: task?.receiptId ?? null
|
|
58079
|
+
};
|
|
58080
|
+
}
|
|
58081
|
+
|
|
57489
58082
|
// src/api/analytics-delivery.ts
|
|
57490
58083
|
function safeDeliveryError(error) {
|
|
57491
58084
|
if (!error) return "memory_write_failed";
|
|
@@ -57494,7 +58087,37 @@ function safeDeliveryError(error) {
|
|
|
57494
58087
|
if (error.includes("429")) return "memory_rate_limited";
|
|
57495
58088
|
return "memory_write_failed";
|
|
57496
58089
|
}
|
|
57497
|
-
|
|
58090
|
+
function memoryWriteReceipt(result3) {
|
|
58091
|
+
if (result3.ok !== true) throw new Error(typeof result3.error === "string" ? result3.error : "memory_write_failed");
|
|
58092
|
+
const record7 = result3.record && typeof result3.record === "object" ? result3.record : null;
|
|
58093
|
+
const receipt4 = result3.receipt && typeof result3.receipt === "object" ? result3.receipt : null;
|
|
58094
|
+
if (!record7 || typeof record7.entityId !== "string" || typeof record7.revision !== "number" || !receipt4 || typeof receipt4.receiptId !== "string") throw new Error("memory_write_receipt_invalid");
|
|
58095
|
+
return {
|
|
58096
|
+
entityId: record7.entityId,
|
|
58097
|
+
receiptId: receipt4.receiptId,
|
|
58098
|
+
revision: record7.revision
|
|
58099
|
+
};
|
|
58100
|
+
}
|
|
58101
|
+
function hostedMemoryCrmBridgeWriter(memoryKey) {
|
|
58102
|
+
return {
|
|
58103
|
+
async upsertPerson(input) {
|
|
58104
|
+
return memoryWriteReceipt(
|
|
58105
|
+
await memoryCall("crmUpsertPersonTool", input, memoryKey)
|
|
58106
|
+
);
|
|
58107
|
+
},
|
|
58108
|
+
async appendCommunication(input) {
|
|
58109
|
+
return memoryWriteReceipt(
|
|
58110
|
+
await memoryCall("crmAppendCommunicationTool", input, memoryKey)
|
|
58111
|
+
);
|
|
58112
|
+
},
|
|
58113
|
+
async upsertTask(input) {
|
|
58114
|
+
return memoryWriteReceipt(
|
|
58115
|
+
await memoryCall("crmUpsertTaskTool", input, memoryKey)
|
|
58116
|
+
);
|
|
58117
|
+
}
|
|
58118
|
+
};
|
|
58119
|
+
}
|
|
58120
|
+
async function deliverPendingAnalyticsForms(limit = 10, dependencies = {}) {
|
|
57498
58121
|
const jobs = await claimAnalyticsFormDeliveryJobs(limit);
|
|
57499
58122
|
let delivered = 0;
|
|
57500
58123
|
let deferred = 0;
|
|
@@ -57515,12 +58138,62 @@ async function deliverPendingAnalyticsForms(limit = 10) {
|
|
|
57515
58138
|
continue;
|
|
57516
58139
|
}
|
|
57517
58140
|
const { key: key3, error } = await getOrCreateUserMemoryKey(user);
|
|
57518
|
-
|
|
57519
|
-
|
|
57520
|
-
|
|
58141
|
+
if (!key3) {
|
|
58142
|
+
await deferAnalyticsFormDelivery(job.id, job.attempts, safeDeliveryError(error));
|
|
58143
|
+
deferred += 1;
|
|
58144
|
+
continue;
|
|
58145
|
+
}
|
|
58146
|
+
if (!job.bridgeRunId || !job.crmEntityId) {
|
|
58147
|
+
const result3 = await memoryCall("putTool", payload, key3);
|
|
58148
|
+
if (result3.ok) {
|
|
58149
|
+
await completeAnalyticsFormDelivery(job.id, job.submissionId);
|
|
58150
|
+
delivered += 1;
|
|
58151
|
+
} else {
|
|
58152
|
+
await deferAnalyticsFormDelivery(job.id, job.attempts, safeDeliveryError(result3.error));
|
|
58153
|
+
deferred += 1;
|
|
58154
|
+
}
|
|
58155
|
+
continue;
|
|
58156
|
+
}
|
|
58157
|
+
try {
|
|
58158
|
+
const source = payload.source && typeof payload.source === "object" ? payload.source : {};
|
|
58159
|
+
const bridgePayload = {
|
|
58160
|
+
...payload,
|
|
58161
|
+
bridgeRunId: job.bridgeRunId,
|
|
58162
|
+
crmEntityId: job.crmEntityId,
|
|
58163
|
+
source: {
|
|
58164
|
+
...source,
|
|
58165
|
+
kind: "xray_form",
|
|
58166
|
+
submissionId: job.submissionId
|
|
58167
|
+
}
|
|
58168
|
+
};
|
|
58169
|
+
const result3 = await applyCrmFormBridge(
|
|
58170
|
+
bridgePayload,
|
|
58171
|
+
(dependencies.createWriter ?? hostedMemoryCrmBridgeWriter)(key3)
|
|
58172
|
+
);
|
|
58173
|
+
await linkAnalyticsFormIdentity({
|
|
58174
|
+
submissionId: job.submissionId,
|
|
58175
|
+
siteId: bridgePayload.source.siteId,
|
|
58176
|
+
crmEntityId: result3.crmEntityId,
|
|
58177
|
+
visitorId: typeof payload.visitorId === "string" ? payload.visitorId : void 0,
|
|
58178
|
+
sessionId: typeof payload.sessionId === "string" ? payload.sessionId : void 0,
|
|
58179
|
+
email: bridgePayload.email,
|
|
58180
|
+
phone: bridgePayload.phone,
|
|
58181
|
+
displayName: bridgePayload.displayName,
|
|
58182
|
+
evidenceType: "first_party_form",
|
|
58183
|
+
clickIds: payload.clickIds && typeof payload.clickIds === "object" ? payload.clickIds : void 0
|
|
58184
|
+
});
|
|
58185
|
+
await completeAnalyticsFormBridgeDelivery({
|
|
58186
|
+
jobId: job.id,
|
|
58187
|
+
submissionId: job.submissionId,
|
|
58188
|
+
crmEntityId: result3.crmEntityId
|
|
58189
|
+
});
|
|
57521
58190
|
delivered += 1;
|
|
57522
|
-
}
|
|
57523
|
-
await deferAnalyticsFormDelivery(
|
|
58191
|
+
} catch (bridgeError) {
|
|
58192
|
+
await deferAnalyticsFormDelivery(
|
|
58193
|
+
job.id,
|
|
58194
|
+
job.attempts,
|
|
58195
|
+
safeDeliveryError(bridgeError instanceof Error ? bridgeError.message : void 0)
|
|
58196
|
+
);
|
|
57524
58197
|
deferred += 1;
|
|
57525
58198
|
}
|
|
57526
58199
|
}
|
|
@@ -57560,7 +58233,7 @@ async function deliverPendingAnalyticsCrmImports(limit = 10) {
|
|
|
57560
58233
|
}
|
|
57561
58234
|
|
|
57562
58235
|
// src/api/analytics-activation-dispatcher.ts
|
|
57563
|
-
import { randomUUID as
|
|
58236
|
+
import { randomUUID as randomUUID40 } from "crypto";
|
|
57564
58237
|
function parseAnalyticsActivationDestinationProviderConfig(platform, value) {
|
|
57565
58238
|
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
57566
58239
|
const config = value;
|
|
@@ -57639,7 +58312,7 @@ async function claimAnalyticsActivationJobs(limit = 10) {
|
|
|
57639
58312
|
}));
|
|
57640
58313
|
}
|
|
57641
58314
|
async function beginAttempt(job, stableEventId) {
|
|
57642
|
-
const id2 =
|
|
58315
|
+
const id2 = randomUUID40();
|
|
57643
58316
|
const result3 = await getAnalyticsPool().query(
|
|
57644
58317
|
`INSERT INTO analytics_activation_delivery_attempts(
|
|
57645
58318
|
id, job_id, destination_id, mapping_version, attempt_number, provider_event_id, actor
|
|
@@ -58024,7 +58697,7 @@ async function pollPendingGoogleActivationDiagnostics(limit = 10, deadlineMs = D
|
|
|
58024
58697
|
}
|
|
58025
58698
|
|
|
58026
58699
|
// src/api/analytics-reconciliation.ts
|
|
58027
|
-
import { createHash as
|
|
58700
|
+
import { createHash as createHash45, randomUUID as randomUUID41 } from "crypto";
|
|
58028
58701
|
var RECONCILIATION_INTERVAL_SECONDS = 15 * 60;
|
|
58029
58702
|
var WEBHOOK_ONLY_RECHECK_SECONDS = 24 * 60 * 60;
|
|
58030
58703
|
var LEASE_SECONDS = 90;
|
|
@@ -58048,7 +58721,7 @@ var defaultDependencies2 = {
|
|
|
58048
58721
|
input: input.payload,
|
|
58049
58722
|
classification: "read",
|
|
58050
58723
|
operationKind: "sync",
|
|
58051
|
-
requestId:
|
|
58724
|
+
requestId: randomUUID41()
|
|
58052
58725
|
});
|
|
58053
58726
|
},
|
|
58054
58727
|
async resolveMappedCrmPerson(input) {
|
|
@@ -58151,14 +58824,14 @@ function crmReadInput(provider, sourceAccountRef, cursorValue, now) {
|
|
|
58151
58824
|
}
|
|
58152
58825
|
}
|
|
58153
58826
|
function crmOutcomeSourceEventId(outcome) {
|
|
58154
|
-
const digest23 =
|
|
58827
|
+
const digest23 = createHash45("sha256").update(`${outcome.provider}:${outcome.sourceRecordId}:${outcome.updatedAt}:${outcome.tombstone}`).digest("hex").slice(0, 40);
|
|
58155
58828
|
return `crm:${outcome.provider}:${digest23}`;
|
|
58156
58829
|
}
|
|
58157
58830
|
function analyticsCrmOutcomeToExternalEvent(outcome, sourceAccountRef) {
|
|
58158
58831
|
const sourceEventId = crmOutcomeSourceEventId(outcome);
|
|
58159
58832
|
return {
|
|
58160
58833
|
schemaVersion: 1,
|
|
58161
|
-
eventId: `crm_${
|
|
58834
|
+
eventId: `crm_${createHash45("sha256").update(sourceEventId).digest("hex").slice(0, 24)}`,
|
|
58162
58835
|
sourceEventId,
|
|
58163
58836
|
source: outcome.provider,
|
|
58164
58837
|
sourceAccountRef,
|
|
@@ -58315,7 +58988,7 @@ async function ensureDueJobs() {
|
|
|
58315
58988
|
await db.query(
|
|
58316
58989
|
`INSERT INTO analytics_reconciliation_jobs(id, connection_id)
|
|
58317
58990
|
VALUES ($1,$2) ON CONFLICT(connection_id) DO NOTHING`,
|
|
58318
|
-
[
|
|
58991
|
+
[randomUUID41(), connection.id]
|
|
58319
58992
|
);
|
|
58320
58993
|
}
|
|
58321
58994
|
}
|
|
@@ -58458,7 +59131,7 @@ async function deferAnalyticsReconciliationJob(input) {
|
|
|
58458
59131
|
connectionId: input.connectionId,
|
|
58459
59132
|
safeErrorCode: errorCode2,
|
|
58460
59133
|
nextRunAt: new Date(Date.now() + delaySeconds * 1e3).toISOString(),
|
|
58461
|
-
receiptFingerprint:
|
|
59134
|
+
receiptFingerprint: createHash45("sha256").update(`${input.jobId}:${input.attempts}:${errorCode2}`).digest("hex")
|
|
58462
59135
|
});
|
|
58463
59136
|
}
|
|
58464
59137
|
}
|
|
@@ -58569,7 +59242,7 @@ async function reconcileAnalyticsConnection(job, dependencies = defaultDependenc
|
|
|
58569
59242
|
deduplicated: duplicates,
|
|
58570
59243
|
rejected: page3.rejected,
|
|
58571
59244
|
hasMore: page3.hasMore,
|
|
58572
|
-
receiptFingerprint:
|
|
59245
|
+
receiptFingerprint: createHash45("sha256").update(`${job.id}:${JSON.stringify(page3.nextCursor)}:${replayed}:${duplicates}`).digest("hex"),
|
|
58573
59246
|
scheduleConfigured: Boolean(scope.sync_id),
|
|
58574
59247
|
scheduleIntervalSeconds: scope.sync_interval_seconds ?? null
|
|
58575
59248
|
}
|
|
@@ -58606,7 +59279,7 @@ async function drainAnalyticsReconciliation(limit = 5, deadlineMs = Date.now() +
|
|
|
58606
59279
|
}
|
|
58607
59280
|
|
|
58608
59281
|
// src/api/analytics-scheduled-lanes.ts
|
|
58609
|
-
import { randomUUID as
|
|
59282
|
+
import { randomUUID as randomUUID42 } from "crypto";
|
|
58610
59283
|
var ANALYTICS_SCHEDULED_LANES = [
|
|
58611
59284
|
{ key: "rollup", intervalMinutes: 15, catchUpIntervals: 2, maxAttempts: 4 },
|
|
58612
59285
|
{ key: "form_delivery", intervalMinutes: 1, catchUpIntervals: 3, maxAttempts: 5 },
|
|
@@ -58653,7 +59326,7 @@ var PostgresAnalyticsScheduledOccurrenceStore = class {
|
|
|
58653
59326
|
(id,lane_key,scheduled_for,status,attempt_count,max_attempts,next_attempt_at,created_at,updated_at)
|
|
58654
59327
|
VALUES ($1,$2,$3,'pending',0,$4,$3,now(),now())
|
|
58655
59328
|
ON CONFLICT (lane_key,scheduled_for) DO NOTHING`,
|
|
58656
|
-
[
|
|
59329
|
+
[randomUUID42(), definition.key, scheduledFor, definition.maxAttempts]
|
|
58657
59330
|
);
|
|
58658
59331
|
inserted += Number(result3.rowCount ?? 0);
|
|
58659
59332
|
}
|
|
@@ -58736,7 +59409,7 @@ var PostgresAnalyticsScheduledOccurrenceStore = class {
|
|
|
58736
59409
|
async function runAnalyticsScheduledLanes(executors, options = {}) {
|
|
58737
59410
|
const store = options.store ?? new PostgresAnalyticsScheduledOccurrenceStore();
|
|
58738
59411
|
const now = options.now ?? (() => /* @__PURE__ */ new Date());
|
|
58739
|
-
const owner5 = options.owner ?? `cron:${
|
|
59412
|
+
const owner5 = options.owner ?? `cron:${randomUUID42()}`;
|
|
58740
59413
|
const leaseMs = options.leaseMs ?? 6e4;
|
|
58741
59414
|
const maxClaims = options.maxClaims ?? 12;
|
|
58742
59415
|
const firstNow = now();
|
|
@@ -58782,17 +59455,17 @@ async function runAnalyticsScheduledLanes(executors, options = {}) {
|
|
|
58782
59455
|
}
|
|
58783
59456
|
|
|
58784
59457
|
// src/api/scheduled-result-routes.ts
|
|
58785
|
-
import { Hono as
|
|
58786
|
-
import { z as
|
|
59458
|
+
import { Hono as Hono38 } from "hono";
|
|
59459
|
+
import { z as z46 } from "zod";
|
|
58787
59460
|
|
|
58788
59461
|
// src/api/scheduled-artifact-owner.ts
|
|
58789
|
-
import { createHash as
|
|
59462
|
+
import { createHash as createHash46 } from "crypto";
|
|
58790
59463
|
function scheduledArtifactOwnerIdForApiKey(apiKey) {
|
|
58791
|
-
return
|
|
59464
|
+
return createHash46("sha256").update(apiKey).digest("hex").slice(0, 24);
|
|
58792
59465
|
}
|
|
58793
59466
|
|
|
58794
59467
|
// src/api/scheduled-run-view-links.ts
|
|
58795
|
-
import { createHash as
|
|
59468
|
+
import { createHash as createHash47, randomBytes as randomBytes6, randomUUID as randomUUID43 } from "crypto";
|
|
58796
59469
|
var schemaReady3 = false;
|
|
58797
59470
|
async function ensureScheduledRunViewLinksSchema() {
|
|
58798
59471
|
if (schemaReady3) return;
|
|
@@ -58846,7 +59519,7 @@ async function ensureScheduledRunViewLinksSchema() {
|
|
|
58846
59519
|
schemaReady3 = true;
|
|
58847
59520
|
}
|
|
58848
59521
|
function tokenHash2(token7) {
|
|
58849
|
-
return
|
|
59522
|
+
return createHash47("sha256").update(token7).digest("hex");
|
|
58850
59523
|
}
|
|
58851
59524
|
function mapRow(row) {
|
|
58852
59525
|
return {
|
|
@@ -58868,7 +59541,7 @@ async function createScheduledRunViewLink(input) {
|
|
|
58868
59541
|
const now = input.now ?? /* @__PURE__ */ new Date();
|
|
58869
59542
|
const token7 = randomBytes6(32).toString("base64url");
|
|
58870
59543
|
const record7 = {
|
|
58871
|
-
shareId:
|
|
59544
|
+
shareId: randomUUID43(),
|
|
58872
59545
|
ownerId: input.ownerId,
|
|
58873
59546
|
runId: input.runId,
|
|
58874
59547
|
artifactId: input.artifactId,
|
|
@@ -58933,7 +59606,7 @@ async function revokeScheduledRunViewLink(ownerId3, runId, shareId, now = /* @__
|
|
|
58933
59606
|
}
|
|
58934
59607
|
|
|
58935
59608
|
// src/personal-authority/render.ts
|
|
58936
|
-
import { createHash as
|
|
59609
|
+
import { createHash as createHash48 } from "crypto";
|
|
58937
59610
|
function escapeHtml8(value) {
|
|
58938
59611
|
return value.replace(/[&<>"']/g, (character) => ({
|
|
58939
59612
|
"&": "&",
|
|
@@ -58993,13 +59666,13 @@ ${section(flags.finalCta && Boolean(finalCta), `<section class="section cta" id=
|
|
|
58993
59666
|
html,
|
|
58994
59667
|
filename: `${input.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") || "personal-authority"}.html`,
|
|
58995
59668
|
bytes: bytes2,
|
|
58996
|
-
sha256:
|
|
59669
|
+
sha256: createHash48("sha256").update(html).digest("hex"),
|
|
58997
59670
|
generatedAt: generatedAtIso
|
|
58998
59671
|
};
|
|
58999
59672
|
}
|
|
59000
59673
|
|
|
59001
59674
|
// src/personal-authority/render-v2.ts
|
|
59002
|
-
import { createHash as
|
|
59675
|
+
import { createHash as createHash49 } from "crypto";
|
|
59003
59676
|
var FONT_STACKS = Object.freeze({
|
|
59004
59677
|
"editorial-serif": "Iowan Old Style, Baskerville, Times New Roman, serif",
|
|
59005
59678
|
"modern-sans": "Avenir Next, Avenir, Helvetica Neue, Arial, sans-serif",
|
|
@@ -59103,13 +59776,13 @@ ${section2(flags.finalCta && Boolean(finalCta), `<section class="section cta" id
|
|
|
59103
59776
|
html,
|
|
59104
59777
|
filename: `${input.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") || "personal-authority"}.html`,
|
|
59105
59778
|
bytes: bytes2,
|
|
59106
|
-
sha256:
|
|
59779
|
+
sha256: createHash49("sha256").update(html).digest("hex"),
|
|
59107
59780
|
generatedAt: generatedAtIso
|
|
59108
59781
|
};
|
|
59109
59782
|
}
|
|
59110
59783
|
|
|
59111
59784
|
// src/newsroom-publisher/render.ts
|
|
59112
|
-
import { createHash as
|
|
59785
|
+
import { createHash as createHash50 } from "crypto";
|
|
59113
59786
|
function escapeHtml10(value) {
|
|
59114
59787
|
return value.replace(/[&<>"']/g, (character) => ({
|
|
59115
59788
|
"&": "&",
|
|
@@ -59215,13 +59888,13 @@ body{overflow-x:hidden}.lead-story__body,.lead-support__item,.story-card__body{m
|
|
|
59215
59888
|
@media(max-width:620px){.desk-section__grid--panorama,.desk-section__grid--mosaic,.desk-section__grid--tiles{grid-template-columns:1fr}.story-card--panorama{display:block}.story-card--panorama h3,.story-card--mosaic-lead h3{font-size:34px}.story-card--mosaic-lead{grid-column:auto;grid-row:auto}.desk-section__grid--tiles>.story-card:nth-child(3n+2){margin-top:0}}
|
|
59216
59889
|
</style></head><body data-theme="${escapeHtml10(config.theme)}" id="top" data-scheduled-renderer="newsroom_publisher_v1">${ticker}${masthead}${navigation}<main>${leadGrid}${latest}${sections}${newsletter}${pressRoom}${trustCenter}</main>${trustFooter}</body></html>`;
|
|
59217
59890
|
const bytes2 = Buffer.byteLength(html);
|
|
59218
|
-
const sha2564 =
|
|
59891
|
+
const sha2564 = createHash50("sha256").update(html).digest("hex");
|
|
59219
59892
|
const filename2 = `${brand.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") || "newsroom"}-news-site.html`;
|
|
59220
59893
|
return { html, filename: filename2, bytes: bytes2, sha256: sha2564, generatedAt: generatedAtIso };
|
|
59221
59894
|
}
|
|
59222
59895
|
|
|
59223
59896
|
// src/blog-article/render.ts
|
|
59224
|
-
import { createHash as
|
|
59897
|
+
import { createHash as createHash51 } from "crypto";
|
|
59225
59898
|
function escapeHtml11(value) {
|
|
59226
59899
|
return value.replace(
|
|
59227
59900
|
/[&<>"']/g,
|
|
@@ -59309,7 +59982,7 @@ function renderBlogArticleV1(input, config, generatedAt) {
|
|
|
59309
59982
|
:root{--ink:#10213d;--ink2:#1c355a;--blue:#2563eb;--blue2:#1749b6;--mint:#45d5aa;--paper:#f7f5f0;--line:#dce4ef;--card:#fff;--body:#475569;--serif:Iowan Old Style,Palatino Linotype,Palatino,Georgia,serif;--sans:Inter,Avenir Next,ui-sans-serif,system-ui,sans-serif}body[data-theme="slate"]{--ink:#1e293b;--ink2:#334155;--blue:#475569;--blue2:#1e293b;--mint:#94a3b8;--paper:#f8fafc}body[data-theme="forest"]{--ink:#12352e;--ink2:#23584c;--blue:#147d64;--blue2:#0c5b48;--mint:#79d8bd;--paper:#f4f8f3}*{box-sizing:border-box}html{scroll-behavior:smooth;background:var(--paper)}body{margin:0;color:#252a33;background:var(--paper);font-family:var(--sans);line-height:1.6}a{color:inherit}button{font:inherit}button:focus-visible,a:focus-visible{outline:3px solid var(--mint);outline-offset:3px}.progress{position:fixed;z-index:50;top:0;left:0;height:4px;width:0;background:var(--mint)}.hero{position:relative;overflow:hidden;color:#fff;background:var(--ink)}.hero:after{position:absolute;right:-110px;top:-150px;width:420px;height:420px;border:1px solid #ffffff1a;border-radius:50%;content:""}.hero-inner{position:relative;z-index:1;max-width:1240px;margin:auto;padding:58px 42px 126px}.breadcrumb{display:flex;gap:8px;margin-bottom:34px;color:#dbeafecc;font-size:14px}.eyebrow{display:block;color:var(--blue);font-size:12px;font-weight:800;letter-spacing:.16em;text-transform:uppercase}.hero .eyebrow{color:var(--mint)}h1,h2,h3,p{margin-top:0}.hero h1{max-width:1000px;margin:14px 0 24px;font:700 clamp(44px,6vw,78px)/.98 var(--serif);letter-spacing:-.035em}.hero .dek{max-width:780px;color:#dbeafe;font-size:20px}.contributors{margin-top:30px;color:#eff6ff;font-size:14px}.contributors a{font-weight:800}.meta{display:flex;flex-wrap:wrap;gap:12px;margin-top:6px;color:#dbeafecc}.layout{position:relative;z-index:2;display:grid;grid-template-columns:minmax(0,760px) 290px;gap:64px;max-width:1240px;margin:-78px auto 0;padding:0 42px 80px}.main{min-width:0}.takeaways{padding:38px 44px;border-radius:24px;background:#fff;box-shadow:0 24px 70px #10213d24}.takeaways h2{margin:5px 0 20px;font:700 32px/1.1 var(--serif);color:var(--ink)}.takeaways ul{display:grid;gap:16px;margin:0;padding:0;list-style:none}.takeaways li{position:relative;padding-left:26px;color:var(--body);font-size:17px}.takeaways li:before{position:absolute;left:2px;top:.7em;width:8px;height:8px;border-radius:50%;background:var(--blue);content:""}.intro{padding:40px 0 4px}.intro p,.article-section>p{margin-bottom:22px;color:var(--body);font:400 18px/1.75 var(--sans)}.article-section{scroll-margin-top:28px;padding-top:45px}.article-section h2,.faq h2{margin:6px 0 20px;color:var(--ink);font:700 38px/1.08 var(--serif);letter-spacing:-.02em}.article-section ul{display:grid;gap:10px;margin:22px 0;padding-left:24px;color:var(--body);font-size:17px}.article-section li::marker{color:var(--blue)}.callout{margin:34px 0;padding:24px 28px;border-left:4px solid var(--blue);border-radius:0 16px 16px 0;background:#fff}.callout span{color:var(--blue);font-size:11px;font-weight:800;letter-spacing:.13em;text-transform:uppercase}.callout h3{margin:5px 0 8px;color:var(--ink);font:700 24px/1.15 var(--serif)}.callout p{margin:0;color:var(--body)}.rail{padding-top:0}.sidebar-media{overflow:hidden;margin:0 0 18px;border:1px solid #dbeafe;border-radius:16px;background:#fff}.sidebar-media img,.sidebar-media svg{display:block;width:100%;aspect-ratio:16/9;object-fit:cover}.sidebar-media figcaption{padding:10px 13px;color:#64748b;font-size:11px}.disclosure{margin-bottom:28px;border-top:1px solid #dbeafe;border-bottom:1px solid #dbeafe}.disclosure button{display:flex;width:100%;align-items:center;justify-content:space-between;gap:14px;padding:15px 0;border:0;color:#64748b;background:transparent;text-align:left;font-size:12px;cursor:pointer}.disclosure button b{color:var(--blue);font-size:18px;transition:transform .2s}.disclosure button[aria-expanded="true"] b{transform:rotate(180deg)}.disclosure p{padding:0 0 16px;margin:0;color:#64748b;font-size:12px}.toc{position:sticky;top:30px;padding:22px;border:1px solid var(--line);border-radius:16px;background:#fff;box-shadow:0 2px 5px #10213d12}.toc header{display:flex;align-items:center;justify-content:space-between}.toc header strong{color:var(--ink);font:700 21px/1 var(--serif)}.toc header button{width:34px;height:34px;border:0;border-radius:50%;color:var(--blue);background:transparent;cursor:pointer}.toc nav{display:grid;margin-top:14px}.toc nav a{display:flex;align-items:flex-start;gap:11px;padding:8px 0;color:#64748b;text-decoration:none;font-size:13px;line-height:1.35}.toc nav i{width:8px;height:8px;margin-top:5px;border:2px solid #bfdbfe;border-radius:50%}.toc nav a[aria-current="location"]{color:var(--ink);font-weight:800}.toc nav a[aria-current="location"] i{border-color:var(--blue);background:var(--blue)}.back-top{width:100%;margin-top:18px;padding:16px 0 0;border:0;border-top:1px solid var(--line);color:var(--blue);background:transparent;text-align:right;font-size:13px;font-weight:800;cursor:pointer}.faq{scroll-margin-top:28px;padding-top:64px}.faq>div{border-top:1px solid var(--line);border-bottom:1px solid var(--line)}.faq article+article{border-top:1px solid var(--line)}.faq h3{margin:0}.faq h3 button{display:flex;width:100%;align-items:center;justify-content:space-between;gap:18px;padding:19px 0;border:0;color:var(--ink);background:transparent;text-align:left;font-weight:800;cursor:pointer}.faq h3 b{color:var(--blue);font-size:22px}.faq article>p{padding:0 0 20px;margin:0;color:var(--body);font-size:16px}.author-card{margin-top:64px;padding:32px 36px;border-radius:18px;background:#fff}.article-actions{display:flex;flex-wrap:wrap;justify-content:space-between;gap:14px}.article-actions button{display:inline-flex;min-height:46px;align-items:center;justify-content:center;gap:8px;padding:8px 18px;border:2px solid var(--blue);border-radius:999px;color:var(--ink);background:#fff;font-weight:800;cursor:pointer}.article-actions button:hover{color:#fff;background:var(--blue)}.action-status{min-height:20px;margin:8px 0 0;color:var(--blue);text-align:right;font-size:13px;font-weight:700}.author-grid{display:grid;grid-template-columns:auto 1fr auto;gap:22px;align-items:center;margin-top:24px}.author-portrait{width:88px;height:88px;border-radius:50%;object-fit:cover}.author-initials{display:grid;place-items:center;color:var(--ink);background:#fecdd3;font-size:22px;font-weight:900}.author-grid span{color:#64748b;font-size:13px}.author-grid h2{margin:2px 0;color:var(--ink);font:700 27px/1 var(--serif)}.author-grid h2 a{text-decoration:none}.author-grid p{margin:8px 0;color:#64748b;font-size:14px}.author-grid nav{display:flex;flex-wrap:wrap;gap:14px}.author-grid nav a{color:#64748b;font-size:12px}.author-more{display:inline-flex;min-height:48px;align-items:center;justify-content:center;padding:10px 24px;border:2px solid var(--blue);color:var(--blue);text-align:center;text-decoration:none;font-size:13px;font-weight:800}.author-bio{margin:24px 0 0!important;padding-top:20px;border-top:1px solid var(--line);color:var(--body);font-size:16px}dialog{width:min(720px,calc(100% - 30px));max-height:calc(100dvh - 30px);padding:0;border:0;border-radius:18px;color:var(--ink);background:#fff;box-shadow:0 24px 70px #10213d38}dialog::backdrop{background:#0f172a7a;backdrop-filter:blur(2px)}dialog>div{position:relative;padding:30px}dialog h2{margin:0 50px 2px 0;font:700 30px/1.1 var(--serif)}dialog>div>p{color:#64748b}.dialog-close{position:absolute;top:13px;right:13px;width:44px;height:44px;border:0;border-radius:50%;color:var(--blue);background:transparent;font-size:29px;cursor:pointer}dialog section{border-top:1px solid var(--line)}dialog section button{display:block;width:100%;padding:17px 5px;border:0;border-bottom:1px solid var(--line);color:var(--body);background:#fff;text-align:left;line-height:1.65;cursor:pointer}.citation-status{min-height:22px;margin:14px 0 0!important;color:var(--blue)!important;font-size:13px;font-weight:800}.generated{max-width:1156px;margin:-52px auto 50px;padding:0 42px;color:#94a3b8;font-size:11px}@media(max-width:900px){.layout{display:block}.rail{display:none}.hero-inner{padding-bottom:116px}}@media(max-width:620px){.hero-inner{padding:36px 20px 104px}.hero h1{font-size:46px}.hero .dek{font-size:17px}.layout{margin-top:-70px;padding:0 16px 54px}.takeaways{padding:28px 24px}.article-section h2,.faq h2{font-size:32px}.author-card{padding:24px}.article-actions{display:grid;justify-content:start}.author-grid{grid-template-columns:1fr;gap:12px}.author-more{width:100%}dialog>div{padding:24px}.generated{padding:0 20px}}
|
|
59310
59983
|
</style></head><body data-theme="${escapeHtml11(config.theme)}" data-scheduled-renderer="blog_article_v1"><div class="progress" aria-hidden="true"></div><header class="hero"><div class="hero-inner"><nav class="breadcrumb" aria-label="Breadcrumb"><a href="${safeHref4(input.canonicalUrl)}">${escapeHtml11(input.category)}</a><span>/</span><span>Article</span></nav><span class="eyebrow">${escapeHtml11(input.eyebrow)}</span><h1>${escapeHtml11(input.title)}</h1>${input.dek ? `<p class="dek">${escapeHtml11(input.dek)}</p>` : ""}<div class="contributors">${contributorText}<div class="meta"><time datetime="${escapeHtml11(articleDate)}">Updated ${formatDate2(articleDate)}</time><span>\u2022</span><span>${input.readTimeMinutes} min read</span>${input.reviewer ? "<span>\u2022</span><strong>Expert reviewed</strong>" : ""}</div></div></div></header><main class="layout"><article class="main"><section class="takeaways"><span class="eyebrow">The short answer</span><h2>Key takeaways</h2><ul>${input.keyTakeaways.map((item) => `<li>${escapeHtml11(item)}</li>`).join("")}</ul></section><section class="intro">${input.introduction.map((paragraph) => `<p>${escapeHtml11(paragraph)}</p>`).join("")}</section>${sections}${faq}${author}</article><div class="rail">${media}${disclosure}${toc}</div></main>${config.showGeneratedAt ? `<p class="generated">Rendered ${formatDate2(generatedAtIso)} by MCP Scraper.</p>` : ""}${citationDialog}<script>(()=>{const citations=${jsonForScript(citationValues)};const canonical=${jsonForScript(input.canonicalUrl)};const title=${jsonForScript(input.title)};const progress=document.querySelector('.progress');const tocLinks=[...document.querySelectorAll('.toc nav a')];const targets=tocLinks.map(link=>document.querySelector(link.hash)).filter(Boolean);const update=()=>{const max=document.documentElement.scrollHeight-innerHeight;if(progress)progress.style.width=(max>0?scrollY/max*100:0)+'%';let active=targets[0]?.id;for(const target of targets){if(target.getBoundingClientRect().top<=innerHeight*.55)active=target.id}tocLinks.forEach(link=>link.toggleAttribute('aria-current',link.hash==='#'+active));tocLinks.forEach(link=>{if(link.hash==='#'+active)link.setAttribute('aria-current','location');else link.removeAttribute('aria-current')})};addEventListener('scroll',update,{passive:true});addEventListener('resize',update);update();document.querySelectorAll('.faq h3 button').forEach(button=>button.addEventListener('click',()=>{const panel=document.getElementById(button.getAttribute('aria-controls'));const open=button.getAttribute('aria-expanded')==='true';button.setAttribute('aria-expanded',String(!open));panel.hidden=open;button.querySelector('b').textContent=open?'+':'\u2212'}));const disclosure=document.querySelector('.disclosure button');disclosure?.addEventListener('click',()=>{const panel=document.getElementById(disclosure.getAttribute('aria-controls'));const open=disclosure.getAttribute('aria-expanded')==='true';disclosure.setAttribute('aria-expanded',String(!open));panel.hidden=open});const tocToggle=document.querySelector('.toc header button');tocToggle?.addEventListener('click',()=>{const nav=document.getElementById('toc-links');const open=tocToggle.getAttribute('aria-expanded')==='true';tocToggle.setAttribute('aria-expanded',String(!open));nav.hidden=open;tocToggle.textContent=open?'\u2304':'\u2303'});document.querySelector('.back-top')?.addEventListener('click',()=>scrollTo({top:0,behavior:'smooth'}));const copy=async text=>{try{await navigator.clipboard.writeText(text)}catch{const area=document.createElement('textarea');area.value=text;area.style.position='fixed';area.style.opacity='0';document.body.append(area);area.select();document.execCommand('copy');area.remove()}};const dialog=document.getElementById('citation-dialog');document.querySelector('[data-cite]')?.addEventListener('click',()=>dialog.showModal());document.querySelector('.dialog-close')?.addEventListener('click',()=>dialog.close());dialog?.addEventListener('click',event=>{if(event.target===dialog)dialog.close()});document.querySelectorAll('[data-citation]').forEach(button=>button.addEventListener('click',async()=>{const style=button.dataset.citation;await copy(citations[style]);document.querySelector('.citation-status').textContent=style+' citation copied to clipboard.'}));document.querySelector('[data-share]')?.addEventListener('click',async()=>{const status=document.querySelector('.action-status');if(navigator.share){try{await navigator.share({title,url:canonical});status.textContent='Sharing options opened.';return}catch(error){if(error.name==='AbortError')return}}await copy(canonical);status.textContent='Article link copied to clipboard.'})})()</script></body></html>`;
|
|
59311
59984
|
const bytes2 = Buffer.byteLength(html);
|
|
59312
|
-
const sha2564 =
|
|
59985
|
+
const sha2564 = createHash51("sha256").update(html).digest("hex");
|
|
59313
59986
|
return {
|
|
59314
59987
|
html,
|
|
59315
59988
|
filename: "blog-article.html",
|
|
@@ -59424,15 +60097,15 @@ var scheduledArtifactTemplatePresets = [
|
|
|
59424
60097
|
];
|
|
59425
60098
|
|
|
59426
60099
|
// src/api/scheduled-result-routes.ts
|
|
59427
|
-
var TemplateParamsSchema =
|
|
59428
|
-
var RunParamsSchema =
|
|
59429
|
-
var ViewLinkParamsSchema =
|
|
59430
|
-
runId:
|
|
59431
|
-
shareId:
|
|
60100
|
+
var TemplateParamsSchema = z46.object({ templateId: z46.string().uuid() }).strict();
|
|
60101
|
+
var RunParamsSchema = z46.object({ runId: z46.string().min(1).max(200) }).strict();
|
|
60102
|
+
var ViewLinkParamsSchema = z46.object({
|
|
60103
|
+
runId: z46.string().min(1).max(200),
|
|
60104
|
+
shareId: z46.string().uuid()
|
|
59432
60105
|
}).strict();
|
|
59433
|
-
var ArtifactTemplateListQuerySchema =
|
|
59434
|
-
status:
|
|
59435
|
-
query:
|
|
60106
|
+
var ArtifactTemplateListQuerySchema = z46.object({
|
|
60107
|
+
status: z46.enum(["active", "archived", "all"]).default("active"),
|
|
60108
|
+
query: z46.string().trim().min(1).max(120).optional(),
|
|
59436
60109
|
presetKey: ArtifactTemplatePresetKeySchema.optional()
|
|
59437
60110
|
}).strict();
|
|
59438
60111
|
function apiError(error, errorCode2 = "invalid_request") {
|
|
@@ -59462,7 +60135,7 @@ function safeMemoryFailure(result3) {
|
|
|
59462
60135
|
errorCode2 in messages ? errorCode2 : "internal_error"
|
|
59463
60136
|
);
|
|
59464
60137
|
}
|
|
59465
|
-
var scheduledResultApp = new
|
|
60138
|
+
var scheduledResultApp = new Hono38();
|
|
59466
60139
|
scheduledResultApp.use("/artifact-templates", createApiKeyAuth());
|
|
59467
60140
|
scheduledResultApp.use("/artifact-templates/*", createApiKeyAuth());
|
|
59468
60141
|
scheduledResultApp.use("/schedule-runs", createApiKeyAuth());
|
|
@@ -59609,10 +60282,10 @@ scheduledResultApp.delete("/schedule-runs/:runId/view-links/:shareId", async (c)
|
|
|
59609
60282
|
});
|
|
59610
60283
|
|
|
59611
60284
|
// src/api/public-scheduled-result-routes.ts
|
|
59612
|
-
import { Hono as
|
|
60285
|
+
import { Hono as Hono39 } from "hono";
|
|
59613
60286
|
|
|
59614
60287
|
// src/scheduled-artifacts/scheduled-run-artifact-store.ts
|
|
59615
|
-
import { createHash as
|
|
60288
|
+
import { createHash as createHash52 } from "crypto";
|
|
59616
60289
|
var SCHEDULED_RUN_ARTIFACT_PREFIX = "scheduled-run-artifacts/";
|
|
59617
60290
|
var SCHEDULED_RUN_ARTIFACT_DOWNLOAD_TTL_MS = 15 * 60 * 1e3;
|
|
59618
60291
|
var SCHEDULED_RUN_ARTIFACT_MAX_BYTES = 2e6;
|
|
@@ -59628,7 +60301,7 @@ function policy5() {
|
|
|
59628
60301
|
};
|
|
59629
60302
|
}
|
|
59630
60303
|
function runStorageSegment(runId) {
|
|
59631
|
-
return /^[a-zA-Z0-9_-]{1,160}$/.test(runId) ? runId : `run-${
|
|
60304
|
+
return /^[a-zA-Z0-9_-]{1,160}$/.test(runId) ? runId : `run-${createHash52("sha256").update(runId).digest("hex").slice(0, 32)}`;
|
|
59632
60305
|
}
|
|
59633
60306
|
async function createScheduledRunArtifact(args) {
|
|
59634
60307
|
if (args.rendered.bytes > SCHEDULED_RUN_ARTIFACT_MAX_BYTES) {
|
|
@@ -59671,7 +60344,7 @@ async function readScheduledRunArtifact(args) {
|
|
|
59671
60344
|
}
|
|
59672
60345
|
|
|
59673
60346
|
// src/api/public-scheduled-result-routes.ts
|
|
59674
|
-
var publicScheduledResultApp = new
|
|
60347
|
+
var publicScheduledResultApp = new Hono39();
|
|
59675
60348
|
function allowedFrameAncestors() {
|
|
59676
60349
|
const configured3 = (process.env.SCHEDULED_ARTIFACT_FRAME_ANCESTORS ?? "").split(",").map((value) => value.trim()).filter((value) => /^https?:\/\/[^/\s]+$/.test(value));
|
|
59677
60350
|
const origins = configured3.length ? configured3 : ["https://mcpscraper.dev", "https://www.mcpscraper.dev"];
|
|
@@ -59732,8 +60405,8 @@ publicScheduledResultApp.get("/scheduled-run-view-links/:token/content", async (
|
|
|
59732
60405
|
});
|
|
59733
60406
|
|
|
59734
60407
|
// src/api/scheduled-artifact-internal-routes.ts
|
|
59735
|
-
import { Hono as
|
|
59736
|
-
var scheduledArtifactInternalApp = new
|
|
60408
|
+
import { Hono as Hono40 } from "hono";
|
|
60409
|
+
var scheduledArtifactInternalApp = new Hono40();
|
|
59737
60410
|
function errorPayload(errorCode2, error, requestId) {
|
|
59738
60411
|
return ApiErrorResponseSchema.parse({
|
|
59739
60412
|
ok: false,
|
|
@@ -59820,19 +60493,19 @@ scheduledArtifactInternalApp.post("/render", async (c) => {
|
|
|
59820
60493
|
});
|
|
59821
60494
|
|
|
59822
60495
|
// src/api/personal-assistant-routes.ts
|
|
59823
|
-
import { createHash as
|
|
59824
|
-
import { Hono as
|
|
60496
|
+
import { createHash as createHash60, randomUUID as randomUUID45 } from "crypto";
|
|
60497
|
+
import { Hono as Hono42 } from "hono";
|
|
59825
60498
|
|
|
59826
60499
|
// src/api/personal-assistant-schedule-readiness.ts
|
|
59827
|
-
import { createHash as
|
|
59828
|
-
import { z as
|
|
59829
|
-
var opaqueRef =
|
|
59830
|
-
var isoTimestamp2 =
|
|
59831
|
-
var reasonCode =
|
|
59832
|
-
var ScheduleReadinessInputSchema =
|
|
60500
|
+
import { createHash as createHash53 } from "crypto";
|
|
60501
|
+
import { z as z47 } from "zod";
|
|
60502
|
+
var opaqueRef = z47.string().trim().regex(/^[a-z][a-z0-9_]*_[A-Za-z0-9_-]{3,128}$/);
|
|
60503
|
+
var isoTimestamp2 = z47.iso.datetime({ offset: true });
|
|
60504
|
+
var reasonCode = z47.string().regex(/^[a-z][a-z0-9_]{2,80}$/);
|
|
60505
|
+
var ScheduleReadinessInputSchema = z47.object({
|
|
59833
60506
|
draft: CanonicalScheduleDraftSchema,
|
|
59834
60507
|
runtimeRef: opaqueRef.nullable(),
|
|
59835
|
-
exactConnectionBindings:
|
|
60508
|
+
exactConnectionBindings: z47.array(ScheduleConnectionBindingSchema).max(100)
|
|
59836
60509
|
}).strict().superRefine((value, context) => {
|
|
59837
60510
|
const connectionRefs = value.exactConnectionBindings.map((binding) => binding.connectionRef);
|
|
59838
60511
|
if (new Set(connectionRefs).size !== connectionRefs.length) {
|
|
@@ -59845,26 +60518,26 @@ var ScheduleReadinessInputSchema = z45.object({
|
|
|
59845
60518
|
context.addIssue({ code: "custom", path: ["runtimeRef"], message: "browser jobs require a registered runtime" });
|
|
59846
60519
|
}
|
|
59847
60520
|
});
|
|
59848
|
-
var ScheduleReadinessFactSchema =
|
|
59849
|
-
key:
|
|
60521
|
+
var ScheduleReadinessFactSchema = z47.object({
|
|
60522
|
+
key: z47.string().regex(/^[a-z][a-z0-9_.]{2,120}$/),
|
|
59850
60523
|
subjectRef: opaqueRef.nullable(),
|
|
59851
|
-
state:
|
|
60524
|
+
state: z47.enum(["ready", "warning", "blocked"]),
|
|
59852
60525
|
reasonCode,
|
|
59853
|
-
revision:
|
|
60526
|
+
revision: z47.number().int().nonnegative().nullable(),
|
|
59854
60527
|
evidenceDigest: DigestSchema.nullable()
|
|
59855
60528
|
}).strict();
|
|
59856
|
-
var readinessIssue =
|
|
59857
|
-
var ScheduleReadinessReceiptSchema =
|
|
59858
|
-
schemaVersion:
|
|
60529
|
+
var readinessIssue = z47.object({ code: reasonCode, subjectRef: opaqueRef.nullable() }).strict();
|
|
60530
|
+
var ScheduleReadinessReceiptSchema = z47.object({
|
|
60531
|
+
schemaVersion: z47.literal("assistant-schedule-readiness.v1"),
|
|
59859
60532
|
scheduleRef: opaqueRef,
|
|
59860
|
-
scheduleRevision:
|
|
59861
|
-
state:
|
|
60533
|
+
scheduleRevision: z47.number().int().positive(),
|
|
60534
|
+
state: z47.enum(["ready", "blocked"]),
|
|
59862
60535
|
planDigest: DigestSchema,
|
|
59863
60536
|
grantSetDigest: DigestSchema,
|
|
59864
60537
|
readinessDigest: DigestSchema,
|
|
59865
|
-
facts:
|
|
59866
|
-
blockers:
|
|
59867
|
-
warnings:
|
|
60538
|
+
facts: z47.array(ScheduleReadinessFactSchema).max(500),
|
|
60539
|
+
blockers: z47.array(readinessIssue).max(200),
|
|
60540
|
+
warnings: z47.array(readinessIssue).max(200),
|
|
59868
60541
|
evaluatedAt: isoTimestamp2
|
|
59869
60542
|
}).strict();
|
|
59870
60543
|
function resolveEffectiveBrowserGrant(raw) {
|
|
@@ -59897,7 +60570,7 @@ function canonicalJson2(value) {
|
|
|
59897
60570
|
return JSON.stringify(value);
|
|
59898
60571
|
}
|
|
59899
60572
|
function digest2(value) {
|
|
59900
|
-
return
|
|
60573
|
+
return createHash53("sha256").update(canonicalJson2(value)).digest("hex");
|
|
59901
60574
|
}
|
|
59902
60575
|
function validTimezone2(timezone) {
|
|
59903
60576
|
try {
|
|
@@ -60158,7 +60831,7 @@ async function evaluateScheduleReadiness(rawInput, dependencies) {
|
|
|
60158
60831
|
}
|
|
60159
60832
|
|
|
60160
60833
|
// src/api/personal-assistant-command-builder.ts
|
|
60161
|
-
import { createHash as
|
|
60834
|
+
import { createHash as createHash54 } from "crypto";
|
|
60162
60835
|
function canonicalJson3(value) {
|
|
60163
60836
|
return JSON.stringify(value, (_key, entry) => {
|
|
60164
60837
|
if (!entry || typeof entry !== "object" || Array.isArray(entry)) return entry;
|
|
@@ -60166,7 +60839,7 @@ function canonicalJson3(value) {
|
|
|
60166
60839
|
});
|
|
60167
60840
|
}
|
|
60168
60841
|
function digest3(value) {
|
|
60169
|
-
return
|
|
60842
|
+
return createHash54("sha256").update(canonicalJson3(value)).digest("hex");
|
|
60170
60843
|
}
|
|
60171
60844
|
function explicitControlIntent(text3) {
|
|
60172
60845
|
const normalized = text3.trim().toLowerCase();
|
|
@@ -60215,7 +60888,7 @@ async function buildPersonalAssistantCommand(context, input) {
|
|
|
60215
60888
|
}
|
|
60216
60889
|
|
|
60217
60890
|
// src/api/personal-assistant-consent-content.ts
|
|
60218
|
-
import { createHash as
|
|
60891
|
+
import { createHash as createHash55 } from "crypto";
|
|
60219
60892
|
var SUBMITTED_EVIDENCE = Object.freeze({
|
|
60220
60893
|
evidenceVersion: "twilio-toll-free-submission.2026-08-28.v1",
|
|
60221
60894
|
policyVersion: "2026-08-28.v1",
|
|
@@ -60278,7 +60951,7 @@ var ASSISTANT_ENROLLMENT_DISCLOSURE_TEXT = Object.freeze([
|
|
|
60278
60951
|
ASSISTANT_CONSENT_CONTENT_V1.retentionDisclosure,
|
|
60279
60952
|
ASSISTANT_CONSENT_CONTENT_V1.termsDisclosure
|
|
60280
60953
|
].join("\n\n"));
|
|
60281
|
-
var ASSISTANT_ENROLLMENT_DISCLOSURE_DIGEST =
|
|
60954
|
+
var ASSISTANT_ENROLLMENT_DISCLOSURE_DIGEST = createHash55("sha256").update(`${ASSISTANT_CONSENT_CONTENT_V1.policyVersion}\0${ASSISTANT_ENROLLMENT_DISCLOSURE_TEXT}`).digest("hex");
|
|
60282
60955
|
var ASSISTANT_ENROLLMENT_DISCLOSURE_PROJECTION = Object.freeze({
|
|
60283
60956
|
policyVersion: ASSISTANT_CONSENT_CONTENT_V1.policyVersion,
|
|
60284
60957
|
disclosureDigest: ASSISTANT_ENROLLMENT_DISCLOSURE_DIGEST,
|
|
@@ -60289,11 +60962,11 @@ var ASSISTANT_ENROLLMENT_DISCLOSURE_PROJECTION = Object.freeze({
|
|
|
60289
60962
|
});
|
|
60290
60963
|
|
|
60291
60964
|
// src/api/personal-assistant-lifecycle.ts
|
|
60292
|
-
import { createHash as
|
|
60293
|
-
import { z as
|
|
60965
|
+
import { createHash as createHash57, randomUUID as randomUUID44 } from "crypto";
|
|
60966
|
+
import { z as z48 } from "zod";
|
|
60294
60967
|
|
|
60295
60968
|
// src/api/personal-assistant-db.ts
|
|
60296
|
-
import { createHash as
|
|
60969
|
+
import { createHash as createHash56 } from "crypto";
|
|
60297
60970
|
import { Pool } from "pg";
|
|
60298
60971
|
|
|
60299
60972
|
// src/api/personal-assistant-schema.ts
|
|
@@ -60415,7 +61088,7 @@ function assistantDatabaseBindingFingerprint(value) {
|
|
|
60415
61088
|
if (!database) {
|
|
60416
61089
|
throw new AssistantDatabaseError("assistant_database_binding_invalid", "Personal Assistant database name is missing.");
|
|
60417
61090
|
}
|
|
60418
|
-
return
|
|
61091
|
+
return createHash56("sha256").update(`${normalizedNeonHost(parsed.hostname)}\0${database}`).digest("hex");
|
|
60419
61092
|
}
|
|
60420
61093
|
function assistantDatabaseRole(value) {
|
|
60421
61094
|
const role = decodeURIComponent(parseDatabaseUrl(value).username);
|
|
@@ -60557,10 +61230,10 @@ async function preflightAssistantRuntimeBinding() {
|
|
|
60557
61230
|
}
|
|
60558
61231
|
|
|
60559
61232
|
// src/api/personal-assistant-lifecycle.ts
|
|
60560
|
-
var opaqueRef2 =
|
|
60561
|
-
var digest4 =
|
|
60562
|
-
var isoTimestamp3 =
|
|
60563
|
-
var AssistantLifecycleOperationSchema =
|
|
61233
|
+
var opaqueRef2 = z48.string().trim().regex(/^[a-z][A-Za-z0-9_-]{2,159}$/);
|
|
61234
|
+
var digest4 = z48.string().regex(/^[a-f0-9]{64}$/);
|
|
61235
|
+
var isoTimestamp3 = z48.string().datetime({ offset: true });
|
|
61236
|
+
var AssistantLifecycleOperationSchema = z48.enum([
|
|
60564
61237
|
"export_data",
|
|
60565
61238
|
"remove_recipient",
|
|
60566
61239
|
"withdraw_consent",
|
|
@@ -60572,7 +61245,7 @@ var AssistantLifecycleOperationSchema = z46.enum([
|
|
|
60572
61245
|
"detach_number",
|
|
60573
61246
|
"release_number"
|
|
60574
61247
|
]);
|
|
60575
|
-
var AssistantLifecycleTargetKindSchema =
|
|
61248
|
+
var AssistantLifecycleTargetKindSchema = z48.enum([
|
|
60576
61249
|
"account",
|
|
60577
61250
|
"recipient",
|
|
60578
61251
|
"consent",
|
|
@@ -60607,24 +61280,24 @@ var ASSISTANT_LIFECYCLE_CONFIRMATION_PHRASES = Object.freeze({
|
|
|
60607
61280
|
detach_number: "DETACH NUMBER",
|
|
60608
61281
|
release_number: "RELEASE NUMBER"
|
|
60609
61282
|
});
|
|
60610
|
-
var AssistantLifecyclePreviewRequestSchema =
|
|
61283
|
+
var AssistantLifecyclePreviewRequestSchema = z48.object({
|
|
60611
61284
|
operation: AssistantLifecycleOperationSchema,
|
|
60612
|
-
target:
|
|
60613
|
-
reason:
|
|
61285
|
+
target: z48.object({ kind: AssistantLifecycleTargetKindSchema, targetRef: opaqueRef2 }).strict(),
|
|
61286
|
+
reason: z48.string().trim().min(3).max(240).optional()
|
|
60614
61287
|
}).strict().superRefine((value, context) => {
|
|
60615
61288
|
if (TARGET_BY_OPERATION[value.operation] !== value.target.kind) {
|
|
60616
61289
|
context.addIssue({ code: "custom", path: ["target", "kind"], message: "target kind does not match lifecycle operation" });
|
|
60617
61290
|
}
|
|
60618
61291
|
});
|
|
60619
|
-
var AssistantLifecycleAffectedGroupSchema =
|
|
60620
|
-
count:
|
|
60621
|
-
refs:
|
|
60622
|
-
truncated:
|
|
61292
|
+
var AssistantLifecycleAffectedGroupSchema = z48.object({
|
|
61293
|
+
count: z48.number().int().nonnegative().max(1e6),
|
|
61294
|
+
refs: z48.array(opaqueRef2).max(50),
|
|
61295
|
+
truncated: z48.boolean()
|
|
60623
61296
|
}).strict().superRefine((value, context) => {
|
|
60624
61297
|
if (value.refs.length > value.count) context.addIssue({ code: "custom", path: ["refs"], message: "references cannot exceed count" });
|
|
60625
61298
|
if (!value.truncated && value.refs.length !== value.count) context.addIssue({ code: "custom", path: ["refs"], message: "complete impact groups must include every reference" });
|
|
60626
61299
|
});
|
|
60627
|
-
var AssistantLifecycleImpactSchema =
|
|
61300
|
+
var AssistantLifecycleImpactSchema = z48.object({
|
|
60628
61301
|
schedules: AssistantLifecycleAffectedGroupSchema,
|
|
60629
61302
|
grants: AssistantLifecycleAffectedGroupSchema,
|
|
60630
61303
|
conversations: AssistantLifecycleAffectedGroupSchema,
|
|
@@ -60634,21 +61307,21 @@ var AssistantLifecycleImpactSchema = z46.object({
|
|
|
60634
61307
|
connections: AssistantLifecycleAffectedGroupSchema,
|
|
60635
61308
|
numbers: AssistantLifecycleAffectedGroupSchema
|
|
60636
61309
|
}).strict();
|
|
60637
|
-
var AssistantLifecycleMinimumAuditSchema =
|
|
60638
|
-
category:
|
|
60639
|
-
reason:
|
|
61310
|
+
var AssistantLifecycleMinimumAuditSchema = z48.object({
|
|
61311
|
+
category: z48.enum(["consent", "suppression", "approval", "receipt", "audit", "registration", "released_number"]),
|
|
61312
|
+
reason: z48.string().trim().min(3).max(160),
|
|
60640
61313
|
retainedUntil: isoTimestamp3.nullable()
|
|
60641
61314
|
}).strict();
|
|
60642
|
-
var AssistantLifecyclePreviewSchema =
|
|
61315
|
+
var AssistantLifecyclePreviewSchema = z48.object({
|
|
60643
61316
|
lifecycleRef: opaqueRef2,
|
|
60644
61317
|
operation: AssistantLifecycleOperationSchema,
|
|
60645
|
-
target:
|
|
60646
|
-
state:
|
|
61318
|
+
target: z48.object({ kind: AssistantLifecycleTargetKindSchema, targetRef: opaqueRef2 }).strict(),
|
|
61319
|
+
state: z48.literal("awaiting_confirmation"),
|
|
60647
61320
|
previewDigest: digest4,
|
|
60648
|
-
confirmationPhrase:
|
|
60649
|
-
irreversible:
|
|
61321
|
+
confirmationPhrase: z48.string().min(3).max(64),
|
|
61322
|
+
irreversible: z48.boolean(),
|
|
60650
61323
|
impact: AssistantLifecycleImpactSchema,
|
|
60651
|
-
minimumAudit:
|
|
61324
|
+
minimumAudit: z48.array(AssistantLifecycleMinimumAuditSchema).min(1).max(10),
|
|
60652
61325
|
createdAt: isoTimestamp3,
|
|
60653
61326
|
expiresAt: isoTimestamp3
|
|
60654
61327
|
}).strict().superRefine((value, context) => {
|
|
@@ -60659,30 +61332,30 @@ var AssistantLifecyclePreviewSchema = z46.object({
|
|
|
60659
61332
|
context.addIssue({ code: "custom", path: ["expiresAt"], message: "preview must expire after creation" });
|
|
60660
61333
|
}
|
|
60661
61334
|
});
|
|
60662
|
-
var AssistantLifecycleConfirmationSchema =
|
|
61335
|
+
var AssistantLifecycleConfirmationSchema = z48.object({
|
|
60663
61336
|
previewDigest: digest4,
|
|
60664
|
-
confirmationPhrase:
|
|
60665
|
-
acknowledgeIrreversible:
|
|
61337
|
+
confirmationPhrase: z48.string().min(3).max(64),
|
|
61338
|
+
acknowledgeIrreversible: z48.boolean()
|
|
60666
61339
|
}).strict();
|
|
60667
|
-
var AssistantLifecycleReconciliationItemSchema =
|
|
61340
|
+
var AssistantLifecycleReconciliationItemSchema = z48.object({
|
|
60668
61341
|
reconciliationRef: opaqueRef2,
|
|
60669
|
-
kind:
|
|
61342
|
+
kind: z48.enum(["provider_disconnect", "provider_number_detach", "provider_number_release", "artifact_purge", "memory_purge"]),
|
|
60670
61343
|
targetRef: opaqueRef2,
|
|
60671
|
-
state:
|
|
60672
|
-
retrySafety:
|
|
60673
|
-
nextAction:
|
|
61344
|
+
state: z48.enum(["awaiting_provider", "pending_cleanup", "outcome_unknown"]),
|
|
61345
|
+
retrySafety: z48.enum(["reconcile_first", "operator_only", "not_retryable"]),
|
|
61346
|
+
nextAction: z48.string().trim().min(3).max(160)
|
|
60674
61347
|
}).strict();
|
|
60675
|
-
var AssistantLifecycleReceiptSchema =
|
|
61348
|
+
var AssistantLifecycleReceiptSchema = z48.object({
|
|
60676
61349
|
lifecycleRef: opaqueRef2,
|
|
60677
61350
|
operation: AssistantLifecycleOperationSchema,
|
|
60678
|
-
target:
|
|
60679
|
-
state:
|
|
61351
|
+
target: z48.object({ kind: AssistantLifecycleTargetKindSchema, targetRef: opaqueRef2 }).strict(),
|
|
61352
|
+
state: z48.enum(["completed", "reconciliation_required", "cancelled", "failed"]),
|
|
60680
61353
|
previewDigest: digest4,
|
|
60681
61354
|
paused: AssistantLifecycleImpactSchema,
|
|
60682
|
-
deleted:
|
|
61355
|
+
deleted: z48.object({ categories: z48.array(z48.string().regex(/^[a-z][a-z0-9_]{2,63}$/)).max(20), count: z48.number().int().nonnegative() }).strict(),
|
|
60683
61356
|
exportRef: opaqueRef2.nullable(),
|
|
60684
|
-
minimumAudit:
|
|
60685
|
-
unresolved:
|
|
61357
|
+
minimumAudit: z48.array(AssistantLifecycleMinimumAuditSchema).min(1).max(10),
|
|
61358
|
+
unresolved: z48.array(AssistantLifecycleReconciliationItemSchema).max(25),
|
|
60686
61359
|
irreversibleAt: isoTimestamp3.nullable(),
|
|
60687
61360
|
completedAt: isoTimestamp3
|
|
60688
61361
|
}).strict().superRefine((value, context) => {
|
|
@@ -60703,7 +61376,7 @@ var AssistantLifecycleError = class extends Error {
|
|
|
60703
61376
|
};
|
|
60704
61377
|
|
|
60705
61378
|
// src/api/personal-assistant-service.ts
|
|
60706
|
-
import { createHash as
|
|
61379
|
+
import { createHash as createHash58 } from "crypto";
|
|
60707
61380
|
var PERSONAL_ASSISTANT_INTENT_ENVELOPE_VERSION = "assistant-intent-envelope.v1";
|
|
60708
61381
|
var CONTROL_INTENTS = /* @__PURE__ */ new Set(["help", "status", "approve", "reject", "cancel"]);
|
|
60709
61382
|
var EXPLICIT_TASK_INTENTS = /* @__PURE__ */ new Set([
|
|
@@ -60869,7 +61542,7 @@ function canonicalServiceJson(value) {
|
|
|
60869
61542
|
});
|
|
60870
61543
|
}
|
|
60871
61544
|
function serviceDigest(value) {
|
|
60872
|
-
return
|
|
61545
|
+
return createHash58("sha256").update(canonicalServiceJson(value)).digest("hex");
|
|
60873
61546
|
}
|
|
60874
61547
|
function serviceReceipt(idempotencyKey4, requestDigest2, occurredAt, state2, result3, error = null) {
|
|
60875
61548
|
const receiptRef = `receipt_${serviceDigest({ idempotencyKey: idempotencyKey4, requestDigest: requestDigest2 }).slice(0, 32)}`;
|
|
@@ -62293,10 +62966,10 @@ function getPersonalAssistantService() {
|
|
|
62293
62966
|
|
|
62294
62967
|
// src/api/twilio-webhook-routes.ts
|
|
62295
62968
|
import twilio3 from "twilio";
|
|
62296
|
-
import { Hono as
|
|
62969
|
+
import { Hono as Hono41 } from "hono";
|
|
62297
62970
|
|
|
62298
62971
|
// src/api/personal-assistant-observability.ts
|
|
62299
|
-
import { createHash as
|
|
62972
|
+
import { createHash as createHash59 } from "crypto";
|
|
62300
62973
|
var OPAQUE_TRACE_REF = /^trace_[A-Za-z0-9_-]{8,128}$/u;
|
|
62301
62974
|
var KINDS = /* @__PURE__ */ new Set([
|
|
62302
62975
|
"purchase_unknown",
|
|
@@ -62772,7 +63445,7 @@ function handlerForRuntime(runtime, kind) {
|
|
|
62772
63445
|
return createTwilioWebhookHandler(kind === "inbound" ? { ...shared, handleInbound: runtime.inboundAdmissionService ? createTwilioInboundAdmissionHandler(runtime.inboundAdmissionService) : createTwilioInboundSmsHandler(runtime.messagingService) } : { ...shared, handleStatus: createTwilioDeliveryStatusHandler(runtime.messagingService) });
|
|
62773
63446
|
}
|
|
62774
63447
|
function buildTwilioWebhookApp(resolveRuntime) {
|
|
62775
|
-
const app2 = new
|
|
63448
|
+
const app2 = new Hono41();
|
|
62776
63449
|
app2.get("/health", (c) => c.json({ ok: true, component: "twilio-webhook-boundary" }));
|
|
62777
63450
|
for (const [path5, kind] of [["/inbound", "inbound"], ["/status", "status"]]) {
|
|
62778
63451
|
app2.post(path5, async (c) => {
|
|
@@ -62993,7 +63666,7 @@ function payloadWithout(input, ...keys) {
|
|
|
62993
63666
|
return Object.fromEntries(Object.entries(input).filter(([key3, value]) => !omitted.has(key3) && value !== void 0));
|
|
62994
63667
|
}
|
|
62995
63668
|
function personalAssistantMessagingServiceReviewDigest(review) {
|
|
62996
|
-
return
|
|
63669
|
+
return createHash60("sha256").update(JSON.stringify({
|
|
62997
63670
|
schemaVersion: "assistant-messaging-service-review.v1",
|
|
62998
63671
|
numberRef: review.numberRef,
|
|
62999
63672
|
connectionRef: review.connectionRef,
|
|
@@ -63127,7 +63800,7 @@ function ownerCaller(c) {
|
|
|
63127
63800
|
throw new OwnerRouteError("not_authenticated", "Authentication is required.", 401);
|
|
63128
63801
|
}
|
|
63129
63802
|
if (ownerUserId2 <= 0n) throw new OwnerRouteError("not_authenticated", "Authentication is required.", 401);
|
|
63130
|
-
const subjectRef = `owner_${
|
|
63803
|
+
const subjectRef = `owner_${createHash60("sha256").update(ownerUserId2.toString()).digest("hex").slice(0, 24)}`;
|
|
63131
63804
|
return { kind: "owner", surface: "rest", ownerUserId: ownerUserId2, subjectRef };
|
|
63132
63805
|
}
|
|
63133
63806
|
function enrollmentRequesterBinding(c, caller2) {
|
|
@@ -63179,10 +63852,10 @@ function publicError2(error, requestRef) {
|
|
|
63179
63852
|
} } };
|
|
63180
63853
|
}
|
|
63181
63854
|
function buildPersonalAssistantOwnerRoutes(options) {
|
|
63182
|
-
const app2 = new
|
|
63855
|
+
const app2 = new Hono42();
|
|
63183
63856
|
const now = options.now ?? (() => /* @__PURE__ */ new Date());
|
|
63184
|
-
const nextRequestRef = options.requestRef ?? (() => `request_${
|
|
63185
|
-
const route = (method, path5, mutating,
|
|
63857
|
+
const nextRequestRef = options.requestRef ?? (() => `request_${randomUUID45().replaceAll("-", "")}`);
|
|
63858
|
+
const route = (method, path5, mutating, call2) => {
|
|
63186
63859
|
app2[method](path5, async (c) => {
|
|
63187
63860
|
const requestRef = nextRequestRef();
|
|
63188
63861
|
try {
|
|
@@ -63190,7 +63863,7 @@ function buildPersonalAssistantOwnerRoutes(options) {
|
|
|
63190
63863
|
const input = mutating ? await jsonBody(c) : pageInput(c);
|
|
63191
63864
|
input.idempotencyKey = requestIdentity(c, requestRef, mutating);
|
|
63192
63865
|
const service = options.service();
|
|
63193
|
-
const result3 = servicePayload(await
|
|
63866
|
+
const result3 = servicePayload(await call2(service, caller2, input, c));
|
|
63194
63867
|
const body3 = { data: result3.data, ...result3.receipt ? { receipt: result3.receipt } : {}, meta: {
|
|
63195
63868
|
request_ref: requestRef,
|
|
63196
63869
|
projection_version: PERSONAL_ASSISTANT_OWNER_PROJECTION_VERSION,
|
|
@@ -63235,10 +63908,10 @@ function buildPersonalAssistantOwnerRoutes(options) {
|
|
|
63235
63908
|
idempotencyKey: i.idempotencyKey,
|
|
63236
63909
|
assistant: payloadWithout(i)
|
|
63237
63910
|
}));
|
|
63238
|
-
const contextRoute = (method, path5, mutating, names,
|
|
63911
|
+
const contextRoute = (method, path5, mutating, names, call2) => {
|
|
63239
63912
|
route(method, path5, mutating, (service, caller2, input, context) => {
|
|
63240
63913
|
for (const name of names) input[name] = opaqueRef3(context, name);
|
|
63241
|
-
return
|
|
63914
|
+
return call2(service, caller2, input, context);
|
|
63242
63915
|
});
|
|
63243
63916
|
};
|
|
63244
63917
|
contextRoute("get", "/lifecycle/:lifecycleRef", false, ["lifecycleRef"], (s, c, i) => s.getDataLifecycle(c, i));
|
|
@@ -63456,8 +64129,8 @@ function buildPersonalAssistantOwnerRoutes(options) {
|
|
|
63456
64129
|
var personalAssistantOwnerApp = buildPersonalAssistantOwnerRoutes({ service: getPersonalAssistantService });
|
|
63457
64130
|
|
|
63458
64131
|
// src/api/personal-assistant-browser-handoff-routes.ts
|
|
63459
|
-
import { randomUUID as
|
|
63460
|
-
import { Hono as
|
|
64132
|
+
import { randomUUID as randomUUID46 } from "crypto";
|
|
64133
|
+
import { Hono as Hono43 } from "hono";
|
|
63461
64134
|
var PERSONAL_ASSISTANT_BROWSER_HANDOFF_PROJECTION_VERSION = "assistant-browser-handoff.v1";
|
|
63462
64135
|
var OPAQUE_REF2 = /^[a-z][a-z0-9]{1,31}_[A-Za-z0-9_-]{3,160}$/;
|
|
63463
64136
|
var IDEMPOTENCY_KEY2 = /^[A-Za-z0-9._~:/+-]{8,240}$/;
|
|
@@ -63567,9 +64240,9 @@ function controlUrl(raw) {
|
|
|
63567
64240
|
return url2;
|
|
63568
64241
|
}
|
|
63569
64242
|
function buildPersonalAssistantBrowserHandoffRoutes(options) {
|
|
63570
|
-
const app2 = new
|
|
64243
|
+
const app2 = new Hono43();
|
|
63571
64244
|
const now = options.now ?? (() => /* @__PURE__ */ new Date());
|
|
63572
|
-
const nextRequestRef = options.requestRef ?? (() => `request_${
|
|
64245
|
+
const nextRequestRef = options.requestRef ?? (() => `request_${randomUUID46().replaceAll("-", "")}`);
|
|
63573
64246
|
const json = async (c, operation, created = false) => {
|
|
63574
64247
|
const requestRef = nextRequestRef();
|
|
63575
64248
|
try {
|
|
@@ -63657,8 +64330,8 @@ function buildPersonalAssistantBrowserHandoffRoutes(options) {
|
|
|
63657
64330
|
}
|
|
63658
64331
|
|
|
63659
64332
|
// src/api/personal-assistant-browser-profile-routes.ts
|
|
63660
|
-
import { randomUUID as
|
|
63661
|
-
import { Hono as
|
|
64333
|
+
import { randomUUID as randomUUID47 } from "crypto";
|
|
64334
|
+
import { Hono as Hono44 } from "hono";
|
|
63662
64335
|
var PERSONAL_ASSISTANT_BROWSER_PROFILE_PROJECTION_VERSION = "assistant-browser-profile.v1";
|
|
63663
64336
|
var IDEMPOTENCY_KEY3 = /^[A-Za-z0-9._~:/+-]{8,240}$/;
|
|
63664
64337
|
var OPAQUE_REF3 = /^[a-z][a-z0-9]{1,31}_[A-Za-z0-9_-]{3,160}$/;
|
|
@@ -63817,10 +64490,10 @@ function publicError4(error, requestRef) {
|
|
|
63817
64490
|
};
|
|
63818
64491
|
}
|
|
63819
64492
|
function buildPersonalAssistantBrowserProfileRoutes(options) {
|
|
63820
|
-
const app2 = new
|
|
64493
|
+
const app2 = new Hono44();
|
|
63821
64494
|
const now = options.now ?? (() => /* @__PURE__ */ new Date());
|
|
63822
64495
|
const healthStaleAfterMs = options.healthStaleAfterMs ?? 15 * 6e4;
|
|
63823
|
-
const requestRef = options.requestRef ?? (() => `request_${
|
|
64496
|
+
const requestRef = options.requestRef ?? (() => `request_${randomUUID47().replaceAll("-", "")}`);
|
|
63824
64497
|
const respond = async (c, operation, created = false) => {
|
|
63825
64498
|
const ref6 = requestRef();
|
|
63826
64499
|
try {
|
|
@@ -63903,10 +64576,10 @@ function buildPersonalAssistantBrowserProfileRoutes(options) {
|
|
|
63903
64576
|
}
|
|
63904
64577
|
|
|
63905
64578
|
// src/api/personal-assistant-browser-production.ts
|
|
63906
|
-
import { createHash as
|
|
64579
|
+
import { createHash as createHash64, randomUUID as randomUUID52 } from "crypto";
|
|
63907
64580
|
|
|
63908
64581
|
// src/api/personal-assistant-browser-handoff-store.ts
|
|
63909
|
-
import { createHmac as createHmac12, randomUUID as
|
|
64582
|
+
import { createHmac as createHmac12, randomUUID as randomUUID48 } from "crypto";
|
|
63910
64583
|
var BrowserHandoffStoreError = class extends Error {
|
|
63911
64584
|
constructor(code, status) {
|
|
63912
64585
|
super(code);
|
|
@@ -63994,14 +64667,14 @@ function createPostgresPersonalAssistantBrowserHandoffStore(options) {
|
|
|
63994
64667
|
[row.owner_user_id, row.handoff_id, mode, now().toISOString()]
|
|
63995
64668
|
);
|
|
63996
64669
|
if (existing.rows[0]) return existing.rows[0].claim_ref;
|
|
63997
|
-
const claimRef = `claim_${
|
|
64670
|
+
const claimRef = `claim_${randomUUID48().replaceAll("-", "")}`;
|
|
63998
64671
|
const ceiling = Math.min(new Date(row.expires_at).getTime(), now().getTime() + (mode === "control" ? controlLifetimeMs : claimLifetimeMs));
|
|
63999
64672
|
if (ceiling <= now().getTime()) throw new BrowserHandoffStoreError("handoff_expired", 409);
|
|
64000
64673
|
await client2.query(
|
|
64001
64674
|
`INSERT INTO assistant.browser_handoff_claims
|
|
64002
64675
|
(owner_user_id,id,public_id,handoff_id,mode,state,claim_digest,expires_at,created_at)
|
|
64003
64676
|
VALUES ($1,$2,$3,$4,$5,'available',$6,$7::timestamptz,$8::timestamptz)`,
|
|
64004
|
-
[row.owner_user_id,
|
|
64677
|
+
[row.owner_user_id, randomUUID48(), claimRef, row.handoff_id, mode, claimDigest(claimRef), new Date(ceiling).toISOString(), now().toISOString()]
|
|
64005
64678
|
);
|
|
64006
64679
|
return claimRef;
|
|
64007
64680
|
}
|
|
@@ -64023,7 +64696,7 @@ function createPostgresPersonalAssistantBrowserHandoffStore(options) {
|
|
|
64023
64696
|
async function create(input) {
|
|
64024
64697
|
return transaction2(async (client2) => {
|
|
64025
64698
|
const owner5 = positiveOwner(input.ownerUserId);
|
|
64026
|
-
const takeoverRef = `takeover_${
|
|
64699
|
+
const takeoverRef = `takeover_${randomUUID48().replaceAll("-", "")}`;
|
|
64027
64700
|
const createdAt = now();
|
|
64028
64701
|
const expiresAt = new Date(createdAt.getTime() + absoluteLifetimeMs);
|
|
64029
64702
|
const inserted = await client2.query(
|
|
@@ -64038,7 +64711,7 @@ function createPostgresPersonalAssistantBrowserHandoffStore(options) {
|
|
|
64038
64711
|
) ${HANDOFF_SELECT} JOIN inserted ON inserted.id=handoff.id WHERE handoff.owner_user_id=$1`,
|
|
64039
64712
|
[
|
|
64040
64713
|
owner5,
|
|
64041
|
-
|
|
64714
|
+
randomUUID48(),
|
|
64042
64715
|
takeoverRef,
|
|
64043
64716
|
ref(input.profileRef, PROFILE_REF),
|
|
64044
64717
|
ref(input.loginBindingRef, LOGIN_REF),
|
|
@@ -64197,7 +64870,7 @@ function createPostgresPersonalAssistantBrowserHandoffStore(options) {
|
|
|
64197
64870
|
}
|
|
64198
64871
|
|
|
64199
64872
|
// src/api/personal-assistant-browser-profile-store.ts
|
|
64200
|
-
import { createHash as
|
|
64873
|
+
import { createHash as createHash61, createHmac as createHmac13, randomUUID as randomUUID49 } from "crypto";
|
|
64201
64874
|
import { domainToASCII } from "url";
|
|
64202
64875
|
var PersonalAssistantBrowserProfileStoreError = class extends Error {
|
|
64203
64876
|
constructor(code, message = code, status = code.endsWith("revision_conflict") ? 409 : code.endsWith("input_rejected") ? 400 : 404) {
|
|
@@ -64239,7 +64912,7 @@ function iso2(value) {
|
|
|
64239
64912
|
return value instanceof Date ? value.toISOString() : new Date(value).toISOString();
|
|
64240
64913
|
}
|
|
64241
64914
|
function newRef(prefix) {
|
|
64242
|
-
return `${prefix}_${
|
|
64915
|
+
return `${prefix}_${randomUUID49().replaceAll("-", "")}`;
|
|
64243
64916
|
}
|
|
64244
64917
|
function deterministicRef(prefix, key3, identity) {
|
|
64245
64918
|
return `${prefix}_${createHmac13("sha256", key3).update(`assistant.${prefix}\0${identity}`).digest("hex").slice(0, 32)}`;
|
|
@@ -64327,7 +65000,7 @@ function deriveBrowserProviderNamespaceDigest(keyInput, ownerUserId2, profileRef
|
|
|
64327
65000
|
}
|
|
64328
65001
|
function digestEvidence(value) {
|
|
64329
65002
|
const canonical3 = JSON.stringify(value, (_key, entry) => entry && typeof entry === "object" && !Array.isArray(entry) ? Object.fromEntries(Object.entries(entry).sort(([a], [b]) => a.localeCompare(b))) : entry);
|
|
64330
|
-
return
|
|
65003
|
+
return createHash61("sha256").update(canonical3).digest("hex");
|
|
64331
65004
|
}
|
|
64332
65005
|
function exactCapabilityList(value, allowed) {
|
|
64333
65006
|
if (!Array.isArray(value)) return [];
|
|
@@ -64442,7 +65115,7 @@ function createPostgresPersonalAssistantBrowserProfileStore(options) {
|
|
|
64442
65115
|
inserted.status,inserted.capability_summary,inserted.revision,inserted.last_verified_at,inserted.verification_digest,
|
|
64443
65116
|
inserted.created_at,inserted.updated_at FROM inserted`, [
|
|
64444
65117
|
owner5,
|
|
64445
|
-
|
|
65118
|
+
randomUUID49(),
|
|
64446
65119
|
profileRef,
|
|
64447
65120
|
input.assistantRef,
|
|
64448
65121
|
label2,
|
|
@@ -64521,7 +65194,7 @@ function createPostgresPersonalAssistantBrowserProfileStore(options) {
|
|
|
64521
65194
|
inserted.identity_label_masked,inserted.status,inserted.capability_summary,inserted.revision,inserted.last_verified_at,
|
|
64522
65195
|
inserted.verification_digest,inserted.created_at,inserted.updated_at FROM inserted`, [
|
|
64523
65196
|
owner5,
|
|
64524
|
-
|
|
65197
|
+
randomUUID49(),
|
|
64525
65198
|
ref6,
|
|
64526
65199
|
assertRef(input.profileRef, PROFILE_REF2, "profileRef"),
|
|
64527
65200
|
canonicalizeBrowserDomain(input.canonicalDomain),
|
|
@@ -64620,7 +65293,7 @@ function createPostgresPersonalAssistantBrowserProfileStore(options) {
|
|
|
64620
65293
|
verification.observed_status,verification.evidence_digest,verification.evidence_summary,verification.verified_at,
|
|
64621
65294
|
verification.created_at FROM verification`, [
|
|
64622
65295
|
owner5,
|
|
64623
|
-
|
|
65296
|
+
randomUUID49(),
|
|
64624
65297
|
newRef("bpver"),
|
|
64625
65298
|
profile.rows[0].id,
|
|
64626
65299
|
bindingId,
|
|
@@ -64678,7 +65351,7 @@ function createPostgresPersonalAssistantBrowserProfileStore(options) {
|
|
|
64678
65351
|
FROM assistant.assistants assistant WHERE assistant.owner_user_id=$1 AND assistant.public_id=$4 AND assistant.deleted_at IS NULL
|
|
64679
65352
|
ON CONFLICT (owner_user_id,public_id) DO NOTHING`, [
|
|
64680
65353
|
owner5,
|
|
64681
|
-
|
|
65354
|
+
randomUUID49(),
|
|
64682
65355
|
profileRef,
|
|
64683
65356
|
input.assistantRef,
|
|
64684
65357
|
assertSafeText(input.displayLabel ?? "Imported browser profile", "displayLabel", 120),
|
|
@@ -64699,7 +65372,7 @@ function createPostgresPersonalAssistantBrowserProfileStore(options) {
|
|
|
64699
65372
|
VALUES ($1,$2,$3,$4,$5,$6,$7,$8::jsonb,$9::timestamptz,$9::timestamptz)
|
|
64700
65373
|
ON CONFLICT (owner_user_id,public_id) DO NOTHING`, [
|
|
64701
65374
|
owner5,
|
|
64702
|
-
|
|
65375
|
+
randomUUID49(),
|
|
64703
65376
|
bindingRef,
|
|
64704
65377
|
existing.rows[0].id,
|
|
64705
65378
|
domain,
|
|
@@ -64733,7 +65406,7 @@ function createPostgresPersonalAssistantBrowserProfileStore(options) {
|
|
|
64733
65406
|
}
|
|
64734
65407
|
|
|
64735
65408
|
// src/api/personal-assistant-idempotency-store.ts
|
|
64736
|
-
import { createHash as
|
|
65409
|
+
import { createHash as createHash62, randomUUID as randomUUID50 } from "crypto";
|
|
64737
65410
|
var PersonalAssistantIdempotencyConflictError = class extends Error {
|
|
64738
65411
|
code = "idempotency_conflict";
|
|
64739
65412
|
status = 409;
|
|
@@ -64762,7 +65435,7 @@ function jsonValue(value) {
|
|
|
64762
65435
|
return JSON.parse(serialized);
|
|
64763
65436
|
}
|
|
64764
65437
|
function resultDigest(value) {
|
|
64765
|
-
return
|
|
65438
|
+
return createHash62("sha256").update(canonicalJson4(value)).digest("hex");
|
|
64766
65439
|
}
|
|
64767
65440
|
function timestamp3(value) {
|
|
64768
65441
|
return value instanceof Date ? value.toISOString() : new Date(value).toISOString();
|
|
@@ -64774,7 +65447,7 @@ function createPostgresPersonalAssistantIdempotencyStore(options = {}) {
|
|
|
64774
65447
|
return Object.freeze({
|
|
64775
65448
|
async run(input, work) {
|
|
64776
65449
|
const ownerUserId2 = input.ownerUserId.toString();
|
|
64777
|
-
const id2 =
|
|
65450
|
+
const id2 = randomUUID50();
|
|
64778
65451
|
const claim = await transaction2(async (client2) => {
|
|
64779
65452
|
const inserted = await client2.query(`
|
|
64780
65453
|
INSERT INTO assistant.owner_request_idempotency (
|
|
@@ -64816,8 +65489,8 @@ function createPostgresPersonalAssistantIdempotencyStore(options = {}) {
|
|
|
64816
65489
|
) VALUES ($1, $2, $3, 'system', 'assistant.idempotency.completed', $4, $5, $6, $7::jsonb, $8::timestamptz)
|
|
64817
65490
|
`, [
|
|
64818
65491
|
ownerUserId2,
|
|
64819
|
-
|
|
64820
|
-
`audit_${
|
|
65492
|
+
randomUUID50(),
|
|
65493
|
+
`audit_${randomUUID50()}`,
|
|
64821
65494
|
input.action,
|
|
64822
65495
|
input.idempotencyKey,
|
|
64823
65496
|
input.requestDigest,
|
|
@@ -64845,7 +65518,7 @@ function createPostgresPersonalAssistantIdempotencyStore(options = {}) {
|
|
|
64845
65518
|
}
|
|
64846
65519
|
|
|
64847
65520
|
// src/api/personal-assistant-browser-account-cleanup.ts
|
|
64848
|
-
import { createHash as
|
|
65521
|
+
import { createHash as createHash63, randomUUID as randomUUID51 } from "crypto";
|
|
64849
65522
|
function positiveOwner2(value) {
|
|
64850
65523
|
if (typeof value !== "bigint" || value <= 0n) throw new TypeError("positive ownerUserId is required");
|
|
64851
65524
|
return value.toString();
|
|
@@ -64904,10 +65577,10 @@ function createPersonalAssistantBrowserAccountCleanup(options) {
|
|
|
64904
65577
|
};
|
|
64905
65578
|
return Object.freeze({
|
|
64906
65579
|
schemaVersion: "assistant-browser-account-cleanup.v1",
|
|
64907
|
-
cleanupRef: `cleanup_${
|
|
65580
|
+
cleanupRef: `cleanup_${randomUUID51().replaceAll("-", "")}`,
|
|
64908
65581
|
state: "confirmed",
|
|
64909
65582
|
...evidence,
|
|
64910
|
-
evidenceDigest:
|
|
65583
|
+
evidenceDigest: createHash63("sha256").update(JSON.stringify(evidence)).digest("hex")
|
|
64911
65584
|
});
|
|
64912
65585
|
};
|
|
64913
65586
|
}
|
|
@@ -64934,7 +65607,7 @@ var VERIFIED_BROWSER_CAPABILITIES = Object.freeze([
|
|
|
64934
65607
|
"download"
|
|
64935
65608
|
]);
|
|
64936
65609
|
function digest5(value) {
|
|
64937
|
-
return
|
|
65610
|
+
return createHash64("sha256").update(JSON.stringify(value, (_key, entry) => {
|
|
64938
65611
|
if (typeof entry === "bigint") return entry.toString();
|
|
64939
65612
|
if (!entry || typeof entry !== "object" || Array.isArray(entry)) return entry;
|
|
64940
65613
|
return Object.fromEntries(Object.entries(entry).sort(([a], [b]) => a.localeCompare(b)));
|
|
@@ -64966,13 +65639,13 @@ function handoffError(error) {
|
|
|
64966
65639
|
}
|
|
64967
65640
|
function receipt2(data, replayed, revision = 1) {
|
|
64968
65641
|
return { data, receipt: {
|
|
64969
|
-
receiptRef: `receipt_${
|
|
65642
|
+
receiptRef: `receipt_${randomUUID52().replaceAll("-", "")}`,
|
|
64970
65643
|
state: replayed ? "reused" : "confirmed",
|
|
64971
65644
|
revision
|
|
64972
65645
|
} };
|
|
64973
65646
|
}
|
|
64974
65647
|
function handoffReceipt(data, replayed) {
|
|
64975
|
-
return { data, receipt: { receiptRef: `receipt_${
|
|
65648
|
+
return { data, receipt: { receiptRef: `receipt_${randomUUID52().replaceAll("-", "")}`, state: replayed ? "reused" : "confirmed" } };
|
|
64976
65649
|
}
|
|
64977
65650
|
function loginHealth(status) {
|
|
64978
65651
|
return status === "deleted" ? "revoked" : status;
|
|
@@ -65084,7 +65757,7 @@ function createPersonalAssistantBrowserProductionDependencies(options) {
|
|
|
65084
65757
|
async createProfile(ownerUserId2, input) {
|
|
65085
65758
|
try {
|
|
65086
65759
|
const result3 = await run(ownerUserId2, "assistant.browser-profile.create", input.idempotencyKey, input, async () => {
|
|
65087
|
-
const profileRef = `bprof_${
|
|
65760
|
+
const profileRef = `bprof_${randomUUID52().replaceAll("-", "")}`;
|
|
65088
65761
|
const scope = { ownerRef: personalAssistantBrowserOwnerRef(ownerUserId2), profileRef };
|
|
65089
65762
|
await runtime.ensureProfile(scope);
|
|
65090
65763
|
try {
|
|
@@ -65147,7 +65820,7 @@ function createPersonalAssistantBrowserProductionDependencies(options) {
|
|
|
65147
65820
|
const result3 = await run(ownerUserId2, "assistant.browser-login.begin", input.idempotencyKey, input, async () => {
|
|
65148
65821
|
const profile = await profiles2.getProfile(ownerUserId2, input.profileRef);
|
|
65149
65822
|
if (!profile) throw new PersonalAssistantBrowserProfileStoreError("browser_profile_not_found");
|
|
65150
|
-
const loginBindingRef = `blogin_${
|
|
65823
|
+
const loginBindingRef = `blogin_${randomUUID52().replaceAll("-", "")}`;
|
|
65151
65824
|
const session = await openLoginSetup(ownerUserId2, profile.profileRef, loginBindingRef, input.canonicalDomain);
|
|
65152
65825
|
try {
|
|
65153
65826
|
const binding = await profiles2.createLoginBinding({
|
|
@@ -65502,19 +66175,19 @@ var personalAssistantBrowserHandoffApp = buildPersonalAssistantBrowserHandoffRou
|
|
|
65502
66175
|
});
|
|
65503
66176
|
|
|
65504
66177
|
// src/api/personal-assistant-worker-composition.ts
|
|
65505
|
-
import { Hono as
|
|
66178
|
+
import { Hono as Hono46 } from "hono";
|
|
65506
66179
|
|
|
65507
66180
|
// src/api/personal-assistant-worker-routes.ts
|
|
65508
|
-
import { createHash as
|
|
65509
|
-
import { Hono as
|
|
65510
|
-
import { z as
|
|
66181
|
+
import { createHash as createHash65, createPublicKey, verify as verify2 } from "crypto";
|
|
66182
|
+
import { Hono as Hono45 } from "hono";
|
|
66183
|
+
import { z as z49 } from "zod";
|
|
65511
66184
|
var PERSONAL_ASSISTANT_WORKER_API_PREFIX = "/api/private/v1/assistant-worker";
|
|
65512
66185
|
var PERSONAL_ASSISTANT_WORKER_SIGNATURE_VERSION = "assistant-worker-signature.v1";
|
|
65513
66186
|
var PERSONAL_ASSISTANT_WORKER_MAX_BODY_BYTES = 262144;
|
|
65514
66187
|
var PERSONAL_ASSISTANT_WORKER_SIGNATURE_TTL_MS = 6e4;
|
|
65515
66188
|
var PERSONAL_ASSISTANT_WORKER_IDENTITY_TTL_MS = 3e5;
|
|
65516
|
-
var OPAQUE_REF4 =
|
|
65517
|
-
var ISO_TIME =
|
|
66189
|
+
var OPAQUE_REF4 = z49.string().regex(/^[a-z][a-z0-9]{1,31}_[A-Za-z0-9_-]{3,160}$/);
|
|
66190
|
+
var ISO_TIME = z49.string().datetime({ offset: true });
|
|
65518
66191
|
var FORBIDDEN_AUTHORITY_KEY2 = /^(?:owner(?:User)?Id|owner_user_id|caller|subjectRef|table|tableName|sql|query|statement)$/i;
|
|
65519
66192
|
var PRIVATE_KEY2 = /(?:accessToken|refreshToken|authToken|accountSid|providerSid|privateKey|clientSecret|databaseUrl|signedUrl)/i;
|
|
65520
66193
|
var AssistantWorkerRouteError = class extends Error {
|
|
@@ -65535,11 +66208,11 @@ function canonicalJson5(value) {
|
|
|
65535
66208
|
return JSON.stringify(value);
|
|
65536
66209
|
}
|
|
65537
66210
|
function personalAssistantWorkerBodyDigest(rawBody) {
|
|
65538
|
-
return
|
|
66211
|
+
return createHash65("sha256").update(rawBody, "utf8").digest("hex");
|
|
65539
66212
|
}
|
|
65540
66213
|
function personalAssistantPlanDigest(plan) {
|
|
65541
66214
|
const { planRef: _planRef, planDigest: _planDigest, immutable: _immutable, createdAt: _createdAt, ...proposal } = plan;
|
|
65542
|
-
return
|
|
66215
|
+
return createHash65("sha256").update(canonicalJson5(proposal)).digest("hex");
|
|
65543
66216
|
}
|
|
65544
66217
|
function personalAssistantWorkerSigningPayload(input) {
|
|
65545
66218
|
return [
|
|
@@ -65563,7 +66236,7 @@ function inspectWorkerInput(value) {
|
|
|
65563
66236
|
}
|
|
65564
66237
|
}
|
|
65565
66238
|
function strictObject(shape) {
|
|
65566
|
-
return
|
|
66239
|
+
return z49.object(shape).strict();
|
|
65567
66240
|
}
|
|
65568
66241
|
var BindingSchema = {
|
|
65569
66242
|
executionRef: OPAQUE_REF4,
|
|
@@ -65573,25 +66246,25 @@ var BindingSchema = {
|
|
|
65573
66246
|
};
|
|
65574
66247
|
var RegistrationSchema = strictObject({
|
|
65575
66248
|
idempotencyKey: IdempotencyKeySchema,
|
|
65576
|
-
runtimeVersion:
|
|
65577
|
-
capabilities:
|
|
66249
|
+
runtimeVersion: z49.string().trim().min(1).max(80),
|
|
66250
|
+
capabilities: z49.array(z49.string().regex(/^[a-z][a-z0-9_.-]{1,80}$/)).max(100)
|
|
65578
66251
|
});
|
|
65579
66252
|
var HealthSchema = strictObject({ idempotencyKey: IdempotencyKeySchema, heartbeat: WorkerHeartbeatSchema });
|
|
65580
66253
|
var SignedWorkerClaimSchema = strictObject({
|
|
65581
|
-
schemaVersion:
|
|
66254
|
+
schemaVersion: z49.literal("assistant-worker-claim-envelope.v1"),
|
|
65582
66255
|
keyRef: OPAQUE_REF4,
|
|
65583
66256
|
createdAt: ISO_TIME,
|
|
65584
66257
|
bodyDigest: DigestSchema,
|
|
65585
66258
|
body: WorkerClaimSchema,
|
|
65586
|
-
signature:
|
|
66259
|
+
signature: z49.string().regex(/^[A-Za-z0-9_-]{40,160}$/)
|
|
65587
66260
|
});
|
|
65588
66261
|
var WakeSchema = strictObject({ ...BindingSchema, idempotencyKey: IdempotencyKeySchema });
|
|
65589
66262
|
var CycleSchema = strictObject({ ...BindingSchema, idempotencyKey: IdempotencyKeySchema, cycle: CycleCommandSchema });
|
|
65590
66263
|
var PlanSchema = strictObject({ ...BindingSchema, idempotencyKey: IdempotencyKeySchema, plan: AssistantPlanSchema });
|
|
65591
66264
|
var PolicyLeaseRequestSchema = strictObject({
|
|
65592
|
-
schemaVersion:
|
|
66265
|
+
schemaVersion: z49.literal("assistant-policy-lease-request.v1"),
|
|
65593
66266
|
requestRef: OPAQUE_REF4,
|
|
65594
|
-
requestNonce:
|
|
66267
|
+
requestNonce: z49.string().regex(/^[A-Za-z0-9_-]{32,128}$/),
|
|
65595
66268
|
ownerRef: OPAQUE_REF4,
|
|
65596
66269
|
workerRef: OPAQUE_REF4,
|
|
65597
66270
|
cycleRef: OPAQUE_REF4,
|
|
@@ -65603,27 +66276,27 @@ var PolicyLeaseRequestSchema = strictObject({
|
|
|
65603
66276
|
planDigest: DigestSchema,
|
|
65604
66277
|
stepRef: OPAQUE_REF4,
|
|
65605
66278
|
actionDigest: DigestSchema,
|
|
65606
|
-
operation:
|
|
66279
|
+
operation: z49.string().min(1).max(160),
|
|
65607
66280
|
argumentDigest: DigestSchema,
|
|
65608
66281
|
connectionRef: OPAQUE_REF4,
|
|
65609
66282
|
profileRef: OPAQUE_REF4,
|
|
65610
66283
|
audienceDigest: DigestSchema.nullable(),
|
|
65611
|
-
estimatedSpend:
|
|
65612
|
-
requestedLeaseSeconds:
|
|
66284
|
+
estimatedSpend: z49.object({ currency: z49.string().regex(/^[A-Z]{3}$/), amountMinor: z49.number().int().nonnegative().safe() }).strict().nullable(),
|
|
66285
|
+
requestedLeaseSeconds: z49.number().int().min(1).max(300)
|
|
65613
66286
|
});
|
|
65614
66287
|
var SignedPolicyLeaseRequestSchema = strictObject({
|
|
65615
|
-
schemaVersion:
|
|
66288
|
+
schemaVersion: z49.literal("assistant-signed-worker-request.v1"),
|
|
65616
66289
|
keyRef: OPAQUE_REF4,
|
|
65617
66290
|
createdAt: ISO_TIME,
|
|
65618
66291
|
expiresAt: ISO_TIME,
|
|
65619
66292
|
bodyDigest: DigestSchema,
|
|
65620
66293
|
body: PolicyLeaseRequestSchema,
|
|
65621
|
-
signature:
|
|
66294
|
+
signature: z49.string().regex(/^[A-Za-z0-9_-]{40,160}$/)
|
|
65622
66295
|
}).superRefine((value, context) => {
|
|
65623
66296
|
const lifetime = Date.parse(value.expiresAt) - Date.parse(value.createdAt);
|
|
65624
66297
|
if (lifetime <= 0 || lifetime > 6e4) context.addIssue({ code: "custom", path: ["expiresAt"], message: "signed worker requests must expire within one minute" });
|
|
65625
66298
|
});
|
|
65626
|
-
var MoneySchema =
|
|
66299
|
+
var MoneySchema = z49.object({ currency: z49.string().regex(/^[A-Z]{3}$/), amountMinor: z49.number().int().nonnegative().safe() }).strict();
|
|
65627
66300
|
var ApprovalSuspensionSchema = strictObject({
|
|
65628
66301
|
...BindingSchema,
|
|
65629
66302
|
idempotencyKey: IdempotencyKeySchema,
|
|
@@ -65638,8 +66311,8 @@ var ApprovalSuspensionSchema = strictObject({
|
|
|
65638
66311
|
spendLimit: MoneySchema.nullable(),
|
|
65639
66312
|
occurrenceRef: OPAQUE_REF4.nullable(),
|
|
65640
66313
|
expiresAt: ISO_TIME,
|
|
65641
|
-
nextAction:
|
|
65642
|
-
prompt:
|
|
66314
|
+
nextAction: z49.string().trim().min(1).max(500),
|
|
66315
|
+
prompt: z49.object({ web: z49.string().trim().min(1).max(1e3), sms: z49.string().trim().min(1).max(480).nullable() }).strict()
|
|
65643
66316
|
});
|
|
65644
66317
|
var DurableApprovalSuspensionSchema = strictObject({
|
|
65645
66318
|
approvalRef: OPAQUE_REF4,
|
|
@@ -65654,9 +66327,9 @@ var DurableApprovalSuspensionSchema = strictObject({
|
|
|
65654
66327
|
spendLimit: MoneySchema.nullable(),
|
|
65655
66328
|
occurrenceRef: OPAQUE_REF4.nullable(),
|
|
65656
66329
|
expiresAt: ISO_TIME,
|
|
65657
|
-
nextAction:
|
|
66330
|
+
nextAction: z49.string().trim().min(1).max(500),
|
|
65658
66331
|
approvalReceiptRef: OPAQUE_REF4,
|
|
65659
|
-
promptReceiptRefs:
|
|
66332
|
+
promptReceiptRefs: z49.array(OPAQUE_REF4).min(1).max(2)
|
|
65660
66333
|
});
|
|
65661
66334
|
var ApprovalResumeSchema = strictObject({
|
|
65662
66335
|
...BindingSchema,
|
|
@@ -65672,12 +66345,12 @@ var SettlementSchema = strictObject({
|
|
|
65672
66345
|
idempotencyKey: IdempotencyKeySchema,
|
|
65673
66346
|
allocationRef: OPAQUE_REF4,
|
|
65674
66347
|
actionReceiptRef: OPAQUE_REF4,
|
|
65675
|
-
settledMinor:
|
|
65676
|
-
currency:
|
|
66348
|
+
settledMinor: z49.number().int().nonnegative().safe(),
|
|
66349
|
+
currency: z49.string().regex(/^[A-Z]{3}$/)
|
|
65677
66350
|
});
|
|
65678
66351
|
function publicWorkerError(error) {
|
|
65679
66352
|
if (error instanceof AssistantWorkerRouteError) return { status: error.status, body: { error: { code: error.code, message: error.message } } };
|
|
65680
|
-
if (error instanceof
|
|
66353
|
+
if (error instanceof z49.ZodError || error instanceof TypeError) return { status: 400, body: { error: { code: "worker_validation_failed", message: "The worker request is invalid." } } };
|
|
65681
66354
|
return { status: 500, body: { error: { code: "worker_route_failed", message: "The worker request could not be completed." } } };
|
|
65682
66355
|
}
|
|
65683
66356
|
function identityKey(identity, nonce) {
|
|
@@ -65693,7 +66366,7 @@ function verifyPolicyEnvelope(identity, envelope, at) {
|
|
|
65693
66366
|
if (Date.parse(envelope.expiresAt) <= at.getTime() || Math.abs(at.getTime() - Date.parse(envelope.createdAt)) > 6e4) {
|
|
65694
66367
|
throw new AssistantWorkerRouteError("worker_policy_request_expired", "The policy request has expired.", 401);
|
|
65695
66368
|
}
|
|
65696
|
-
const expectedDigest =
|
|
66369
|
+
const expectedDigest = createHash65("sha256").update(canonicalJson5(envelope.body)).digest("hex");
|
|
65697
66370
|
if (expectedDigest !== envelope.bodyDigest) throw new AssistantWorkerRouteError("worker_policy_digest_mismatch", "The policy request digest does not match.", 401);
|
|
65698
66371
|
const { signature, ...unsigned } = envelope;
|
|
65699
66372
|
let valid = false;
|
|
@@ -65711,7 +66384,7 @@ function verifyClaimEnvelope(identity, envelope, at) {
|
|
|
65711
66384
|
if (Math.abs(at.getTime() - Date.parse(envelope.createdAt)) > PERSONAL_ASSISTANT_WORKER_SIGNATURE_TTL_MS) {
|
|
65712
66385
|
throw new AssistantWorkerRouteError("worker_claim_expired", "The worker claim has expired.", 401);
|
|
65713
66386
|
}
|
|
65714
|
-
const expectedDigest =
|
|
66387
|
+
const expectedDigest = createHash65("sha256").update(canonicalJson5(envelope.body)).digest("hex");
|
|
65715
66388
|
if (expectedDigest !== envelope.bodyDigest) throw new AssistantWorkerRouteError("worker_claim_digest_mismatch", "The claim digest does not match.", 401);
|
|
65716
66389
|
const { signature, ...unsigned } = envelope;
|
|
65717
66390
|
let valid = false;
|
|
@@ -65733,7 +66406,7 @@ function workerCaller(identity, executionRef) {
|
|
|
65733
66406
|
};
|
|
65734
66407
|
}
|
|
65735
66408
|
function buildPersonalAssistantWorkerRoutes(options) {
|
|
65736
|
-
const app2 = new
|
|
66409
|
+
const app2 = new Hono45();
|
|
65737
66410
|
const now = options.now ?? (() => /* @__PURE__ */ new Date());
|
|
65738
66411
|
const maxClockSkewMs = options.maxClockSkewMs ?? PERSONAL_ASSISTANT_WORKER_SIGNATURE_TTL_MS;
|
|
65739
66412
|
const maxIdentityLifetimeMs = options.maxIdentityLifetimeMs ?? PERSONAL_ASSISTANT_WORKER_IDENTITY_TTL_MS;
|
|
@@ -65789,7 +66462,7 @@ function buildPersonalAssistantWorkerRoutes(options) {
|
|
|
65789
66462
|
return c.json(mapped.body, mapped.status);
|
|
65790
66463
|
}
|
|
65791
66464
|
});
|
|
65792
|
-
const route = (path5, schema, binding,
|
|
66465
|
+
const route = (path5, schema, binding, call2, rawResponse = false) => {
|
|
65793
66466
|
app2.post(path5, async (c) => {
|
|
65794
66467
|
try {
|
|
65795
66468
|
const identity = c.get("assistantWorker");
|
|
@@ -65817,7 +66490,7 @@ function buildPersonalAssistantWorkerRoutes(options) {
|
|
|
65817
66490
|
throw new AssistantWorkerRouteError("worker_binding_rejected", "The worker execution binding was not found.", 404);
|
|
65818
66491
|
}
|
|
65819
66492
|
}
|
|
65820
|
-
const data = await
|
|
66493
|
+
const data = await call2(identity, parsed);
|
|
65821
66494
|
return c.json(rawResponse ? data : { data, meta: { signature_version: PERSONAL_ASSISTANT_WORKER_SIGNATURE_VERSION } }, 200);
|
|
65822
66495
|
} catch (error) {
|
|
65823
66496
|
const mapped = publicWorkerError(error);
|
|
@@ -65993,7 +66666,7 @@ var configuredWorkerGraph = null;
|
|
|
65993
66666
|
function configurePersonalAssistantWorkerProduction(dependencies) {
|
|
65994
66667
|
if (configuredWorkerGraph) throw new PersonalAssistantWorkerCompositionError("Personal assistant worker routes are already configured.");
|
|
65995
66668
|
const routes = buildPersonalAssistantWorkerRoutes(composePersonalAssistantWorkerProduction(dependencies).routeOptions);
|
|
65996
|
-
const graph = new
|
|
66669
|
+
const graph = new Hono46();
|
|
65997
66670
|
graph.route(PERSONAL_ASSISTANT_WORKER_API_PREFIX, routes);
|
|
65998
66671
|
configuredWorkerGraph = graph;
|
|
65999
66672
|
}
|
|
@@ -66001,7 +66674,7 @@ function personalAssistantWorkerProductionReadiness() {
|
|
|
66001
66674
|
return Object.freeze({ configured: configuredWorkerGraph !== null, durablePortsRequired: true });
|
|
66002
66675
|
}
|
|
66003
66676
|
var personalAssistantWorkerProductionApp = (() => {
|
|
66004
|
-
const app2 = new
|
|
66677
|
+
const app2 = new Hono46();
|
|
66005
66678
|
app2.get("/ready", (c) => {
|
|
66006
66679
|
const readiness2 = personalAssistantWorkerProductionReadiness();
|
|
66007
66680
|
return c.json(readiness2, readiness2.configured ? 200 : 503);
|
|
@@ -66014,12 +66687,12 @@ var personalAssistantWorkerProductionApp = (() => {
|
|
|
66014
66687
|
})();
|
|
66015
66688
|
|
|
66016
66689
|
// src/api/personal-assistant-admin-routes.ts
|
|
66017
|
-
import { createHash as
|
|
66018
|
-
import { Hono as
|
|
66019
|
-
import { z as
|
|
66690
|
+
import { createHash as createHash67, createPublicKey as createPublicKey2 } from "crypto";
|
|
66691
|
+
import { Hono as Hono47 } from "hono";
|
|
66692
|
+
import { z as z50 } from "zod";
|
|
66020
66693
|
|
|
66021
66694
|
// src/api/personal-assistant-kill-controls.ts
|
|
66022
|
-
import { createHash as
|
|
66695
|
+
import { createHash as createHash66, randomUUID as randomUUID53 } from "crypto";
|
|
66023
66696
|
var PERSONAL_ASSISTANT_KILL_SCOPES = [
|
|
66024
66697
|
"global",
|
|
66025
66698
|
"outbound",
|
|
@@ -66047,7 +66720,7 @@ function canonicalJson6(value) {
|
|
|
66047
66720
|
return JSON.stringify(value);
|
|
66048
66721
|
}
|
|
66049
66722
|
function digest6(value) {
|
|
66050
|
-
return
|
|
66723
|
+
return createHash66("sha256").update(canonicalJson6(value)).digest("hex");
|
|
66051
66724
|
}
|
|
66052
66725
|
function validateTarget(target) {
|
|
66053
66726
|
if (!PERSONAL_ASSISTANT_KILL_SCOPES.includes(target.scope)) throw new PersonalAssistantKillControlError("invalid_kill_control", "Invalid kill-control scope.", 400);
|
|
@@ -66167,7 +66840,7 @@ var PostgresPersonalAssistantKillControlStore = class {
|
|
|
66167
66840
|
const active = input.action === "activate";
|
|
66168
66841
|
if (state2.active === active) throw new PersonalAssistantKillControlError("kill_state_conflict", "Kill control is already in the requested state.", 409);
|
|
66169
66842
|
const revision = Number(state2.revision) + 1;
|
|
66170
|
-
const receiptRef = `kill_receipt_${
|
|
66843
|
+
const receiptRef = `kill_receipt_${randomUUID53().replaceAll("-", "")}`;
|
|
66171
66844
|
await client2.query(`UPDATE assistant.kill_switch_controls SET revision = $3, active = $4, reason_code = $5, actor_ref = $6, updated_at = $7
|
|
66172
66845
|
WHERE scope = $1 AND target_key = $2`, [input.target.scope, input.target.targetKey, revision, active, input.reasonCode, input.actorRef, input.occurredAt]);
|
|
66173
66846
|
const inserted = await client2.query(
|
|
@@ -66245,11 +66918,11 @@ var PersonalAssistantAdminRouteError = class extends Error {
|
|
|
66245
66918
|
code;
|
|
66246
66919
|
status;
|
|
66247
66920
|
};
|
|
66248
|
-
var OPAQUE_REF6 =
|
|
66249
|
-
var DigestSchema2 =
|
|
66250
|
-
var IdempotencyKeySchema2 =
|
|
66251
|
-
var WorkerRegistrationSchema =
|
|
66252
|
-
schemaVersion:
|
|
66921
|
+
var OPAQUE_REF6 = z50.string().regex(/^[a-z][a-z0-9]{1,31}_[A-Za-z0-9_-]{3,160}$/);
|
|
66922
|
+
var DigestSchema2 = z50.string().regex(/^[a-f0-9]{64}$/);
|
|
66923
|
+
var IdempotencyKeySchema2 = z50.string().regex(/^[A-Za-z0-9][A-Za-z0-9_.:-]{2,199}$/);
|
|
66924
|
+
var WorkerRegistrationSchema = z50.object({
|
|
66925
|
+
schemaVersion: z50.literal("assistant-worker-registration-request.v1"),
|
|
66253
66926
|
idempotencyKey: IdempotencyKeySchema2,
|
|
66254
66927
|
authorizedHostRef: OPAQUE_REF6,
|
|
66255
66928
|
ownerRef: OPAQUE_REF6,
|
|
@@ -66257,34 +66930,34 @@ var WorkerRegistrationSchema = z48.object({
|
|
|
66257
66930
|
workerRef: OPAQUE_REF6,
|
|
66258
66931
|
deviceKeyId: OPAQUE_REF6,
|
|
66259
66932
|
keyRef: OPAQUE_REF6,
|
|
66260
|
-
algorithm:
|
|
66261
|
-
publicKeyPem:
|
|
66933
|
+
algorithm: z50.literal("Ed25519"),
|
|
66934
|
+
publicKeyPem: z50.string().min(80).max(2e3),
|
|
66262
66935
|
publicKeySha256: DigestSchema2,
|
|
66263
|
-
runtimeVersion:
|
|
66264
|
-
capabilities:
|
|
66936
|
+
runtimeVersion: z50.string().trim().min(1).max(120),
|
|
66937
|
+
capabilities: z50.array(z50.enum([
|
|
66265
66938
|
"assistant.claim",
|
|
66266
66939
|
"assistant.health",
|
|
66267
66940
|
"assistant.execute"
|
|
66268
66941
|
])).min(1).max(3).refine((values) => new Set(values).size === values.length),
|
|
66269
|
-
expiresAt:
|
|
66942
|
+
expiresAt: z50.string().datetime({ offset: true })
|
|
66270
66943
|
}).strict();
|
|
66271
|
-
var WorkerRevocationSchema =
|
|
66272
|
-
schemaVersion:
|
|
66944
|
+
var WorkerRevocationSchema = z50.object({
|
|
66945
|
+
schemaVersion: z50.literal("assistant-worker-revocation-request.v1"),
|
|
66273
66946
|
idempotencyKey: IdempotencyKeySchema2,
|
|
66274
66947
|
authorizedHostRef: OPAQUE_REF6,
|
|
66275
66948
|
ownerRef: OPAQUE_REF6,
|
|
66276
66949
|
workerRef: OPAQUE_REF6,
|
|
66277
66950
|
deviceKeyId: OPAQUE_REF6,
|
|
66278
66951
|
keyRef: OPAQUE_REF6,
|
|
66279
|
-
reasonCode:
|
|
66952
|
+
reasonCode: z50.string().regex(/^[a-z][a-z0-9_.-]{2,80}$/)
|
|
66280
66953
|
}).strict();
|
|
66281
|
-
var KillMutationSchema =
|
|
66282
|
-
action:
|
|
66283
|
-
scope:
|
|
66954
|
+
var KillMutationSchema = z50.object({
|
|
66955
|
+
action: z50.enum(["activate", "deactivate"]),
|
|
66956
|
+
scope: z50.enum(PERSONAL_ASSISTANT_KILL_SCOPES),
|
|
66284
66957
|
targetRef: OPAQUE_REF6.nullable(),
|
|
66285
66958
|
idempotencyKey: IdempotencyKeySchema2,
|
|
66286
|
-
reasonCode:
|
|
66287
|
-
expectedRevision:
|
|
66959
|
+
reasonCode: z50.string().regex(/^[a-z][a-z0-9_.-]{2,80}$/),
|
|
66960
|
+
expectedRevision: z50.number().int().nonnegative().safe()
|
|
66288
66961
|
}).strict().superRefine((value, context) => {
|
|
66289
66962
|
const targeted = ["owner", "assistant", "number"].includes(value.scope);
|
|
66290
66963
|
if (targeted !== (value.targetRef !== null)) {
|
|
@@ -66315,7 +66988,7 @@ async function strictJson2(c, maxBodyBytes) {
|
|
|
66315
66988
|
}
|
|
66316
66989
|
}
|
|
66317
66990
|
function derivedRef(prefix, ...identity) {
|
|
66318
|
-
return `${prefix}_${
|
|
66991
|
+
return `${prefix}_${createHash67("sha256").update(identity.join("\0")).digest("base64url").slice(0, 32)}`;
|
|
66319
66992
|
}
|
|
66320
66993
|
function ownerUserId(target) {
|
|
66321
66994
|
if (!/^[1-9][0-9]{0,18}$/.test(target.targetKey)) {
|
|
@@ -66343,7 +67016,7 @@ async function resolvedTarget(options, scope, targetRef) {
|
|
|
66343
67016
|
return target;
|
|
66344
67017
|
}
|
|
66345
67018
|
function buildPersonalAssistantAdminRoutes(options) {
|
|
66346
|
-
const app2 = new
|
|
67019
|
+
const app2 = new Hono47();
|
|
66347
67020
|
const now = options.now ?? (() => /* @__PURE__ */ new Date());
|
|
66348
67021
|
const maxBodyBytes = options.maxBodyBytes ?? PERSONAL_ASSISTANT_ADMIN_MAX_BODY_BYTES;
|
|
66349
67022
|
app2.onError((error, c) => {
|
|
@@ -66360,7 +67033,7 @@ function buildPersonalAssistantAdminRoutes(options) {
|
|
|
66360
67033
|
});
|
|
66361
67034
|
app2.get("/kill-switches", async (c) => {
|
|
66362
67035
|
requireCapability(c.get("assistantAdmin"), "assistant.kill_switch.read");
|
|
66363
|
-
const scope =
|
|
67036
|
+
const scope = z50.enum(PERSONAL_ASSISTANT_KILL_SCOPES).safeParse(c.req.query("scope"));
|
|
66364
67037
|
const targetRaw = c.req.query("targetRef");
|
|
66365
67038
|
const parsedTarget = targetRaw === void 0 || targetRaw === "" ? { success: true, data: null } : OPAQUE_REF6.safeParse(targetRaw);
|
|
66366
67039
|
if (!scope.success) throw new PersonalAssistantAdminRouteError("invalid_kill_control", "Valid kill-control scope is required.", 400);
|
|
@@ -66401,7 +67074,7 @@ function buildPersonalAssistantAdminRoutes(options) {
|
|
|
66401
67074
|
const identity = c.get("assistantAdmin");
|
|
66402
67075
|
requireCapability(identity, "assistant.worker_registration.register");
|
|
66403
67076
|
const parsed = WorkerRegistrationSchema.safeParse(await strictJson2(c, maxBodyBytes));
|
|
66404
|
-
if (!parsed.success || Date.parse(parsed.data.expiresAt) <= now().getTime() || !/^-----BEGIN PUBLIC KEY-----\n[\s\S]+\n-----END PUBLIC KEY-----\n?$/.test(parsed.data.publicKeyPem) || /PRIVATE KEY|ENCRYPTED/.test(parsed.data.publicKeyPem) ||
|
|
67077
|
+
if (!parsed.success || Date.parse(parsed.data.expiresAt) <= now().getTime() || !/^-----BEGIN PUBLIC KEY-----\n[\s\S]+\n-----END PUBLIC KEY-----\n?$/.test(parsed.data.publicKeyPem) || /PRIVATE KEY|ENCRYPTED/.test(parsed.data.publicKeyPem) || createHash67("sha256").update(parsed.success ? parsed.data.publicKeyPem : "").digest("hex") !== (parsed.success ? parsed.data.publicKeySha256 : "")) {
|
|
66405
67078
|
throw new PersonalAssistantAdminRouteError("invalid_worker_registration", "Invalid worker registration request.", 400);
|
|
66406
67079
|
}
|
|
66407
67080
|
try {
|
|
@@ -66484,7 +67157,7 @@ var configuredAdminGraph = null;
|
|
|
66484
67157
|
function configurePersonalAssistantAdminProduction(options) {
|
|
66485
67158
|
if (configuredAdminGraph) throw new PersonalAssistantAdminRouteError("assistant_admin_already_configured", "Assistant administrator routes are already configured.", 409);
|
|
66486
67159
|
const routes = buildPersonalAssistantAdminRoutes(options);
|
|
66487
|
-
const graph = new
|
|
67160
|
+
const graph = new Hono47();
|
|
66488
67161
|
graph.route(PERSONAL_ASSISTANT_ADMIN_API_PREFIX, routes);
|
|
66489
67162
|
configuredAdminGraph = graph;
|
|
66490
67163
|
}
|
|
@@ -66492,7 +67165,7 @@ function personalAssistantAdminReadiness() {
|
|
|
66492
67165
|
return Object.freeze({ configured: configuredAdminGraph !== null, durablePortsRequired: true });
|
|
66493
67166
|
}
|
|
66494
67167
|
var personalAssistantAdminProductionApp = (() => {
|
|
66495
|
-
const app2 = new
|
|
67168
|
+
const app2 = new Hono47();
|
|
66496
67169
|
app2.get("/ready", (c) => {
|
|
66497
67170
|
const readiness2 = personalAssistantAdminReadiness();
|
|
66498
67171
|
return c.json(readiness2, readiness2.configured ? 200 : 503);
|
|
@@ -66502,7 +67175,7 @@ var personalAssistantAdminProductionApp = (() => {
|
|
|
66502
67175
|
})();
|
|
66503
67176
|
|
|
66504
67177
|
// src/api/personal-assistant-cron-routes.ts
|
|
66505
|
-
import { Hono as
|
|
67178
|
+
import { Hono as Hono48 } from "hono";
|
|
66506
67179
|
var PERSONAL_ASSISTANT_CRON_PREFIX = "/cron/assistant";
|
|
66507
67180
|
var handlers = null;
|
|
66508
67181
|
function configurePersonalAssistantCronProduction(next) {
|
|
@@ -66514,7 +67187,7 @@ function personalAssistantCronReadiness() {
|
|
|
66514
67187
|
return Object.freeze({ configured: handlers !== null, durableReconciliationRequired: true });
|
|
66515
67188
|
}
|
|
66516
67189
|
var personalAssistantCronProductionApp = (() => {
|
|
66517
|
-
const app2 = new
|
|
67190
|
+
const app2 = new Hono48();
|
|
66518
67191
|
app2.get("/ready", (c) => {
|
|
66519
67192
|
const readiness2 = personalAssistantCronReadiness();
|
|
66520
67193
|
return c.json(readiness2, readiness2.configured ? 200 : 503);
|
|
@@ -66527,24 +67200,24 @@ var personalAssistantCronProductionApp = (() => {
|
|
|
66527
67200
|
})();
|
|
66528
67201
|
|
|
66529
67202
|
// src/api/personal-assistant-production.ts
|
|
66530
|
-
import { createHash as
|
|
67203
|
+
import { createHash as createHash97 } from "crypto";
|
|
66531
67204
|
|
|
66532
67205
|
// src/api/personal-assistant-admin-production.ts
|
|
66533
|
-
import { createHash as
|
|
67206
|
+
import { createHash as createHash71 } from "crypto";
|
|
66534
67207
|
|
|
66535
67208
|
// src/api/personal-assistant-worker-store.ts
|
|
66536
|
-
import { createHash as
|
|
67209
|
+
import { createHash as createHash70, randomUUID as randomUUID55 } from "crypto";
|
|
66537
67210
|
|
|
66538
67211
|
// src/api/personal-assistant-repository.ts
|
|
66539
|
-
import { createHash as
|
|
67212
|
+
import { createHash as createHash69, randomBytes as randomBytes7, randomUUID as randomUUID54 } from "crypto";
|
|
66540
67213
|
|
|
66541
67214
|
// src/api/personal-assistant-wake-packet.ts
|
|
66542
|
-
import { createHash as
|
|
67215
|
+
import { createHash as createHash68 } from "crypto";
|
|
66543
67216
|
function stableJson(value) {
|
|
66544
67217
|
return JSON.stringify(value, (_key, entry) => !entry || typeof entry !== "object" || Array.isArray(entry) ? entry : Object.fromEntries(Object.entries(entry).sort(([a], [b]) => a.localeCompare(b))));
|
|
66545
67218
|
}
|
|
66546
67219
|
function stableDigest(value) {
|
|
66547
|
-
return
|
|
67220
|
+
return createHash68("sha256").update(stableJson(value)).digest("hex");
|
|
66548
67221
|
}
|
|
66549
67222
|
function deterministicWakePacketRef(snapshot) {
|
|
66550
67223
|
return `wake_${stableDigest({ assistantRef: snapshot.assistantRef, commandRef: snapshot.commandRef, cycleRef: snapshot.cycleRef, executionRef: snapshot.executionRef, contextVersionRef: snapshot.contextVersion.contextVersionRef }).slice(0, 32)}`;
|
|
@@ -66597,10 +67270,10 @@ function canonicalJson7(value) {
|
|
|
66597
67270
|
});
|
|
66598
67271
|
}
|
|
66599
67272
|
function digest7(value) {
|
|
66600
|
-
return
|
|
67273
|
+
return createHash69("sha256").update(canonicalJson7(value)).digest("hex");
|
|
66601
67274
|
}
|
|
66602
67275
|
function deterministicRef2(prefix, identity) {
|
|
66603
|
-
return `${prefix}_${
|
|
67276
|
+
return `${prefix}_${createHash69("sha256").update(identity).digest("hex").slice(0, 32)}`;
|
|
66604
67277
|
}
|
|
66605
67278
|
function messageCursor(message) {
|
|
66606
67279
|
return Buffer.from(JSON.stringify([message.occurredAt, message.messageRef])).toString("base64url");
|
|
@@ -66985,7 +67658,7 @@ function createPostgresPersonalAssistantRepositoryStore(options = {}) {
|
|
|
66985
67658
|
const stored = AssistantCommandSchema.parse(existing.rows[0].payload);
|
|
66986
67659
|
return { command: stored, receipt: receipt4, entity: stored };
|
|
66987
67660
|
}
|
|
66988
|
-
const commandId =
|
|
67661
|
+
const commandId = randomUUID54();
|
|
66989
67662
|
const inserted = await client2.query(`
|
|
66990
67663
|
INSERT INTO assistant.commands (
|
|
66991
67664
|
owner_user_id, id, public_id, assistant_id, conversation_id, command_type,
|
|
@@ -67027,7 +67700,7 @@ function createPostgresPersonalAssistantRepositoryStore(options = {}) {
|
|
|
67027
67700
|
)
|
|
67028
67701
|
`, [
|
|
67029
67702
|
ownerUserId2.toString(),
|
|
67030
|
-
|
|
67703
|
+
randomUUID54(),
|
|
67031
67704
|
receipt4.receiptRef,
|
|
67032
67705
|
commandId,
|
|
67033
67706
|
command.operation,
|
|
@@ -67096,7 +67769,7 @@ function createPostgresPersonalAssistantRepositoryStore(options = {}) {
|
|
|
67096
67769
|
`, [ownerUserId2.toString(), row.id]);
|
|
67097
67770
|
}
|
|
67098
67771
|
const token7 = randomBytes7(32).toString("base64url");
|
|
67099
|
-
const tokenHash5 =
|
|
67772
|
+
const tokenHash5 = createHash69("sha256").update(token7).digest("hex");
|
|
67100
67773
|
const leaseRef = deterministicRef2("lease", `${input.executionRef}\0${input.workerRef}\0${input.now}`);
|
|
67101
67774
|
const expiresAt = new Date(Date.parse(input.now) + input.leaseSeconds * 1e3).toISOString();
|
|
67102
67775
|
await client2.query(`
|
|
@@ -67104,7 +67777,7 @@ function createPostgresPersonalAssistantRepositoryStore(options = {}) {
|
|
|
67104
67777
|
owner_user_id, id, public_id, worker_id, execution_id, lease_token_hash,
|
|
67105
67778
|
state, claimed_at, heartbeat_at, expires_at
|
|
67106
67779
|
) VALUES ($1, $2, $3, $4, $5, $6, 'active', $7, $7, $8)
|
|
67107
|
-
`, [ownerUserId2.toString(),
|
|
67780
|
+
`, [ownerUserId2.toString(), randomUUID54(), leaseRef, worker.rows[0].id, row.id, tokenHash5, input.now, expiresAt]);
|
|
67108
67781
|
await client2.query(`
|
|
67109
67782
|
UPDATE assistant.executions
|
|
67110
67783
|
SET state = 'claimed', claimed_by_worker_id = $3, claim_token_hash = $4,
|
|
@@ -67181,7 +67854,7 @@ function createPostgresPersonalAssistantRepositoryStore(options = {}) {
|
|
|
67181
67854
|
RETURNING public_id
|
|
67182
67855
|
`, [
|
|
67183
67856
|
ownerUserId2.toString(),
|
|
67184
|
-
|
|
67857
|
+
randomUUID54(),
|
|
67185
67858
|
grant.grantRef,
|
|
67186
67859
|
grant.revision,
|
|
67187
67860
|
grant.authorityClass,
|
|
@@ -67238,7 +67911,7 @@ function createPostgresPersonalAssistantRepositoryStore(options = {}) {
|
|
|
67238
67911
|
RETURNING public_id
|
|
67239
67912
|
`, [
|
|
67240
67913
|
ownerUserId2.toString(),
|
|
67241
|
-
|
|
67914
|
+
randomUUID54(),
|
|
67242
67915
|
approval.approvalRef,
|
|
67243
67916
|
approval.requestedActionDigest,
|
|
67244
67917
|
approval.approvedArgumentDigest,
|
|
@@ -67371,7 +68044,7 @@ function createPostgresPersonalAssistantRepositoryStore(options = {}) {
|
|
|
67371
68044
|
RETURNING public_id
|
|
67372
68045
|
`, [
|
|
67373
68046
|
ownerUserId2.toString(),
|
|
67374
|
-
|
|
68047
|
+
randomUUID54(),
|
|
67375
68048
|
input.conversationRef,
|
|
67376
68049
|
input.participantDigest,
|
|
67377
68050
|
input.occurredAt,
|
|
@@ -67419,7 +68092,7 @@ function createPostgresPersonalAssistantRepositoryStore(options = {}) {
|
|
|
67419
68092
|
RETURNING public_id
|
|
67420
68093
|
`, [
|
|
67421
68094
|
ownerUserId2.toString(),
|
|
67422
|
-
|
|
68095
|
+
randomUUID54(),
|
|
67423
68096
|
message.messageRef,
|
|
67424
68097
|
message.direction,
|
|
67425
68098
|
message.providerAccountRef,
|
|
@@ -67462,7 +68135,7 @@ function createPostgresPersonalAssistantRepositoryStore(options = {}) {
|
|
|
67462
68135
|
provider_message_sid,provider_event_key,error_class,occurred_at
|
|
67463
68136
|
`, [
|
|
67464
68137
|
ownerUserId2.toString(),
|
|
67465
|
-
|
|
68138
|
+
randomUUID54(),
|
|
67466
68139
|
event2.deliveryEventRef,
|
|
67467
68140
|
event2.providerAccountRef,
|
|
67468
68141
|
event2.providerMessageSid,
|
|
@@ -67511,7 +68184,7 @@ function createPostgresPersonalAssistantRepositoryStore(options = {}) {
|
|
|
67511
68184
|
RETURNING public_id, byte_digest
|
|
67512
68185
|
`, [
|
|
67513
68186
|
ownerUserId2.toString(),
|
|
67514
|
-
|
|
68187
|
+
randomUUID54(),
|
|
67515
68188
|
media.mediaRef,
|
|
67516
68189
|
media.providerAccountRef,
|
|
67517
68190
|
media.providerMediaSid,
|
|
@@ -67570,7 +68243,7 @@ function createPostgresPersonalAssistantRepositoryStore(options = {}) {
|
|
|
67570
68243
|
RETURNING public_id,version,manifest_digest,created_at
|
|
67571
68244
|
`, [
|
|
67572
68245
|
ownerUserId2.toString(),
|
|
67573
|
-
|
|
68246
|
+
randomUUID54(),
|
|
67574
68247
|
input.contextVersionRef,
|
|
67575
68248
|
input.version,
|
|
67576
68249
|
input.manifestDigest,
|
|
@@ -67599,7 +68272,7 @@ function createPostgresPersonalAssistantRepositoryStore(options = {}) {
|
|
|
67599
68272
|
RETURNING public_id,state,opened_at,updated_at,closed_at
|
|
67600
68273
|
`, [
|
|
67601
68274
|
ownerUserId2.toString(),
|
|
67602
|
-
|
|
68275
|
+
randomUUID54(),
|
|
67603
68276
|
cycle.cycleRef,
|
|
67604
68277
|
cycle.state,
|
|
67605
68278
|
cycle.openedAt,
|
|
@@ -67632,7 +68305,7 @@ function createPostgresPersonalAssistantRepositoryStore(options = {}) {
|
|
|
67632
68305
|
FROM assistant.wake_cycles cycle WHERE cycle.owner_user_id = $1 AND cycle.public_id = $9
|
|
67633
68306
|
`, [
|
|
67634
68307
|
ownerUserId2.toString(),
|
|
67635
|
-
|
|
68308
|
+
randomUUID54(),
|
|
67636
68309
|
transition.taskRef,
|
|
67637
68310
|
title,
|
|
67638
68311
|
transition.toState,
|
|
@@ -67666,7 +68339,7 @@ function createPostgresPersonalAssistantRepositoryStore(options = {}) {
|
|
|
67666
68339
|
RETURNING public_id,state,attempt,retry_class,terminal_at
|
|
67667
68340
|
`, [
|
|
67668
68341
|
ownerUserId2.toString(),
|
|
67669
|
-
|
|
68342
|
+
randomUUID54(),
|
|
67670
68343
|
execution.executionRef,
|
|
67671
68344
|
execution.planDigest,
|
|
67672
68345
|
execution.state,
|
|
@@ -67701,7 +68374,7 @@ function createPostgresPersonalAssistantRepositoryStore(options = {}) {
|
|
|
67701
68374
|
RETURNING runtime_version,health,occurred_at
|
|
67702
68375
|
`, [
|
|
67703
68376
|
ownerUserId2.toString(),
|
|
67704
|
-
|
|
68377
|
+
randomUUID54(),
|
|
67705
68378
|
relation.rows[0].worker_id,
|
|
67706
68379
|
relation.rows[0].lease_id,
|
|
67707
68380
|
heartbeat.sequence,
|
|
@@ -67786,7 +68459,7 @@ function createPostgresPersonalAssistantRepositoryStore(options = {}) {
|
|
|
67786
68459
|
RETURNING id
|
|
67787
68460
|
`, [
|
|
67788
68461
|
ownerUserId2.toString(),
|
|
67789
|
-
|
|
68462
|
+
randomUUID54(),
|
|
67790
68463
|
plan.planRef,
|
|
67791
68464
|
plan.planDigest,
|
|
67792
68465
|
JSON.stringify(plan),
|
|
@@ -67805,7 +68478,7 @@ function createPostgresPersonalAssistantRepositoryStore(options = {}) {
|
|
|
67805
68478
|
) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9::jsonb,$10,$11,$12,$13,$14)
|
|
67806
68479
|
`, [
|
|
67807
68480
|
ownerUserId2.toString(),
|
|
67808
|
-
|
|
68481
|
+
randomUUID54(),
|
|
67809
68482
|
step.stepRef,
|
|
67810
68483
|
inserted.rows[0].id,
|
|
67811
68484
|
step.position,
|
|
@@ -67845,7 +68518,7 @@ function createPostgresPersonalAssistantRepositoryStore(options = {}) {
|
|
|
67845
68518
|
RETURNING required_digest,decision,reason_code
|
|
67846
68519
|
`, [
|
|
67847
68520
|
ownerUserId2.toString(),
|
|
67848
|
-
|
|
68521
|
+
randomUUID54(),
|
|
67849
68522
|
barrier.barrierRef,
|
|
67850
68523
|
barrier.barrierKind,
|
|
67851
68524
|
barrier.decision,
|
|
@@ -67876,7 +68549,7 @@ function createPostgresPersonalAssistantRepositoryStore(options = {}) {
|
|
|
67876
68549
|
RETURNING public_id,authorized_minor,state
|
|
67877
68550
|
`, [
|
|
67878
68551
|
ownerUserId2.toString(),
|
|
67879
|
-
|
|
68552
|
+
randomUUID54(),
|
|
67880
68553
|
allocation.allocationRef,
|
|
67881
68554
|
allocation.kind,
|
|
67882
68555
|
allocation.idempotencyKey,
|
|
@@ -67990,7 +68663,7 @@ function createPostgresPersonalAssistantRepositoryStore(options = {}) {
|
|
|
67990
68663
|
ON CONFLICT (owner_user_id, public_id) DO NOTHING
|
|
67991
68664
|
`, [
|
|
67992
68665
|
ownerUserId2.toString(),
|
|
67993
|
-
|
|
68666
|
+
randomUUID54(),
|
|
67994
68667
|
contact.contactRef,
|
|
67995
68668
|
contact.displayName,
|
|
67996
68669
|
contact.phoneCiphertext,
|
|
@@ -68018,7 +68691,7 @@ function createPostgresPersonalAssistantRepositoryStore(options = {}) {
|
|
|
68018
68691
|
ON CONFLICT (owner_user_id, public_id) DO NOTHING
|
|
68019
68692
|
`, [
|
|
68020
68693
|
ownerUserId2.toString(),
|
|
68021
|
-
|
|
68694
|
+
randomUUID54(),
|
|
68022
68695
|
number.numberRef,
|
|
68023
68696
|
number.providerAccountRef,
|
|
68024
68697
|
number.providerNumberSid,
|
|
@@ -68050,7 +68723,7 @@ function createPostgresPersonalAssistantRepositoryStore(options = {}) {
|
|
|
68050
68723
|
ON CONFLICT (owner_user_id, public_id) DO NOTHING
|
|
68051
68724
|
`, [
|
|
68052
68725
|
ownerUserId2.toString(),
|
|
68053
|
-
|
|
68726
|
+
randomUUID54(),
|
|
68054
68727
|
conversation.conversationRef,
|
|
68055
68728
|
conversation.participantDigest,
|
|
68056
68729
|
conversation.occurredAt,
|
|
@@ -68072,7 +68745,7 @@ function createPostgresPersonalAssistantRepositoryStore(options = {}) {
|
|
|
68072
68745
|
ON CONFLICT (owner_user_id, public_id) DO NOTHING
|
|
68073
68746
|
`, [
|
|
68074
68747
|
ownerUserId2.toString(),
|
|
68075
|
-
|
|
68748
|
+
randomUUID54(),
|
|
68076
68749
|
message.messageRef,
|
|
68077
68750
|
message.direction,
|
|
68078
68751
|
message.providerAccountRef,
|
|
@@ -68101,7 +68774,7 @@ function createPostgresPersonalAssistantRepositoryStore(options = {}) {
|
|
|
68101
68774
|
RETURNING id
|
|
68102
68775
|
`, [
|
|
68103
68776
|
ownerUserId2.toString(),
|
|
68104
|
-
|
|
68777
|
+
randomUUID54(),
|
|
68105
68778
|
schedule.scheduleRef,
|
|
68106
68779
|
schedule.sourceSystem,
|
|
68107
68780
|
schedule.sourceRef,
|
|
@@ -68129,7 +68802,7 @@ function createPostgresPersonalAssistantRepositoryStore(options = {}) {
|
|
|
68129
68802
|
ON CONFLICT (owner_user_id, public_id) DO NOTHING
|
|
68130
68803
|
`, [
|
|
68131
68804
|
ownerUserId2.toString(),
|
|
68132
|
-
|
|
68805
|
+
randomUUID54(),
|
|
68133
68806
|
grant.grantRef,
|
|
68134
68807
|
insertedSchedule.rows[0].id,
|
|
68135
68808
|
grant.revision,
|
|
@@ -68155,7 +68828,7 @@ function createPostgresPersonalAssistantRepositoryStore(options = {}) {
|
|
|
68155
68828
|
ON CONFLICT (owner_user_id, public_id) DO NOTHING
|
|
68156
68829
|
`, [
|
|
68157
68830
|
ownerUserId2.toString(),
|
|
68158
|
-
|
|
68831
|
+
randomUUID54(),
|
|
68159
68832
|
run.occurrenceRef,
|
|
68160
68833
|
run.sourceRef,
|
|
68161
68834
|
run.occurrenceKey,
|
|
@@ -68214,7 +68887,7 @@ function createPostgresPersonalAssistantRepositoryStore(options = {}) {
|
|
|
68214
68887
|
INSERT INTO assistant.audit_events (
|
|
68215
68888
|
owner_user_id,id,public_id,actor_kind,event_type,correlation_id,evidence_digest,details,occurred_at
|
|
68216
68889
|
) VALUES ($1,$2,$3,'operator','legacy_import_applied',$3,$4,$5::jsonb,$6)
|
|
68217
|
-
`, [ownerUserId2.toString(),
|
|
68890
|
+
`, [ownerUserId2.toString(), randomUUID54(), input.importRef, applied.classificationDigest, JSON.stringify({ receipt: applied }), appliedAt]);
|
|
68218
68891
|
return applied;
|
|
68219
68892
|
});
|
|
68220
68893
|
}
|
|
@@ -68282,7 +68955,7 @@ async function appendPostgresReceipt(transaction2, ownerUserId2, receipt4, recei
|
|
|
68282
68955
|
) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12::jsonb,$13,$14,$15)
|
|
68283
68956
|
`, [
|
|
68284
68957
|
ownerUserId2.toString(),
|
|
68285
|
-
|
|
68958
|
+
randomUUID54(),
|
|
68286
68959
|
receipt4.receiptRef,
|
|
68287
68960
|
relation.rows[0].command_id,
|
|
68288
68961
|
relation.rows[0].execution_id,
|
|
@@ -68315,7 +68988,7 @@ async function insertPostgresConsentEvidence(queryable, ownerUserId2, evidence)
|
|
|
68315
68988
|
RETURNING public_id
|
|
68316
68989
|
`, [
|
|
68317
68990
|
ownerUserId2.toString(),
|
|
68318
|
-
|
|
68991
|
+
randomUUID54(),
|
|
68319
68992
|
evidence.consentRef,
|
|
68320
68993
|
evidence.recipientHash,
|
|
68321
68994
|
evidence.subjectKey,
|
|
@@ -68356,7 +69029,7 @@ async function insertPostgresSuppressionEvent(queryable, ownerUserId2, event2) {
|
|
|
68356
69029
|
ON CONFLICT (owner_user_id, public_id) DO NOTHING RETURNING public_id
|
|
68357
69030
|
`, [
|
|
68358
69031
|
ownerUserId2.toString(),
|
|
68359
|
-
|
|
69032
|
+
randomUUID54(),
|
|
68360
69033
|
event2.suppressionRef,
|
|
68361
69034
|
event2.subjectKey,
|
|
68362
69035
|
event2.transition,
|
|
@@ -68634,10 +69307,10 @@ var AssistantWorkerStoreError = class extends Error {
|
|
|
68634
69307
|
};
|
|
68635
69308
|
function hash(value) {
|
|
68636
69309
|
const canonical3 = JSON.stringify(value, (_key, entry) => entry && typeof entry === "object" && !Array.isArray(entry) ? Object.fromEntries(Object.entries(entry).sort(([a], [b]) => a.localeCompare(b))) : entry);
|
|
68637
|
-
return
|
|
69310
|
+
return createHash70("sha256").update(canonical3).digest("hex");
|
|
68638
69311
|
}
|
|
68639
69312
|
function ref2(prefix, identity) {
|
|
68640
|
-
return `${prefix}_${
|
|
69313
|
+
return `${prefix}_${createHash70("sha256").update(identity).digest("hex").slice(0, 32)}`;
|
|
68641
69314
|
}
|
|
68642
69315
|
function requiredString(input, key3) {
|
|
68643
69316
|
const value = input[key3];
|
|
@@ -68688,7 +69361,7 @@ var PostgresAssistantWorkerIdentityRegistry = class {
|
|
|
68688
69361
|
RETURNING owner_user_id::text,owner_ref,subject_ref,public_id AS worker_ref,device_key_id,key_ref,
|
|
68689
69362
|
device_public_key,state,expires_at`, [
|
|
68690
69363
|
input.ownerUserId.toString(),
|
|
68691
|
-
|
|
69364
|
+
randomUUID55(),
|
|
68692
69365
|
input.workerRef,
|
|
68693
69366
|
input.ownerRef,
|
|
68694
69367
|
input.subjectRef,
|
|
@@ -68741,7 +69414,7 @@ var PostgresAssistantWorkerNonceLedger = class {
|
|
|
68741
69414
|
INSERT INTO assistant.worker_nonces(owner_user_id,id,namespace,nonce_key,expires_at,consumed_at)
|
|
68742
69415
|
SELECT owner_user_id,$1,$2,$3,$4,$5 FROM unique_candidate
|
|
68743
69416
|
ON CONFLICT (owner_user_id,namespace,nonce_key) DO NOTHING RETURNING id`,
|
|
68744
|
-
[
|
|
69417
|
+
[randomUUID55(), input.namespace, input.key, input.expiresAt, now.toISOString(), workerRef]
|
|
68745
69418
|
);
|
|
68746
69419
|
return (result3.rowCount ?? result3.rows.length) === 1;
|
|
68747
69420
|
}
|
|
@@ -69036,7 +69709,7 @@ var INTERNAL_CAPABILITIES = /* @__PURE__ */ new Set([
|
|
|
69036
69709
|
"assistant.worker_registration.revoke"
|
|
69037
69710
|
]);
|
|
69038
69711
|
function actorRef(issuer, subject) {
|
|
69039
|
-
return `admin_actor_${
|
|
69712
|
+
return `admin_actor_${createHash71("sha256").update(`${issuer}\0${subject}`).digest("base64url").slice(0, 32)}`;
|
|
69040
69713
|
}
|
|
69041
69714
|
var VerifiedPersonalAssistantAdminIdentityPort = class {
|
|
69042
69715
|
constructor(verifier, configuration) {
|
|
@@ -69150,7 +69823,7 @@ function createPersonalAssistantAdminProductionDependencies(input) {
|
|
|
69150
69823
|
}
|
|
69151
69824
|
|
|
69152
69825
|
// src/api/personal-assistant-dispatcher.ts
|
|
69153
|
-
import { createHash as
|
|
69826
|
+
import { createHash as createHash72, randomBytes as randomBytes8, randomUUID as randomUUID56 } from "crypto";
|
|
69154
69827
|
var AssistantLeaseFenceError = class extends Error {
|
|
69155
69828
|
code = "assistant_lease_fence_rejected";
|
|
69156
69829
|
constructor() {
|
|
@@ -69164,7 +69837,7 @@ function canonical2(value) {
|
|
|
69164
69837
|
return Object.fromEntries(Object.entries(value).sort(([a], [b]) => a.localeCompare(b)).map(([key3, entry]) => [key3, canonical2(entry)]));
|
|
69165
69838
|
}
|
|
69166
69839
|
function digest8(value) {
|
|
69167
|
-
return
|
|
69840
|
+
return createHash72("sha256").update(JSON.stringify(canonical2(value))).digest("hex");
|
|
69168
69841
|
}
|
|
69169
69842
|
function ref3(prefix, identity) {
|
|
69170
69843
|
return `${prefix}_${digest8(identity).slice(0, 32)}`;
|
|
@@ -69382,7 +70055,7 @@ function createPostgresPersonalAssistantDispatchStore(options = {}) {
|
|
|
69382
70055
|
const cycleRef = deterministic ? null : ref3("cycle", commandRef);
|
|
69383
70056
|
const executionRef = deterministic ? null : ref3("execution", commandRef);
|
|
69384
70057
|
const occurrenceRef = input.occurrenceKey ? ref3("occurrence", `${ownerId3}\0${input.scheduleRef}\0${input.occurrenceKey}`) : null;
|
|
69385
|
-
const commandId =
|
|
70058
|
+
const commandId = randomUUID56();
|
|
69386
70059
|
const commandPayload = {
|
|
69387
70060
|
schemaVersion: "assistant-command.v1",
|
|
69388
70061
|
commandRef,
|
|
@@ -69427,8 +70100,8 @@ function createPostgresPersonalAssistantDispatchStore(options = {}) {
|
|
|
69427
70100
|
let cycleId = null;
|
|
69428
70101
|
let executionId = null;
|
|
69429
70102
|
if (!deterministic && cycleRef && executionRef) {
|
|
69430
|
-
cycleId =
|
|
69431
|
-
executionId =
|
|
70103
|
+
cycleId = randomUUID56();
|
|
70104
|
+
executionId = randomUUID56();
|
|
69432
70105
|
await client2.query(
|
|
69433
70106
|
`INSERT INTO assistant.wake_cycles
|
|
69434
70107
|
(owner_user_id,id,public_id,assistant_id,command_id,context_version_id,state,opened_at,updated_at)
|
|
@@ -69450,7 +70123,7 @@ function createPostgresPersonalAssistantDispatchStore(options = {}) {
|
|
|
69450
70123
|
ON CONFLICT (owner_user_id,schedule_ref,occurrence_key) DO UPDATE SET public_id=assistant.reminder_occurrences.public_id
|
|
69451
70124
|
RETURNING public_id`, [
|
|
69452
70125
|
ownerId3,
|
|
69453
|
-
|
|
70126
|
+
randomUUID56(),
|
|
69454
70127
|
occurrenceRef,
|
|
69455
70128
|
input.occurrenceKey,
|
|
69456
70129
|
input.scheduledFor,
|
|
@@ -69479,7 +70152,7 @@ function createPostgresPersonalAssistantDispatchStore(options = {}) {
|
|
|
69479
70152
|
VALUES ($1,$2,$3,$4,$5,'assistant.execution.status','response',$6,$7,$8,$9,$10::jsonb,$11,$12)`,
|
|
69480
70153
|
[
|
|
69481
70154
|
ownerId3,
|
|
69482
|
-
|
|
70155
|
+
randomUUID56(),
|
|
69483
70156
|
receiptRef,
|
|
69484
70157
|
commandId,
|
|
69485
70158
|
executionId,
|
|
@@ -69540,7 +70213,7 @@ function createPostgresPersonalAssistantDispatchStore(options = {}) {
|
|
|
69540
70213
|
(owner_user_id,id,public_id,worker_id,execution_id,lease_token_hash,state,claimed_at,heartbeat_at,expires_at)
|
|
69541
70214
|
SELECT $1,$2,$3,$4,execution.id,$5,'active',$6,$6,$7 FROM assistant.executions execution
|
|
69542
70215
|
WHERE execution.owner_user_id=$1 AND execution.public_id=$8`,
|
|
69543
|
-
[ownerId3,
|
|
70216
|
+
[ownerId3, randomUUID56(), leaseRef, worker.rows[0].id, tokenHash3(token7), at, expiresAt, row.execution_ref]
|
|
69544
70217
|
);
|
|
69545
70218
|
await client2.query(
|
|
69546
70219
|
`UPDATE assistant.executions SET state='claimed',claimed_by_worker_id=$3,claim_token_hash=$4,
|
|
@@ -69580,7 +70253,7 @@ function createPostgresPersonalAssistantDispatchStore(options = {}) {
|
|
|
69580
70253
|
SELECT $1,$2,worker.id,lease.id,$3,$4,$5::jsonb,$6 FROM assistant.worker_registrations worker
|
|
69581
70254
|
JOIN assistant.worker_leases lease ON lease.owner_user_id=worker.owner_user_id AND lease.worker_id=worker.id
|
|
69582
70255
|
WHERE worker.owner_user_id=$1 AND worker.public_id=$7 AND lease.public_id=$8 AND lease.state='active'`,
|
|
69583
|
-
[ownerId3,
|
|
70256
|
+
[ownerId3, randomUUID56(), input.sequence, input.runtimeVersion, JSON.stringify(input.health), occurredAt, input.workerRef, input.leaseRef]
|
|
69584
70257
|
);
|
|
69585
70258
|
await client2.query(`UPDATE assistant.worker_leases SET heartbeat_at=$3,expires_at=$4
|
|
69586
70259
|
WHERE owner_user_id=$1 AND public_id=$2 AND state='active'`, [ownerId3, input.leaseRef, occurredAt, expiresAt]);
|
|
@@ -69822,7 +70495,7 @@ function createPostgresAssistantReminderRuntimeStore(options = {}) {
|
|
|
69822
70495
|
payload_digest,payload,parsed_intent,parsed_intent_digest,source,state,accepted_at,updated_at,terminal_at)
|
|
69823
70496
|
SELECT $1,$2,$3,assistant.id,NULL,$4,'assistant-reminder-command.v1',$5,$6,$7::jsonb,NULL,NULL,'system','succeeded',$8,$8,$8
|
|
69824
70497
|
FROM assistant.assistants assistant WHERE assistant.owner_user_id=$1 AND assistant.public_id=$9
|
|
69825
|
-
RETURNING id`, [ownerId3,
|
|
70498
|
+
RETURNING id`, [ownerId3, randomUUID56(), commandRef, command.kind, command.idempotencyKey, digest8(command), JSON.stringify(payload), at, assistantRef2]);
|
|
69826
70499
|
if (!inserted.rows[0]) throw new Error("assistant_reminder_assistant_not_found");
|
|
69827
70500
|
return inserted.rows[0].id;
|
|
69828
70501
|
};
|
|
@@ -69872,7 +70545,7 @@ function createPostgresAssistantReminderRuntimeStore(options = {}) {
|
|
|
69872
70545
|
FROM assistant.assistants assistant WHERE assistant.owner_user_id=$1 AND assistant.public_id=$12`,
|
|
69873
70546
|
[
|
|
69874
70547
|
ownerId3,
|
|
69875
|
-
|
|
70548
|
+
randomUUID56(),
|
|
69876
70549
|
publicRef,
|
|
69877
70550
|
commandRef,
|
|
69878
70551
|
definition2.instruction,
|
|
@@ -69948,7 +70621,7 @@ function createPostgresAssistantReminderRuntimeStore(options = {}) {
|
|
|
69948
70621
|
ON CONFLICT (owner_user_id,schedule_ref,occurrence_key) DO NOTHING RETURNING public_id`,
|
|
69949
70622
|
[
|
|
69950
70623
|
definition.ownerId,
|
|
69951
|
-
|
|
70624
|
+
randomUUID56(),
|
|
69952
70625
|
occurrence.occurrenceRef,
|
|
69953
70626
|
definition.assistantRef,
|
|
69954
70627
|
definition.reminderRef,
|
|
@@ -70028,10 +70701,10 @@ function createPersonalAssistantReminderRuntime(options) {
|
|
|
70028
70701
|
}
|
|
70029
70702
|
|
|
70030
70703
|
// src/api/personal-assistant-reconcile-cron.ts
|
|
70031
|
-
import { createHash as
|
|
70704
|
+
import { createHash as createHash74, timingSafeEqual as timingSafeEqual8 } from "crypto";
|
|
70032
70705
|
|
|
70033
70706
|
// src/api/personal-assistant-reconcile.ts
|
|
70034
|
-
import { createHash as
|
|
70707
|
+
import { createHash as createHash73 } from "crypto";
|
|
70035
70708
|
var PERSONAL_ASSISTANT_RECONCILIATION_LIMITS = Object.freeze({
|
|
70036
70709
|
defaultBatchSize: 20,
|
|
70037
70710
|
maxBatchSize: 50,
|
|
@@ -70053,7 +70726,7 @@ var PUBLIC_REF = /^[a-z][a-z0-9_]*_[A-Za-z0-9_-]{3,128}$/u;
|
|
|
70053
70726
|
var DIGEST2 = /^[a-f0-9]{64}$/u;
|
|
70054
70727
|
var PROVIDER_REF = /^[A-Za-z0-9:_-]{3,200}$/u;
|
|
70055
70728
|
function hash2(value) {
|
|
70056
|
-
return
|
|
70729
|
+
return createHash73("sha256").update(value).digest("hex");
|
|
70057
70730
|
}
|
|
70058
70731
|
function validateCandidate(candidate) {
|
|
70059
70732
|
if (!/^[1-9]\d*$/u.test(candidate.ownerUserId) || !PUBLIC_REF.test(candidate.candidateRef) || !/^trace_[A-Za-z0-9_-]{8,128}$/u.test(candidate.traceRef) || !PUBLIC_REF.test(candidate.claimToken) || !PROVIDER_REF.test(candidate.providerAccountRef) || !PROVIDER_REF.test(candidate.providerLocatorRef) || !DIGEST2.test(candidate.expectedDigest) || !Number.isFinite(Date.parse(candidate.stuckSince))) {
|
|
@@ -70175,8 +70848,8 @@ async function reconcilePersonalAssistantTransports(dependencies, options = {})
|
|
|
70175
70848
|
// src/api/personal-assistant-reconcile-cron.ts
|
|
70176
70849
|
function authorized(actual, expectedSecret) {
|
|
70177
70850
|
if (!actual?.startsWith("Bearer ")) return false;
|
|
70178
|
-
const actualDigest =
|
|
70179
|
-
const expectedDigest =
|
|
70851
|
+
const actualDigest = createHash74("sha256").update(actual).digest();
|
|
70852
|
+
const expectedDigest = createHash74("sha256").update(`Bearer ${expectedSecret}`).digest();
|
|
70180
70853
|
return timingSafeEqual8(actualDigest, expectedDigest);
|
|
70181
70854
|
}
|
|
70182
70855
|
function createPersonalAssistantReconcileCronHandler(options) {
|
|
@@ -70238,7 +70911,7 @@ function createPersonalAssistantReminderCronHandler(options) {
|
|
|
70238
70911
|
}
|
|
70239
70912
|
|
|
70240
70913
|
// src/api/twilio-inbound-admission.ts
|
|
70241
|
-
import { createHash as
|
|
70914
|
+
import { createHash as createHash75, randomBytes as randomBytes9 } from "crypto";
|
|
70242
70915
|
var ACCOUNT_SID = /^AC[0-9a-f]{32}$/iu;
|
|
70243
70916
|
var MESSAGE_SID = /^(?:SM|MM)[0-9a-f]{32}$/iu;
|
|
70244
70917
|
var MESSAGING_SERVICE_SID = /^MG[0-9a-f]{32}$/iu;
|
|
@@ -70260,10 +70933,10 @@ function canonicalJson8(value) {
|
|
|
70260
70933
|
});
|
|
70261
70934
|
}
|
|
70262
70935
|
function digest9(value) {
|
|
70263
|
-
return
|
|
70936
|
+
return createHash75("sha256").update(canonicalJson8(value)).digest("hex");
|
|
70264
70937
|
}
|
|
70265
70938
|
function stableRef(prefix, value) {
|
|
70266
|
-
return `${prefix}_${
|
|
70939
|
+
return `${prefix}_${createHash75("sha256").update(value).digest("hex").slice(0, 32)}`;
|
|
70267
70940
|
}
|
|
70268
70941
|
function normalizeOptionalSid(value) {
|
|
70269
70942
|
const normalized = value?.trim() || null;
|
|
@@ -70409,8 +71082,8 @@ function createTwilioInboundIngressCronHandler(options) {
|
|
|
70409
71082
|
return async (request) => {
|
|
70410
71083
|
if (request.method !== "GET") return Response.json({ error: "method_not_allowed" }, { status: 405, headers: { Allow: "GET" } });
|
|
70411
71084
|
const actual = request.headers.get("authorization") ?? "";
|
|
70412
|
-
const actualDigest =
|
|
70413
|
-
const expectedDigest =
|
|
71085
|
+
const actualDigest = createHash75("sha256").update(actual).digest();
|
|
71086
|
+
const expectedDigest = createHash75("sha256").update(expectedAuthorization).digest();
|
|
70414
71087
|
if (actualDigest.length !== expectedDigest.length || !actualDigest.equals(expectedDigest)) {
|
|
70415
71088
|
return Response.json({ error: "unauthorized" }, { status: 401 });
|
|
70416
71089
|
}
|
|
@@ -70452,7 +71125,7 @@ function createPersonalAssistantWorkerAndCronProduction(options) {
|
|
|
70452
71125
|
}
|
|
70453
71126
|
|
|
70454
71127
|
// src/api/personal-assistant-control-plane-store.ts
|
|
70455
|
-
import { createHash as
|
|
71128
|
+
import { createHash as createHash76, randomUUID as randomUUID57 } from "crypto";
|
|
70456
71129
|
var REF = /^[a-z][A-Za-z0-9_-]{2,159}$/;
|
|
70457
71130
|
var DIGEST4 = /^[a-f0-9]{64}$/;
|
|
70458
71131
|
function record3(input) {
|
|
@@ -70475,7 +71148,7 @@ function ref4(value) {
|
|
|
70475
71148
|
return value;
|
|
70476
71149
|
}
|
|
70477
71150
|
function newRef2(prefix) {
|
|
70478
|
-
return `${prefix}_${
|
|
71151
|
+
return `${prefix}_${randomUUID57().replaceAll("-", "")}`;
|
|
70479
71152
|
}
|
|
70480
71153
|
function canonicalJson9(value) {
|
|
70481
71154
|
return JSON.stringify(value, (_key, entry) => {
|
|
@@ -70484,7 +71157,7 @@ function canonicalJson9(value) {
|
|
|
70484
71157
|
});
|
|
70485
71158
|
}
|
|
70486
71159
|
function digest10(value) {
|
|
70487
|
-
return
|
|
71160
|
+
return createHash76("sha256").update(canonicalJson9(value)).digest("hex");
|
|
70488
71161
|
}
|
|
70489
71162
|
function normalizeE164(value) {
|
|
70490
71163
|
const trimmed = value.trim();
|
|
@@ -70531,7 +71204,7 @@ async function audit(client2, owner5, operation, resourceRef, occurredAt) {
|
|
|
70531
71204
|
`INSERT INTO assistant.audit_events (
|
|
70532
71205
|
owner_user_id,id,public_id,actor_kind,event_type,operation,correlation_id,details,occurred_at
|
|
70533
71206
|
) VALUES ($1,$2,$3,'user','assistant.control_plane.mutation',$4,$5,$6::jsonb,$7::timestamptz)`,
|
|
70534
|
-
[owner5,
|
|
71207
|
+
[owner5, randomUUID57(), newRef2("audit"), operation, resourceRef, JSON.stringify({ resourceRef }), occurredAt]
|
|
70535
71208
|
);
|
|
70536
71209
|
}
|
|
70537
71210
|
var ASSISTANT_PROJECTION = `jsonb_build_object('assistantRef', assistant.public_id, 'state', assistant.status,
|
|
@@ -70612,7 +71285,7 @@ function createPostgresPersonalAssistantControlPlaneStore(options) {
|
|
|
70612
71285
|
'assistantRef',public_id,'state',status,'displayName',name,'revision',revision,'createdAt',created_at,'updatedAt',updated_at) AS projection`,
|
|
70613
71286
|
[
|
|
70614
71287
|
ownerUserId2.toString(),
|
|
70615
|
-
|
|
71288
|
+
randomUUID57(),
|
|
70616
71289
|
assistantRef2,
|
|
70617
71290
|
text2(body3, "displayName", text2(body3, "name", "Personal Assistant")),
|
|
70618
71291
|
optionalText3(body3, "timezone") ?? "UTC",
|
|
@@ -70666,7 +71339,7 @@ function createPostgresPersonalAssistantControlPlaneStore(options) {
|
|
|
70666
71339
|
(owner_user_id,id,public_id,assistant_id,channel,address_ciphertext,address_hash,state,revision,created_at,updated_at)
|
|
70667
71340
|
SELECT $1,$2,$3,assistant.id,$4,$5,$6,'active',1,$7,$7 FROM assistant.assistants assistant WHERE assistant.owner_user_id=$1 AND assistant.public_id=$8 AND assistant.deleted_at IS NULL
|
|
70668
71341
|
RETURNING jsonb_build_object('bindingRef',public_id,'assistantRef',$8::text,'channelEndpointRef',public_id,'channel',channel,'state',state,'revision',revision) AS projection`,
|
|
70669
|
-
[ownerUserId2.toString(),
|
|
71342
|
+
[ownerUserId2.toString(), randomUUID57(), bindingRef, channel, protectedAddress?.ciphertext ?? null, protectedAddress?.digest ?? null, at, ref4(assistantRef2)]
|
|
70670
71343
|
);
|
|
70671
71344
|
if (!result3.rows[0]) throw new Error("assistant_not_found");
|
|
70672
71345
|
await audit(client2, ownerUserId2.toString(), "assistant.channel.bind", bindingRef, at);
|
|
@@ -70723,11 +71396,11 @@ function createPostgresPersonalAssistantControlPlaneStore(options) {
|
|
|
70723
71396
|
const inserted = await client2.query(`INSERT INTO assistant.contacts(owner_user_id,id,public_id,display_name,relationship,phone_ciphertext,phone_hash,timezone,attributes,created_at,updated_at)
|
|
70724
71397
|
VALUES($1,$2,$3,$4,$5,$6,$7,$8,'{}'::jsonb,$9,$9)
|
|
70725
71398
|
ON CONFLICT(owner_user_id,phone_hash) WHERE phone_hash IS NOT NULL DO UPDATE SET updated_at=assistant.contacts.updated_at
|
|
70726
|
-
RETURNING id,public_id`, [ownerUserId2.toString(),
|
|
71399
|
+
RETURNING id,public_id`, [ownerUserId2.toString(), randomUUID57(), contactRef, optionalText3(body3, "displayName"), relationship, protectedAddress.ciphertext, protectedAddress.digest, optionalText3(body3, "timezone"), at]);
|
|
70727
71400
|
const row = inserted.rows[0];
|
|
70728
71401
|
if (!row) throw new Error("contact_create_failed");
|
|
70729
71402
|
await client2.query(`INSERT INTO assistant.contact_delivery_endpoints(owner_user_id,id,public_id,endpoint_key,revision,contact_id,channel,address_ciphertext,address_hash,masked_display,state,created_at)
|
|
70730
|
-
SELECT $1,$2,$3,$4,1,$5,'sms',$6,$7,$8,'unverified',$9 WHERE NOT EXISTS(SELECT 1 FROM (SELECT DISTINCT ON(endpoint_key) endpoint_key,contact_id,address_hash,state FROM assistant.contact_delivery_endpoints WHERE owner_user_id=$1 ORDER BY endpoint_key,revision DESC) effective WHERE effective.contact_id=$5 AND effective.address_hash=$7 AND effective.state<>'removed')`, [ownerUserId2.toString(),
|
|
71403
|
+
SELECT $1,$2,$3,$4,1,$5,'sms',$6,$7,$8,'unverified',$9 WHERE NOT EXISTS(SELECT 1 FROM (SELECT DISTINCT ON(endpoint_key) endpoint_key,contact_id,address_hash,state FROM assistant.contact_delivery_endpoints WHERE owner_user_id=$1 ORDER BY endpoint_key,revision DESC) effective WHERE effective.contact_id=$5 AND effective.address_hash=$7 AND effective.state<>'removed')`, [ownerUserId2.toString(), randomUUID57(), endpointRef, randomUUID57(), row.id, protectedAddress.ciphertext, protectedAddress.digest, maskedPhone(phone), at]);
|
|
70731
71404
|
await audit(client2, ownerUserId2.toString(), "assistant.contact.create", row.public_id, at);
|
|
70732
71405
|
const projected = await client2.query(`SELECT ${CONTACT_PROJECTION} AS projection FROM assistant.contacts contact WHERE contact.owner_user_id=$1 AND contact.public_id=$2`, [ownerUserId2.toString(), row.public_id]);
|
|
70733
71406
|
return projected.rows[0].projection;
|
|
@@ -70752,7 +71425,7 @@ function createPostgresPersonalAssistantControlPlaneStore(options) {
|
|
|
70752
71425
|
if (!DIGEST4.test(protectedAddress.digest)) throw new TypeError("protected address digest is invalid");
|
|
70753
71426
|
return tx(async (client2) => {
|
|
70754
71427
|
const result3 = await client2.query(`INSERT INTO assistant.contact_delivery_endpoints(owner_user_id,id,public_id,endpoint_key,revision,contact_id,channel,address_ciphertext,address_hash,masked_display,state,created_at)
|
|
70755
|
-
SELECT $1,$2,$3,$4,1,contact.id,$5,$6,$7,$8,'unverified',$9 FROM assistant.contacts contact WHERE contact.owner_user_id=$1 AND contact.public_id=$10 AND contact.deleted_at IS NULL AND NOT EXISTS(SELECT 1 FROM (SELECT DISTINCT ON(endpoint_key) endpoint_key,address_hash,state FROM assistant.contact_delivery_endpoints WHERE owner_user_id=$1 ORDER BY endpoint_key,revision DESC) effective WHERE effective.address_hash=$7 AND effective.state<>'removed')`, [ownerUserId2.toString(),
|
|
71428
|
+
SELECT $1,$2,$3,$4,1,contact.id,$5,$6,$7,$8,'unverified',$9 FROM assistant.contacts contact WHERE contact.owner_user_id=$1 AND contact.public_id=$10 AND contact.deleted_at IS NULL AND NOT EXISTS(SELECT 1 FROM (SELECT DISTINCT ON(endpoint_key) endpoint_key,address_hash,state FROM assistant.contact_delivery_endpoints WHERE owner_user_id=$1 ORDER BY endpoint_key,revision DESC) effective WHERE effective.address_hash=$7 AND effective.state<>'removed')`, [ownerUserId2.toString(), randomUUID57(), endpointRef, randomUUID57(), channel, protectedAddress.ciphertext, protectedAddress.digest, maskedPhone(phone), at, ref4(contactRef)]);
|
|
70756
71429
|
if (!result3.rowCount) return null;
|
|
70757
71430
|
await client2.query(`UPDATE assistant.contacts SET phone_ciphertext=COALESCE(phone_ciphertext,$3),phone_hash=COALESCE(phone_hash,$4),updated_at=$5 WHERE owner_user_id=$1 AND public_id=$2`, [ownerUserId2.toString(), contactRef, protectedAddress.ciphertext, protectedAddress.digest, at]);
|
|
70758
71431
|
await audit(client2, ownerUserId2.toString(), "assistant.contact.delivery_endpoint.add", endpointRef, at);
|
|
@@ -70765,7 +71438,7 @@ function createPostgresPersonalAssistantControlPlaneStore(options) {
|
|
|
70765
71438
|
if (!DIGEST4.test(protectedAddress.digest)) throw new TypeError("protected address digest is invalid");
|
|
70766
71439
|
return tx(async (client2) => {
|
|
70767
71440
|
const result3 = await client2.query(`INSERT INTO assistant.contact_delivery_endpoints(owner_user_id,id,public_id,endpoint_key,revision,contact_id,channel,address_ciphertext,address_hash,masked_display,state,created_at)
|
|
70768
|
-
SELECT prior.owner_user_id,$4,$5,prior.endpoint_key,prior.revision+1,prior.contact_id,prior.channel,$6,$7,$8,'unverified',$9 FROM assistant.contact_delivery_endpoints prior JOIN assistant.contacts contact ON contact.owner_user_id=prior.owner_user_id AND contact.id=prior.contact_id WHERE prior.owner_user_id=$1 AND contact.public_id=$2 AND prior.public_id=$3 AND prior.state<>'removed' AND NOT EXISTS(SELECT 1 FROM (SELECT DISTINCT ON(endpoint_key) endpoint_key,address_hash,state FROM assistant.contact_delivery_endpoints WHERE owner_user_id=$1 ORDER BY endpoint_key,revision DESC) effective WHERE effective.address_hash=$7 AND effective.state<>'removed' AND effective.endpoint_key<>prior.endpoint_key)`, [ownerUserId2.toString(), ref4(contactRef), ref4(deliveryEndpointRef),
|
|
71441
|
+
SELECT prior.owner_user_id,$4,$5,prior.endpoint_key,prior.revision+1,prior.contact_id,prior.channel,$6,$7,$8,'unverified',$9 FROM assistant.contact_delivery_endpoints prior JOIN assistant.contacts contact ON contact.owner_user_id=prior.owner_user_id AND contact.id=prior.contact_id WHERE prior.owner_user_id=$1 AND contact.public_id=$2 AND prior.public_id=$3 AND prior.state<>'removed' AND NOT EXISTS(SELECT 1 FROM (SELECT DISTINCT ON(endpoint_key) endpoint_key,address_hash,state FROM assistant.contact_delivery_endpoints WHERE owner_user_id=$1 ORDER BY endpoint_key,revision DESC) effective WHERE effective.address_hash=$7 AND effective.state<>'removed' AND effective.endpoint_key<>prior.endpoint_key)`, [ownerUserId2.toString(), ref4(contactRef), ref4(deliveryEndpointRef), randomUUID57(), nextRef, protectedAddress.ciphertext, protectedAddress.digest, maskedPhone(phone), at]);
|
|
70769
71442
|
if (!result3.rowCount) return null;
|
|
70770
71443
|
await client2.query(`UPDATE assistant.contacts SET phone_ciphertext=$3,phone_hash=$4,updated_at=$5 WHERE owner_user_id=$1 AND public_id=$2`, [ownerUserId2.toString(), contactRef, protectedAddress.ciphertext, protectedAddress.digest, at]);
|
|
70771
71444
|
await audit(client2, ownerUserId2.toString(), "assistant.contact.delivery_endpoint.update", nextRef, at);
|
|
@@ -70777,7 +71450,7 @@ function createPostgresPersonalAssistantControlPlaneStore(options) {
|
|
|
70777
71450
|
const body3 = record3(input), at = now().toISOString(), nextRef = newRef2("delivery");
|
|
70778
71451
|
return tx(async (client2) => {
|
|
70779
71452
|
const result3 = await client2.query(`INSERT INTO assistant.contact_delivery_endpoints(owner_user_id,id,public_id,endpoint_key,revision,contact_id,channel,address_ciphertext,address_hash,masked_display,state,reason_code,created_at)
|
|
70780
|
-
SELECT prior.owner_user_id,$4,$5,prior.endpoint_key,prior.revision+1,prior.contact_id,prior.channel,prior.address_ciphertext,prior.address_hash,prior.masked_display,'removed',$6,$7 FROM assistant.contact_delivery_endpoints prior JOIN assistant.contacts contact ON contact.owner_user_id=prior.owner_user_id AND contact.id=prior.contact_id WHERE prior.owner_user_id=$1 AND contact.public_id=$2 AND prior.public_id=$3 AND prior.state<>'removed'`, [ownerUserId2.toString(), ref4(contactRef), ref4(deliveryEndpointRef),
|
|
71453
|
+
SELECT prior.owner_user_id,$4,$5,prior.endpoint_key,prior.revision+1,prior.contact_id,prior.channel,prior.address_ciphertext,prior.address_hash,prior.masked_display,'removed',$6,$7 FROM assistant.contact_delivery_endpoints prior JOIN assistant.contacts contact ON contact.owner_user_id=prior.owner_user_id AND contact.id=prior.contact_id WHERE prior.owner_user_id=$1 AND contact.public_id=$2 AND prior.public_id=$3 AND prior.state<>'removed'`, [ownerUserId2.toString(), ref4(contactRef), ref4(deliveryEndpointRef), randomUUID57(), nextRef, optionalText3(body3, "reasonCode") ?? "owner_removed", at]);
|
|
70781
71454
|
if (!result3.rowCount) return null;
|
|
70782
71455
|
await client2.query(`WITH effective AS(SELECT DISTINCT ON(endpoint_key) endpoint_key,contact_id,address_ciphertext,address_hash,state,revision FROM assistant.contact_delivery_endpoints WHERE owner_user_id=$1 ORDER BY endpoint_key,revision DESC),replacement AS(SELECT DISTINCT ON(contact_id) contact_id,address_ciphertext,address_hash FROM effective WHERE state<>'removed' ORDER BY contact_id,revision DESC) UPDATE assistant.contacts contact SET phone_ciphertext=replacement.address_ciphertext,phone_hash=replacement.address_hash,updated_at=$3 FROM replacement WHERE contact.owner_user_id=$1 AND contact.public_id=$2 AND replacement.contact_id=contact.id`, [ownerUserId2.toString(), contactRef, at]);
|
|
70783
71456
|
await client2.query(`UPDATE assistant.contacts SET phone_ciphertext=NULL,phone_hash=NULL,updated_at=$3 WHERE owner_user_id=$1 AND public_id=$2 AND NOT EXISTS(SELECT 1 FROM (SELECT DISTINCT ON(endpoint_key) endpoint_key,contact_id,state FROM assistant.contact_delivery_endpoints WHERE owner_user_id=$1 ORDER BY endpoint_key,revision DESC) effective WHERE effective.contact_id=assistant.contacts.id AND effective.state<>'removed')`, [ownerUserId2.toString(), contactRef, at]);
|
|
@@ -70801,7 +71474,7 @@ function createPostgresPersonalAssistantControlPlaneStore(options) {
|
|
|
70801
71474
|
const body3 = record3(input), contactRef = ref4(text2(body3, "contactRef")), consentRef = ref4(text2(body3, "consentRef")), at = now().toISOString();
|
|
70802
71475
|
return tx(async (client2) => {
|
|
70803
71476
|
const result3 = await client2.query(`INSERT INTO assistant.consent_evidence(owner_user_id,id,public_id,contact_id,sender_endpoint_id,recipient_hash,subject_key,message_class,transition,source,proof_digest,captured_at,withdrawn_at)
|
|
70804
|
-
SELECT prior.owner_user_id,$3,$4,prior.contact_id,prior.sender_endpoint_id,prior.recipient_hash,prior.subject_key,prior.message_class,'withdrawn','internal_dnc',$5,$6,$6 FROM assistant.consent_evidence prior JOIN assistant.contacts contact ON contact.owner_user_id=prior.owner_user_id AND contact.id=prior.contact_id JOIN assistant.channel_endpoints endpoint ON endpoint.owner_user_id=prior.owner_user_id AND endpoint.id=prior.sender_endpoint_id WHERE prior.owner_user_id=$1 AND prior.public_id=$2 AND contact.public_id=$7 RETURNING public_id,(SELECT public_id FROM assistant.channel_endpoints WHERE owner_user_id=$1 AND id=sender_endpoint_id) sender_ref,subject_key,message_class,proof_digest`, [ownerUserId2.toString(), consentRef,
|
|
71477
|
+
SELECT prior.owner_user_id,$3,$4,prior.contact_id,prior.sender_endpoint_id,prior.recipient_hash,prior.subject_key,prior.message_class,'withdrawn','internal_dnc',$5,$6,$6 FROM assistant.consent_evidence prior JOIN assistant.contacts contact ON contact.owner_user_id=prior.owner_user_id AND contact.id=prior.contact_id JOIN assistant.channel_endpoints endpoint ON endpoint.owner_user_id=prior.owner_user_id AND endpoint.id=prior.sender_endpoint_id WHERE prior.owner_user_id=$1 AND prior.public_id=$2 AND contact.public_id=$7 RETURNING public_id,(SELECT public_id FROM assistant.channel_endpoints WHERE owner_user_id=$1 AND id=sender_endpoint_id) sender_ref,subject_key,message_class,proof_digest`, [ownerUserId2.toString(), consentRef, randomUUID57(), newRef2("consent"), digest10({ consentRef, at }), at, contactRef]);
|
|
70805
71478
|
if (!result3.rows[0]) throw new Error("consent_not_found");
|
|
70806
71479
|
await audit(client2, ownerUserId2.toString(), "assistant.consent.withdraw", consentRef, at);
|
|
70807
71480
|
const row = result3.rows[0];
|
|
@@ -70811,7 +71484,7 @@ function createPostgresPersonalAssistantControlPlaneStore(options) {
|
|
|
70811
71484
|
async createSchedule(ownerUserId2, assistantRef2, input) {
|
|
70812
71485
|
const body3 = record3(input), scheduleRef = newRef2("schedule"), at = now().toISOString();
|
|
70813
71486
|
return tx(async (client2) => {
|
|
70814
|
-
const result3 = await client2.query(`INSERT INTO assistant.schedules(owner_user_id,id,public_id,assistant_id,source_system,source_ref,source_owner_ref,description,cadence,time_of_day,timezone,logical_vault,status,next_due_at,execution_mode,artifact_selection,source_payload_digest,revision,created_at,updated_at) SELECT $1,$2,$3,assistant.id,$4,$5,$6,$7,$8,$9,$10,$11,'active',$12,$13,$14::jsonb,$15,1,$16,$16 FROM assistant.assistants assistant WHERE assistant.owner_user_id=$1 AND assistant.public_id=$17 RETURNING jsonb_build_object('scheduleRef',public_id,'assistantRef',$17::text,'state',status,'timezone',timezone,'nextDueAt',next_due_at,'revision',revision) AS projection`, [ownerUserId2.toString(),
|
|
71487
|
+
const result3 = await client2.query(`INSERT INTO assistant.schedules(owner_user_id,id,public_id,assistant_id,source_system,source_ref,source_owner_ref,description,cadence,time_of_day,timezone,logical_vault,status,next_due_at,execution_mode,artifact_selection,source_payload_digest,revision,created_at,updated_at) SELECT $1,$2,$3,assistant.id,$4,$5,$6,$7,$8,$9,$10,$11,'active',$12,$13,$14::jsonb,$15,1,$16,$16 FROM assistant.assistants assistant WHERE assistant.owner_user_id=$1 AND assistant.public_id=$17 RETURNING jsonb_build_object('scheduleRef',public_id,'assistantRef',$17::text,'state',status,'timezone',timezone,'nextDueAt',next_due_at,'revision',revision) AS projection`, [ownerUserId2.toString(), randomUUID57(), scheduleRef, optionalText3(body3, "sourceSystem") ?? "assistant", optionalText3(body3, "sourceRef") ?? scheduleRef, optionalText3(body3, "sourceOwnerRef") ?? ownerUserId2.toString(), text2(body3, "description"), text2(body3, "cadence"), optionalText3(body3, "timeOfDay"), optionalText3(body3, "timezone") ?? "UTC", optionalText3(body3, "logicalVault") ?? "Personal Assistant", text2(body3, "nextDueAt"), optionalText3(body3, "executionMode") ?? "agent", JSON.stringify(body3.artifactSelection ?? { mode: "none" }), digest10(body3), at, ref4(assistantRef2)]);
|
|
70815
71488
|
if (!result3.rows[0]) throw new Error("assistant_not_found");
|
|
70816
71489
|
await audit(client2, ownerUserId2.toString(), "assistant.schedule.create", scheduleRef, at);
|
|
70817
71490
|
return result3.rows[0].projection;
|
|
@@ -70834,7 +71507,7 @@ function createPostgresPersonalAssistantControlPlaneStore(options) {
|
|
|
70834
71507
|
async createReminder(ownerUserId2, assistantRef2, input) {
|
|
70835
71508
|
const body3 = record3(input), reminderRef2 = newRef2("reminder"), at = now().toISOString(), scheduledFor = text2(body3, "scheduledFor");
|
|
70836
71509
|
return tx(async (client2) => {
|
|
70837
|
-
const result3 = await client2.query(`INSERT INTO assistant.reminder_occurrences(owner_user_id,id,public_id,assistant_id,schedule_id,schedule_ref,occurrence_key,instruction,scheduled_for,timezone,state,revision,created_at,updated_at) SELECT $1,$2,$3,assistant.id,schedule.id,COALESCE(schedule.public_id,$3),$4,$5,$6,$7,'materialized',1,$8,$8 FROM assistant.assistants assistant LEFT JOIN assistant.schedules schedule ON schedule.owner_user_id=assistant.owner_user_id AND schedule.public_id=$9 WHERE assistant.owner_user_id=$1 AND assistant.public_id=$10 RETURNING jsonb_build_object('reminderRef',public_id,'assistantRef',$10::text,'scheduleRef',CASE WHEN schedule_id IS NULL THEN NULL ELSE schedule_ref END,'state','scheduled','instruction',instruction,'scheduledFor',scheduled_for,'timezone',timezone,'revision',revision,'updatedAt',updated_at) AS projection`, [ownerUserId2.toString(),
|
|
71510
|
+
const result3 = await client2.query(`INSERT INTO assistant.reminder_occurrences(owner_user_id,id,public_id,assistant_id,schedule_id,schedule_ref,occurrence_key,instruction,scheduled_for,timezone,state,revision,created_at,updated_at) SELECT $1,$2,$3,assistant.id,schedule.id,COALESCE(schedule.public_id,$3),$4,$5,$6,$7,'materialized',1,$8,$8 FROM assistant.assistants assistant LEFT JOIN assistant.schedules schedule ON schedule.owner_user_id=assistant.owner_user_id AND schedule.public_id=$9 WHERE assistant.owner_user_id=$1 AND assistant.public_id=$10 RETURNING jsonb_build_object('reminderRef',public_id,'assistantRef',$10::text,'scheduleRef',CASE WHEN schedule_id IS NULL THEN NULL ELSE schedule_ref END,'state','scheduled','instruction',instruction,'scheduledFor',scheduled_for,'timezone',timezone,'revision',revision,'updatedAt',updated_at) AS projection`, [ownerUserId2.toString(), randomUUID57(), reminderRef2, optionalText3(body3, "occurrenceKey") ?? reminderRef2, text2(body3, "instruction"), scheduledFor, optionalText3(body3, "timezone") ?? "UTC", at, optionalText3(body3, "scheduleRef"), ref4(assistantRef2)]);
|
|
70838
71511
|
if (!result3.rows[0]) throw new Error("assistant_not_found");
|
|
70839
71512
|
await audit(client2, ownerUserId2.toString(), "assistant.reminder.create", reminderRef2, at);
|
|
70840
71513
|
return result3.rows[0].projection;
|
|
@@ -70858,7 +71531,7 @@ function createPostgresPersonalAssistantControlPlaneStore(options) {
|
|
|
70858
71531
|
const body3 = record3(input), packetRef = newRef2("packet"), at = now().toISOString(), manifestDigest = text2(body3, "manifestDigest");
|
|
70859
71532
|
if (!DIGEST4.test(manifestDigest)) throw new TypeError("manifestDigest is invalid");
|
|
70860
71533
|
return tx(async (client2) => {
|
|
70861
|
-
const result3 = await client2.query(`INSERT INTO assistant.context_packet_pointers(owner_user_id,id,public_id,assistant_id,context_version_id,memory_vault_ref,packet_ref,packet_revision,revision,manifest_digest,label,sensitivity,state,created_at,updated_at) SELECT $1,$2,$3,assistant.id,context.id,$4,$5,$6,1,$7,$8,$9,'active',$10,$10 FROM assistant.assistants assistant JOIN LATERAL(SELECT id FROM assistant.context_versions WHERE owner_user_id=assistant.owner_user_id AND assistant_id=assistant.id ORDER BY version DESC LIMIT 1) context ON true WHERE assistant.owner_user_id=$1 AND assistant.public_id=$11 RETURNING jsonb_build_object('packetRef',public_id,'assistantRef',$11::text,'revision',revision,'state',state,'manifestDigest',manifest_digest,'label',label,'updatedAt',updated_at) AS projection`, [ownerUserId2.toString(),
|
|
71534
|
+
const result3 = await client2.query(`INSERT INTO assistant.context_packet_pointers(owner_user_id,id,public_id,assistant_id,context_version_id,memory_vault_ref,packet_ref,packet_revision,revision,manifest_digest,label,sensitivity,state,created_at,updated_at) SELECT $1,$2,$3,assistant.id,context.id,$4,$5,$6,1,$7,$8,$9,'active',$10,$10 FROM assistant.assistants assistant JOIN LATERAL(SELECT id FROM assistant.context_versions WHERE owner_user_id=assistant.owner_user_id AND assistant_id=assistant.id ORDER BY version DESC LIMIT 1) context ON true WHERE assistant.owner_user_id=$1 AND assistant.public_id=$11 RETURNING jsonb_build_object('packetRef',public_id,'assistantRef',$11::text,'revision',revision,'state',state,'manifestDigest',manifest_digest,'label',label,'updatedAt',updated_at) AS projection`, [ownerUserId2.toString(), randomUUID57(), packetRef, text2(body3, "memoryVaultRef"), text2(body3, "memoryPacketRef", packetRef), optionalText3(body3, "packetRevision") ?? "1", manifestDigest, text2(body3, "label"), optionalText3(body3, "sensitivity") ?? "standard", at, ref4(assistantRef2)]);
|
|
70862
71535
|
if (!result3.rows[0]) throw new Error("context_version_not_found");
|
|
70863
71536
|
await audit(client2, ownerUserId2.toString(), "assistant.context.create", packetRef, at);
|
|
70864
71537
|
return result3.rows[0].projection;
|
|
@@ -70913,7 +71586,7 @@ function createPostgresPersonalAssistantNumberPort(options) {
|
|
|
70913
71586
|
}
|
|
70914
71587
|
|
|
70915
71588
|
// src/api/personal-assistant-scheduling-store.ts
|
|
70916
|
-
import { createHash as
|
|
71589
|
+
import { createHash as createHash77, randomUUID as randomUUID58 } from "crypto";
|
|
70917
71590
|
var PersonalAssistantSchedulingStoreError = class extends Error {
|
|
70918
71591
|
constructor(code, message = code, status = code === "schedule_not_found" ? 404 : code === "schedule_activation_unavailable" ? 503 : 409) {
|
|
70919
71592
|
super(message);
|
|
@@ -70929,7 +71602,7 @@ function owner3(ownerUserId2) {
|
|
|
70929
71602
|
return ownerUserId2.toString();
|
|
70930
71603
|
}
|
|
70931
71604
|
function ref5(prefix) {
|
|
70932
|
-
return `${prefix}_${
|
|
71605
|
+
return `${prefix}_${randomUUID58().replaceAll("-", "")}`;
|
|
70933
71606
|
}
|
|
70934
71607
|
function iso4(value) {
|
|
70935
71608
|
return value instanceof Date ? value.toISOString() : new Date(value).toISOString();
|
|
@@ -70940,7 +71613,7 @@ function canonicalJson10(value) {
|
|
|
70940
71613
|
return JSON.stringify(value);
|
|
70941
71614
|
}
|
|
70942
71615
|
function digest11(value) {
|
|
70943
|
-
return
|
|
71616
|
+
return createHash77("sha256").update(canonicalJson10(value)).digest("hex");
|
|
70944
71617
|
}
|
|
70945
71618
|
function authorityClass(value) {
|
|
70946
71619
|
if (value === "observe") return "observe";
|
|
@@ -71053,7 +71726,7 @@ function createPostgresPersonalAssistantSchedulingStore(options) {
|
|
|
71053
71726
|
RETURNING id AS schedule_id,revision AS schedule_revision`,
|
|
71054
71727
|
[
|
|
71055
71728
|
ownerRef,
|
|
71056
|
-
|
|
71729
|
+
randomUUID58(),
|
|
71057
71730
|
input.draft.scheduleRef,
|
|
71058
71731
|
input.draft.instruction,
|
|
71059
71732
|
scheduleCadence(input.draft),
|
|
@@ -71087,7 +71760,7 @@ function createPostgresPersonalAssistantSchedulingStore(options) {
|
|
|
71087
71760
|
) VALUES ($1,$2,$3,$4,$5,$6,$7::jsonb,$8,$9,$10::timestamptz,$11::timestamptz)`,
|
|
71088
71761
|
[
|
|
71089
71762
|
ownerRef,
|
|
71090
|
-
|
|
71763
|
+
randomUUID58(),
|
|
71091
71764
|
ref5("schedrev"),
|
|
71092
71765
|
schedule.rows[0].schedule_id,
|
|
71093
71766
|
input.draft.revision,
|
|
@@ -71112,7 +71785,7 @@ function createPostgresPersonalAssistantSchedulingStore(options) {
|
|
|
71112
71785
|
AND profile.deleted_at IS NULL AND login.deleted_at IS NULL`,
|
|
71113
71786
|
[
|
|
71114
71787
|
ownerRef,
|
|
71115
|
-
|
|
71788
|
+
randomUUID58(),
|
|
71116
71789
|
ref5("sbgrant"),
|
|
71117
71790
|
schedule.rows[0].schedule_id,
|
|
71118
71791
|
input.draft.revision,
|
|
@@ -71182,7 +71855,7 @@ function createPostgresPersonalAssistantSchedulingStore(options) {
|
|
|
71182
71855
|
RETURNING id`,
|
|
71183
71856
|
[
|
|
71184
71857
|
ownerRef,
|
|
71185
|
-
|
|
71858
|
+
randomUUID58(),
|
|
71186
71859
|
ref5("sready"),
|
|
71187
71860
|
row.schedule_id,
|
|
71188
71861
|
row.revision,
|
|
@@ -71231,7 +71904,7 @@ function createPostgresPersonalAssistantSchedulingStore(options) {
|
|
|
71231
71904
|
) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12::jsonb,$13::timestamptz)`,
|
|
71232
71905
|
[
|
|
71233
71906
|
ownerRef,
|
|
71234
|
-
|
|
71907
|
+
randomUUID58(),
|
|
71235
71908
|
ref5("sactivate"),
|
|
71236
71909
|
row.schedule_id,
|
|
71237
71910
|
row.revision,
|
|
@@ -71384,7 +72057,7 @@ function assertNoRawTwilioSecretEnvironment(environment2 = process.env) {
|
|
|
71384
72057
|
}
|
|
71385
72058
|
|
|
71386
72059
|
// src/api/twilio-messaging-service.ts
|
|
71387
|
-
import { createHash as
|
|
72060
|
+
import { createHash as createHash78 } from "crypto";
|
|
71388
72061
|
|
|
71389
72062
|
// src/api/personal-assistant-policy.ts
|
|
71390
72063
|
var AUTHORITY_RANK = {
|
|
@@ -71684,10 +72357,10 @@ function canonicalJson11(value) {
|
|
|
71684
72357
|
});
|
|
71685
72358
|
}
|
|
71686
72359
|
function digest12(value) {
|
|
71687
|
-
return
|
|
72360
|
+
return createHash78("sha256").update(canonicalJson11(value)).digest("hex");
|
|
71688
72361
|
}
|
|
71689
72362
|
function deterministicRef3(prefix, identity) {
|
|
71690
|
-
return `${prefix}_${
|
|
72363
|
+
return `${prefix}_${createHash78("sha256").update(identity).digest("hex").slice(0, 32)}`;
|
|
71691
72364
|
}
|
|
71692
72365
|
function isBoundedAuthorityRef(value) {
|
|
71693
72366
|
return typeof value === "string" && value.length >= 3 && value.length <= 240 && !value.includes("\0");
|
|
@@ -71859,7 +72532,7 @@ function inboundIdentity(input, route) {
|
|
|
71859
72532
|
};
|
|
71860
72533
|
}
|
|
71861
72534
|
function sha256Bytes(bytes2) {
|
|
71862
|
-
return
|
|
72535
|
+
return createHash78("sha256").update(bytes2).digest("hex");
|
|
71863
72536
|
}
|
|
71864
72537
|
function startsWith(bytes2, signature) {
|
|
71865
72538
|
return signature.every((value, index) => bytes2[index] === value);
|
|
@@ -73038,11 +73711,11 @@ function createTwilioMessagingService(dependencies = {}) {
|
|
|
73038
73711
|
}
|
|
73039
73712
|
|
|
73040
73713
|
// src/api/twilio-memory-media.ts
|
|
73041
|
-
import { createHash as
|
|
73714
|
+
import { createHash as createHash79, randomUUID as randomUUID59 } from "crypto";
|
|
73042
73715
|
var IMAGE_TYPES = /* @__PURE__ */ new Set(["image/jpeg", "image/png", "image/gif", "image/webp"]);
|
|
73043
73716
|
var FILE_TYPES = /* @__PURE__ */ new Set(["application/pdf", "text/plain"]);
|
|
73044
73717
|
function digestBytes(bytes2) {
|
|
73045
|
-
return
|
|
73718
|
+
return createHash79("sha256").update(bytes2).digest("hex");
|
|
73046
73719
|
}
|
|
73047
73720
|
function publicPointer(pointer) {
|
|
73048
73721
|
return Object.freeze({
|
|
@@ -73126,7 +73799,7 @@ function createTwilioMemoryMedia(options) {
|
|
|
73126
73799
|
return publicPointer(await options.pointers.put({
|
|
73127
73800
|
ownerBindingRef: input.ownerBindingRef,
|
|
73128
73801
|
mediaRef: input.mediaRef,
|
|
73129
|
-
renewablePointerRef: `memory_asset_${
|
|
73802
|
+
renewablePointerRef: `memory_asset_${createHash79("sha256").update(`${input.ownerBindingRef}\0${asset.assetId}`).digest("hex").slice(0, 32)}`,
|
|
73130
73803
|
byteDigest: input.byteDigest,
|
|
73131
73804
|
contentType: input.contentType,
|
|
73132
73805
|
byteSize: input.bytes.byteLength,
|
|
@@ -73159,7 +73832,7 @@ function createTwilioMemoryMedia(options) {
|
|
|
73159
73832
|
}
|
|
73160
73833
|
|
|
73161
73834
|
// src/api/twilio-provider-facade.ts
|
|
73162
|
-
import { createHash as
|
|
73835
|
+
import { createHash as createHash80 } from "crypto";
|
|
73163
73836
|
|
|
73164
73837
|
// src/api/twilio-messaging-client.ts
|
|
73165
73838
|
import twilio4 from "twilio";
|
|
@@ -73340,7 +74013,7 @@ function createTwilioMessagingClient(options) {
|
|
|
73340
74013
|
if (!options.accountSid || !options.authToken) throw new Error("twilio_credentials_required");
|
|
73341
74014
|
return createOfficialAdapter(options.accountSid, options.authToken, defaultDeadlineMs);
|
|
73342
74015
|
})();
|
|
73343
|
-
async function
|
|
74016
|
+
async function call2(operation, work, deadlineMs) {
|
|
73344
74017
|
const timeoutMs = boundedInteger(deadlineMs, defaultDeadlineMs, TWILIO_CLIENT_LIMITS.minDeadlineMs, TWILIO_CLIENT_LIMITS.maxDeadlineMs, "deadline_ms");
|
|
73345
74018
|
let timer;
|
|
73346
74019
|
try {
|
|
@@ -73372,7 +74045,7 @@ function createTwilioMessagingClient(options) {
|
|
|
73372
74045
|
if (input.areaCode !== void 0 && (!Number.isInteger(input.areaCode) || input.areaCode < 100 || input.areaCode > 999)) throw new RangeError("area_code_out_of_bounds");
|
|
73373
74046
|
if (input.contains !== void 0 && !/^[0-9A-Za-z*%+$]{2,16}$/.test(input.contains)) throw new TypeError("invalid_number_pattern");
|
|
73374
74047
|
const bounds2 = listBounds(input.limit, input.pageSize, TWILIO_CLIENT_LIMITS.maxSearchResults);
|
|
73375
|
-
const result3 = await
|
|
74048
|
+
const result3 = await call2("number.search", () => adapter.searchAvailableNumbers({
|
|
73376
74049
|
countryCode,
|
|
73377
74050
|
type: input.type,
|
|
73378
74051
|
...bounds2,
|
|
@@ -73386,54 +74059,54 @@ function createTwilioMessagingClient(options) {
|
|
|
73386
74059
|
},
|
|
73387
74060
|
listIncomingNumbers: async (input = {}) => {
|
|
73388
74061
|
const bounds2 = listBounds(input.limit, input.pageSize);
|
|
73389
|
-
const result3 = await
|
|
74062
|
+
const result3 = await call2("number.list", () => adapter.listIncomingNumbers(bounds2), input.deadlineMs);
|
|
73390
74063
|
return result3.slice(0, bounds2.limit).map(projectNumber);
|
|
73391
74064
|
},
|
|
73392
|
-
readIncomingNumber: async (sid, options2 = {}) => projectNumber(await
|
|
73393
|
-
purchaseIncomingNumber: async (input) => projectNumber(await
|
|
74065
|
+
readIncomingNumber: async (sid, options2 = {}) => projectNumber(await call2("number.read", () => adapter.fetchIncomingNumber(assertSid(sid, "number")), options2.deadlineMs)),
|
|
74066
|
+
purchaseIncomingNumber: async (input) => projectNumber(await call2("number.purchase", () => adapter.purchaseIncomingNumber({
|
|
73394
74067
|
phoneNumber: assertE164(input.phoneNumber, "phone_number"),
|
|
73395
74068
|
...input.friendlyName === void 0 ? {} : { friendlyName: boundedText2(input.friendlyName, TWILIO_CLIENT_LIMITS.maxFriendlyNameChars, "friendly_name") }
|
|
73396
74069
|
}), input.deadlineMs)),
|
|
73397
|
-
releaseIncomingNumber: async (sid, options2 = {}) => ({ released: await
|
|
73398
|
-
createMessagingService: async (input) => projectService(await
|
|
74070
|
+
releaseIncomingNumber: async (sid, options2 = {}) => ({ released: await call2("number.release", () => adapter.releaseIncomingNumber(assertSid(sid, "number")), options2.deadlineMs) }),
|
|
74071
|
+
createMessagingService: async (input) => projectService(await call2("messaging_service.create", () => adapter.createMessagingService({
|
|
73399
74072
|
friendlyName: boundedText2(input.friendlyName, TWILIO_CLIENT_LIMITS.maxFriendlyNameChars, "friendly_name"),
|
|
73400
74073
|
...input.inboundRequestUrl ? { inboundRequestUrl: assertHttpsUrl(input.inboundRequestUrl, "inbound_request_url") } : {},
|
|
73401
74074
|
...input.statusCallback ? { statusCallback: assertHttpsUrl(input.statusCallback, "status_callback") } : {}
|
|
73402
74075
|
}), input.deadlineMs)),
|
|
73403
74076
|
listMessagingServices: async (input = {}) => {
|
|
73404
74077
|
const bounds2 = listBounds(input.limit, input.pageSize);
|
|
73405
|
-
const result3 = await
|
|
74078
|
+
const result3 = await call2("messaging_service.list", () => adapter.listMessagingServices(bounds2), input.deadlineMs);
|
|
73406
74079
|
return result3.slice(0, bounds2.limit).map(projectService);
|
|
73407
74080
|
},
|
|
73408
|
-
readMessagingService: async (sid, options2 = {}) => projectService(await
|
|
74081
|
+
readMessagingService: async (sid, options2 = {}) => projectService(await call2("messaging_service.read", () => adapter.fetchMessagingService(assertSid(sid, "service")), options2.deadlineMs)),
|
|
73409
74082
|
updateMessagingService: async (sid, input) => {
|
|
73410
74083
|
const patch = {};
|
|
73411
74084
|
if (input.friendlyName !== void 0) patch.friendlyName = boundedText2(input.friendlyName, TWILIO_CLIENT_LIMITS.maxFriendlyNameChars, "friendly_name");
|
|
73412
74085
|
if (input.inboundRequestUrl !== void 0) patch.inboundRequestUrl = assertHttpsUrl(input.inboundRequestUrl, "inbound_request_url");
|
|
73413
74086
|
if (input.statusCallback !== void 0) patch.statusCallback = assertHttpsUrl(input.statusCallback, "status_callback");
|
|
73414
74087
|
if (!Object.keys(patch).length) throw new TypeError("messaging_service_update_empty");
|
|
73415
|
-
return projectService(await
|
|
74088
|
+
return projectService(await call2("messaging_service.update", () => adapter.updateMessagingService(assertSid(sid, "service"), patch), input.deadlineMs));
|
|
73416
74089
|
},
|
|
73417
|
-
deleteMessagingService: async (sid, options2 = {}) => ({ deleted: await
|
|
73418
|
-
bindMessagingServiceSender: async (serviceSid, phoneNumberSid, options2 = {}) => pick2(await
|
|
74090
|
+
deleteMessagingService: async (sid, options2 = {}) => ({ deleted: await call2("messaging_service.delete", () => adapter.deleteMessagingService(assertSid(sid, "service")), options2.deadlineMs) }),
|
|
74091
|
+
bindMessagingServiceSender: async (serviceSid, phoneNumberSid, options2 = {}) => pick2(await call2("messaging_service.sender.bind", () => adapter.bindMessagingServiceSender(assertSid(serviceSid, "service"), { phoneNumberSid: assertSid(phoneNumberSid, "number") }), options2.deadlineMs), ["sid", "phoneNumberSid", "dateCreated"]),
|
|
73419
74092
|
listMessagingServiceSenders: async (serviceSid, input = {}) => {
|
|
73420
74093
|
const bounds2 = listBounds(input.limit, input.pageSize);
|
|
73421
|
-
const result3 = await
|
|
74094
|
+
const result3 = await call2("messaging_service.sender.list", () => adapter.listMessagingServiceSenders(assertSid(serviceSid, "service"), bounds2), input.deadlineMs);
|
|
73422
74095
|
return result3.slice(0, bounds2.limit).map((value) => pick2(value, ["sid", "phoneNumberSid", "dateCreated"]));
|
|
73423
74096
|
},
|
|
73424
|
-
unbindMessagingServiceSender: async (serviceSid, senderSid, options2 = {}) => ({ unbound: await
|
|
74097
|
+
unbindMessagingServiceSender: async (serviceSid, senderSid, options2 = {}) => ({ unbound: await call2("messaging_service.sender.unbind", () => adapter.unbindMessagingServiceSender(assertSid(serviceSid, "service"), assertSid(senderSid, "sender")), options2.deadlineMs) }),
|
|
73425
74098
|
createRegulatoryBundle: async (input) => {
|
|
73426
74099
|
const isoCountry = input.isoCountry.trim().toUpperCase();
|
|
73427
74100
|
if (!/^[A-Z]{2}$/.test(isoCountry)) throw new TypeError("invalid_country_code");
|
|
73428
74101
|
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(input.email) || input.email.length > 254) throw new TypeError("invalid_contact_email");
|
|
73429
|
-
return projectRegistration(await
|
|
74102
|
+
return projectRegistration(await call2("registration.bundle.create", () => adapter.createRegulatoryBundle({ friendlyName: boundedText2(input.friendlyName, TWILIO_CLIENT_LIMITS.maxFriendlyNameChars, "friendly_name"), email: input.email, endUserType: input.endUserType, isoCountry, numberType: boundedText2(input.numberType, 40, "number_type"), regulationSid: assertSid(input.regulationSid, "regulation") }), input.deadlineMs));
|
|
73430
74103
|
},
|
|
73431
74104
|
listRegulatoryBundles: async (input = {}) => {
|
|
73432
74105
|
const bounds2 = listBounds(input.limit, input.pageSize);
|
|
73433
|
-
const result3 = await
|
|
74106
|
+
const result3 = await call2("registration.bundle.list", () => adapter.listRegulatoryBundles({ ...bounds2, ...input.status ? { status: boundedText2(input.status, 40, "status") } : {} }), input.deadlineMs);
|
|
73434
74107
|
return result3.slice(0, bounds2.limit).map(projectRegistration);
|
|
73435
74108
|
},
|
|
73436
|
-
readRegulatoryBundle: async (sid, options2 = {}) => projectRegistration(await
|
|
74109
|
+
readRegulatoryBundle: async (sid, options2 = {}) => projectRegistration(await call2("registration.bundle.read", () => adapter.fetchRegulatoryBundle(assertSid(sid, "bundle")), options2.deadlineMs)),
|
|
73437
74110
|
updateRegulatoryBundle: async (sid, input) => {
|
|
73438
74111
|
const patch = {};
|
|
73439
74112
|
if (input.friendlyName !== void 0) patch.friendlyName = boundedText2(input.friendlyName, TWILIO_CLIENT_LIMITS.maxFriendlyNameChars, "friendly_name");
|
|
@@ -73442,16 +74115,16 @@ function createTwilioMessagingClient(options) {
|
|
|
73442
74115
|
patch.email = input.email;
|
|
73443
74116
|
}
|
|
73444
74117
|
if (!Object.keys(patch).length) throw new TypeError("registration_bundle_update_empty");
|
|
73445
|
-
return projectRegistration(await
|
|
74118
|
+
return projectRegistration(await call2("registration.bundle.update", () => adapter.updateRegulatoryBundle(assertSid(sid, "bundle"), patch), input.deadlineMs));
|
|
73446
74119
|
},
|
|
73447
|
-
submitRegulatoryBundle: async (sid, options2 = {}) => projectRegistration(await
|
|
73448
|
-
bindRegulatoryItem: async (bundleSid, objectSid, options2 = {}) => pick2(await
|
|
74120
|
+
submitRegulatoryBundle: async (sid, options2 = {}) => projectRegistration(await call2("registration.bundle.submit", () => adapter.updateRegulatoryBundle(assertSid(sid, "bundle"), { status: "pending-review" }), options2.deadlineMs)),
|
|
74121
|
+
bindRegulatoryItem: async (bundleSid, objectSid, options2 = {}) => pick2(await call2("registration.item.bind", () => adapter.bindRegulatoryItem(assertSid(bundleSid, "bundle"), { objectSid: assertSid(objectSid, "regulatoryObject") }), options2.deadlineMs), ["sid", "objectSid", "bundleSid", "dateCreated"]),
|
|
73449
74122
|
listRegulatoryItems: async (bundleSid, input = {}) => {
|
|
73450
74123
|
const bounds2 = listBounds(input.limit, input.pageSize);
|
|
73451
|
-
const result3 = await
|
|
74124
|
+
const result3 = await call2("registration.item.list", () => adapter.listRegulatoryItems(assertSid(bundleSid, "bundle"), bounds2), input.deadlineMs);
|
|
73452
74125
|
return result3.slice(0, bounds2.limit).map((value) => pick2(value, ["sid", "objectSid", "bundleSid", "dateCreated"]));
|
|
73453
74126
|
},
|
|
73454
|
-
unbindRegulatoryItem: async (bundleSid, itemSid, options2 = {}) => ({ unbound: await
|
|
74127
|
+
unbindRegulatoryItem: async (bundleSid, itemSid, options2 = {}) => ({ unbound: await call2("registration.item.unbind", () => adapter.unbindRegulatoryItem(assertSid(bundleSid, "bundle"), assertSid(itemSid, "item")), options2.deadlineMs) }),
|
|
73455
74128
|
createMessage: async (input) => {
|
|
73456
74129
|
if (input.from === void 0 === (input.messagingServiceSid === void 0)) throw new TypeError("message_sender_requires_exactly_one_source");
|
|
73457
74130
|
if (input.body === void 0 && (!input.mediaUrl || input.mediaUrl.length === 0)) throw new TypeError("message_content_required");
|
|
@@ -73466,21 +74139,21 @@ function createTwilioMessagingClient(options) {
|
|
|
73466
74139
|
...input.statusCallback ? { statusCallback: assertHttpsUrl(input.statusCallback, "status_callback") } : {},
|
|
73467
74140
|
...input.validityPeriod === void 0 ? {} : { validityPeriod: boundedInteger(input.validityPeriod, 36e3, 1, 36e3, "validity_period") }
|
|
73468
74141
|
};
|
|
73469
|
-
return projectMessage(await
|
|
74142
|
+
return projectMessage(await call2("message.create", () => adapter.createMessage(request), input.deadlineMs));
|
|
73470
74143
|
},
|
|
73471
74144
|
listMessages: async (input = {}) => {
|
|
73472
74145
|
const bounds2 = listBounds(input.limit, input.pageSize);
|
|
73473
|
-
const result3 = await
|
|
74146
|
+
const result3 = await call2("message.list", () => adapter.listMessages(bounds2), input.deadlineMs);
|
|
73474
74147
|
return result3.slice(0, bounds2.limit).map(projectMessage);
|
|
73475
74148
|
},
|
|
73476
|
-
readMessage: async (sid, options2 = {}) => projectMessage(await
|
|
73477
|
-
cancelMessage: async (sid, options2 = {}) => projectMessage(await
|
|
74149
|
+
readMessage: async (sid, options2 = {}) => projectMessage(await call2("message.read", () => adapter.fetchMessage(assertSid(sid, "message")), options2.deadlineMs)),
|
|
74150
|
+
cancelMessage: async (sid, options2 = {}) => projectMessage(await call2("message.cancel", () => adapter.cancelMessage(assertSid(sid, "message")), options2.deadlineMs)),
|
|
73478
74151
|
listMessageMedia: async (messageSid, input = {}) => {
|
|
73479
74152
|
const bounds2 = listBounds(input.limit, input.pageSize, TWILIO_CLIENT_LIMITS.maxMediaUrls);
|
|
73480
|
-
const result3 = await
|
|
74153
|
+
const result3 = await call2("message.media.list", () => adapter.listMedia(assertSid(messageSid, "message"), bounds2), input.deadlineMs);
|
|
73481
74154
|
return result3.slice(0, bounds2.limit).map(projectMedia);
|
|
73482
74155
|
},
|
|
73483
|
-
readMessageMedia: async (messageSid, mediaSid, options2 = {}) => projectMedia(await
|
|
74156
|
+
readMessageMedia: async (messageSid, mediaSid, options2 = {}) => projectMedia(await call2("message.media.read", () => adapter.fetchMedia(assertSid(messageSid, "message"), assertSid(mediaSid, "media")), options2.deadlineMs))
|
|
73484
74157
|
});
|
|
73485
74158
|
}
|
|
73486
74159
|
|
|
@@ -73494,7 +74167,7 @@ function validAuthority(input) {
|
|
|
73494
74167
|
return /^[1-9]\d*$/u.test(input.ownerUserId) && PUBLIC_REF2.test(input.executionRef) && ACCOUNT_SID3.test(input.providerAccountRef) && PUBLIC_REF2.test(input.connectionRef) && /^[A-Za-z][A-Za-z0-9_.:-]{2,159}$/u.test(input.environmentRef);
|
|
73495
74168
|
}
|
|
73496
74169
|
function digest13(value) {
|
|
73497
|
-
return
|
|
74170
|
+
return createHash80("sha256").update(JSON.stringify(value, (_key, entry) => {
|
|
73498
74171
|
if (!entry || typeof entry !== "object" || Array.isArray(entry)) return entry;
|
|
73499
74172
|
return Object.fromEntries(Object.entries(entry).sort(([a], [b]) => a.localeCompare(b)));
|
|
73500
74173
|
})).digest("hex");
|
|
@@ -73683,7 +74356,7 @@ function createTwilioProduction(options) {
|
|
|
73683
74356
|
}
|
|
73684
74357
|
|
|
73685
74358
|
// src/runtime/personal-assistant-deployment-config.ts
|
|
73686
|
-
import { createHash as
|
|
74359
|
+
import { createHash as createHash81 } from "crypto";
|
|
73687
74360
|
import { readFileSync as readFileSync4 } from "fs";
|
|
73688
74361
|
import { resolve as resolve2 } from "path";
|
|
73689
74362
|
var REF_PATTERN = /^(?:[a-z][a-z0-9+.-]*:\/\/)?[A-Za-z0-9][A-Za-z0-9._:/-]{2,240}$/;
|
|
@@ -73719,7 +74392,7 @@ function databaseBinding(value) {
|
|
|
73719
74392
|
const database = decodeURIComponent(parsed.pathname.replace(/^\//, ""));
|
|
73720
74393
|
const role = decodeURIComponent(parsed.username);
|
|
73721
74394
|
if (!database || !/^[a-z_][a-z0-9_]*$/.test(role)) return null;
|
|
73722
|
-
return { fingerprint:
|
|
74395
|
+
return { fingerprint: createHash81("sha256").update(`${labels.join(".")}\0${database}`).digest("hex"), role };
|
|
73723
74396
|
} catch {
|
|
73724
74397
|
return null;
|
|
73725
74398
|
}
|
|
@@ -74181,8 +74854,8 @@ function createPersonalAssistantHostedConfigurationAdapter(input) {
|
|
|
74181
74854
|
}
|
|
74182
74855
|
|
|
74183
74856
|
// src/api/personal-assistant-authorization.ts
|
|
74184
|
-
import { createHash as
|
|
74185
|
-
import { z as
|
|
74857
|
+
import { createHash as createHash82 } from "crypto";
|
|
74858
|
+
import { z as z51 } from "zod";
|
|
74186
74859
|
var ABUSE_GATED_OPERATIONS = /* @__PURE__ */ new Set(["assistant.message.send", "assistant.bulk.send"]);
|
|
74187
74860
|
var NORMALIZED_RECIPIENT_OPERATIONS = /* @__PURE__ */ new Set([
|
|
74188
74861
|
"assistant.message.send",
|
|
@@ -74260,27 +74933,27 @@ var RepositoryBackedPersonalAssistantAuthorization = class {
|
|
|
74260
74933
|
return result3;
|
|
74261
74934
|
}
|
|
74262
74935
|
};
|
|
74263
|
-
var AuthorizationContextSchema =
|
|
74264
|
-
resourceRefs:
|
|
74265
|
-
contactRef:
|
|
74266
|
-
senderEndpointRef:
|
|
74267
|
-
numberRef:
|
|
74268
|
-
consentSubjectKey:
|
|
74269
|
-
messageClass:
|
|
74270
|
-
recipientHashes:
|
|
74271
|
-
recipientCount:
|
|
74272
|
-
segmentCount:
|
|
74273
|
-
mediaCount:
|
|
74274
|
-
byteCount:
|
|
74275
|
-
spendCurrency:
|
|
74276
|
-
spendAmountMinor:
|
|
74277
|
-
destinationCountry:
|
|
74278
|
-
routingRef:
|
|
74279
|
-
audienceDigest:
|
|
74280
|
-
occurrenceRef:
|
|
74281
|
-
currentPlanRevision:
|
|
74282
|
-
validFrom:
|
|
74283
|
-
expiresAt:
|
|
74936
|
+
var AuthorizationContextSchema = z51.object({
|
|
74937
|
+
resourceRefs: z51.array(z51.string()).max(100),
|
|
74938
|
+
contactRef: z51.string().optional(),
|
|
74939
|
+
senderEndpointRef: z51.string().optional(),
|
|
74940
|
+
numberRef: z51.string().optional(),
|
|
74941
|
+
consentSubjectKey: z51.string().optional(),
|
|
74942
|
+
messageClass: z51.enum(["administrative", "transactional", "conversational", "campaign", "compliance"]).optional(),
|
|
74943
|
+
recipientHashes: z51.array(z51.string().regex(/^[a-f0-9]{64}$/)).max(1e4),
|
|
74944
|
+
recipientCount: z51.number().int().nonnegative(),
|
|
74945
|
+
segmentCount: z51.number().int().nonnegative(),
|
|
74946
|
+
mediaCount: z51.number().int().nonnegative(),
|
|
74947
|
+
byteCount: z51.number().int().nonnegative().safe(),
|
|
74948
|
+
spendCurrency: z51.string().regex(/^[A-Z]{3}$/).optional(),
|
|
74949
|
+
spendAmountMinor: z51.number().int().nonnegative().safe().optional(),
|
|
74950
|
+
destinationCountry: z51.string().regex(/^[A-Z]{2}$/).optional(),
|
|
74951
|
+
routingRef: z51.string().optional(),
|
|
74952
|
+
audienceDigest: z51.string().regex(/^[a-f0-9]{64}$/).optional(),
|
|
74953
|
+
occurrenceRef: z51.string().optional(),
|
|
74954
|
+
currentPlanRevision: z51.number().int().positive().optional(),
|
|
74955
|
+
validFrom: z51.string(),
|
|
74956
|
+
expiresAt: z51.string()
|
|
74284
74957
|
}).strict().superRefine((value, context) => {
|
|
74285
74958
|
if (value.spendCurrency === void 0 !== (value.spendAmountMinor === void 0)) {
|
|
74286
74959
|
context.addIssue({ code: "custom", path: ["spendCurrency"], message: "spend currency and amount must be paired" });
|
|
@@ -74323,43 +74996,43 @@ var PostgresPersonalAssistantAuthorizationContextRepository = class {
|
|
|
74323
74996
|
return parsed.success ? Object.freeze(parsed.data) : null;
|
|
74324
74997
|
}
|
|
74325
74998
|
};
|
|
74326
|
-
var MoneySchema2 =
|
|
74327
|
-
var DurablePolicyFactsSchema =
|
|
74328
|
-
requestedEffect:
|
|
74329
|
-
channel:
|
|
74330
|
-
provider:
|
|
74331
|
-
accountRef:
|
|
74332
|
-
resourceRefs:
|
|
74333
|
-
requestedDomain:
|
|
74334
|
-
occurrenceRef:
|
|
74335
|
-
audienceDigest:
|
|
74336
|
-
operationCount:
|
|
74337
|
-
recipientCount:
|
|
74338
|
-
segmentCount:
|
|
74339
|
-
byteCount:
|
|
74999
|
+
var MoneySchema2 = z51.object({ currency: z51.string().regex(/^[A-Z]{3}$/), amountMinor: z51.number().int().nonnegative().safe() }).strict();
|
|
75000
|
+
var DurablePolicyFactsSchema = z51.object({
|
|
75001
|
+
requestedEffect: z51.string().optional(),
|
|
75002
|
+
channel: z51.enum(["web", "sms", "mms", "cron", "system", "browser"]).optional(),
|
|
75003
|
+
provider: z51.enum(["gmail", "calendar", "zoom", "twilio", "memory", "browser", "assistant"]).optional(),
|
|
75004
|
+
accountRef: z51.string().optional(),
|
|
75005
|
+
resourceRefs: z51.array(z51.string()).max(100).optional(),
|
|
75006
|
+
requestedDomain: z51.string().optional(),
|
|
75007
|
+
occurrenceRef: z51.string().optional(),
|
|
75008
|
+
audienceDigest: z51.string().nullable().optional(),
|
|
75009
|
+
operationCount: z51.number().int().nonnegative().optional(),
|
|
75010
|
+
recipientCount: z51.number().int().nonnegative().optional(),
|
|
75011
|
+
segmentCount: z51.number().int().nonnegative().optional(),
|
|
75012
|
+
byteCount: z51.number().int().nonnegative().safe().optional(),
|
|
74340
75013
|
spend: MoneySchema2.nullable().optional(),
|
|
74341
|
-
costBearing:
|
|
74342
|
-
actionDigest:
|
|
74343
|
-
argumentDigest:
|
|
74344
|
-
targetDigest:
|
|
74345
|
-
providerCapability:
|
|
74346
|
-
actionSwitch:
|
|
74347
|
-
accountSwitch:
|
|
74348
|
-
grants:
|
|
74349
|
-
assistant:
|
|
74350
|
-
channel:
|
|
74351
|
-
schedule:
|
|
74352
|
-
conversation:
|
|
75014
|
+
costBearing: z51.union([z51.boolean(), z51.literal("unknown")]).optional(),
|
|
75015
|
+
actionDigest: z51.string().optional(),
|
|
75016
|
+
argumentDigest: z51.string().optional(),
|
|
75017
|
+
targetDigest: z51.string().nullable().optional(),
|
|
75018
|
+
providerCapability: z51.enum(["available", "unavailable", "unknown"]).optional(),
|
|
75019
|
+
actionSwitch: z51.enum(["enabled", "disabled", "unknown"]).optional(),
|
|
75020
|
+
accountSwitch: z51.enum(["matched", "unbound", "mismatch", "trial", "unknown"]).optional(),
|
|
75021
|
+
grants: z51.object({
|
|
75022
|
+
assistant: z51.enum(["allow", "deny", "unknown", "not_applicable"]),
|
|
75023
|
+
channel: z51.enum(["allow", "deny", "unknown", "not_applicable"]),
|
|
75024
|
+
schedule: z51.enum(["allow", "deny", "unknown", "not_applicable"]),
|
|
75025
|
+
conversation: z51.enum(["allow", "deny", "unknown", "not_applicable"])
|
|
74353
75026
|
}).strict().optional(),
|
|
74354
|
-
quietHours:
|
|
74355
|
-
financialAuthorization:
|
|
74356
|
-
bulkConfirmation:
|
|
75027
|
+
quietHours: z51.enum(["clear", "active_defer", "timezone_unknown", "not_applicable", "unknown"]).optional(),
|
|
75028
|
+
financialAuthorization: z51.enum(["authorized", "missing", "not_required", "unknown"]).optional(),
|
|
75029
|
+
bulkConfirmation: z51.enum(["confirmed", "missing", "not_applicable"]).optional()
|
|
74357
75030
|
}).strict();
|
|
74358
75031
|
function canonicalJson12(value) {
|
|
74359
75032
|
return JSON.stringify(value, (_key, entry) => entry && typeof entry === "object" && !Array.isArray(entry) ? Object.fromEntries(Object.entries(entry).sort(([a], [b]) => a.localeCompare(b))) : entry);
|
|
74360
75033
|
}
|
|
74361
75034
|
function factDigest(value) {
|
|
74362
|
-
return
|
|
75035
|
+
return createHash82("sha256").update(canonicalJson12(value)).digest("hex");
|
|
74363
75036
|
}
|
|
74364
75037
|
var PostgresPersonalAssistantPolicyFactsRepository = class {
|
|
74365
75038
|
constructor(db, contexts, now = () => /* @__PURE__ */ new Date()) {
|
|
@@ -74549,7 +75222,7 @@ var PostgresPersonalAssistantPolicyFactsRepository = class {
|
|
|
74549
75222
|
};
|
|
74550
75223
|
|
|
74551
75224
|
// src/api/personal-assistant-abuse-controls.ts
|
|
74552
|
-
import { createHash as
|
|
75225
|
+
import { createHash as createHash83 } from "crypto";
|
|
74553
75226
|
var EMPTY_STATE = () => ({
|
|
74554
75227
|
version: 1,
|
|
74555
75228
|
events: [],
|
|
@@ -74560,7 +75233,7 @@ var EMPTY_STATE = () => ({
|
|
|
74560
75233
|
bulkIdentities: {}
|
|
74561
75234
|
});
|
|
74562
75235
|
function digest14(value) {
|
|
74563
|
-
return
|
|
75236
|
+
return createHash83("sha256").update(JSON.stringify(value)).digest("hex");
|
|
74564
75237
|
}
|
|
74565
75238
|
function isDigest(value) {
|
|
74566
75239
|
return typeof value === "string" && /^[a-f0-9]{64}$/.test(value);
|
|
@@ -74820,10 +75493,10 @@ var PostgresPersonalAssistantAbuseStore = class {
|
|
|
74820
75493
|
};
|
|
74821
75494
|
|
|
74822
75495
|
// src/api/twilio-authority-billing-postgres.ts
|
|
74823
|
-
import { createHash as
|
|
75496
|
+
import { createHash as createHash85, randomUUID as randomUUID60 } from "crypto";
|
|
74824
75497
|
|
|
74825
75498
|
// src/api/personal-assistant-billing.ts
|
|
74826
|
-
import { createHash as
|
|
75499
|
+
import { createHash as createHash84 } from "crypto";
|
|
74827
75500
|
var AssistantBillingError = class extends Error {
|
|
74828
75501
|
constructor(code, message) {
|
|
74829
75502
|
super(message);
|
|
@@ -74840,7 +75513,7 @@ function canonicalJson13(value) {
|
|
|
74840
75513
|
});
|
|
74841
75514
|
}
|
|
74842
75515
|
function digest15(value) {
|
|
74843
|
-
return
|
|
75516
|
+
return createHash84("sha256").update(canonicalJson13(value)).digest("hex");
|
|
74844
75517
|
}
|
|
74845
75518
|
function assertMoney(value, field) {
|
|
74846
75519
|
if (!Number.isSafeInteger(value) || value < 0) throw new AssistantBillingError("billing_invalid_input", `${field} must be a non-negative safe integer.`);
|
|
@@ -74885,7 +75558,7 @@ function canonicalJson14(value) {
|
|
|
74885
75558
|
});
|
|
74886
75559
|
}
|
|
74887
75560
|
function digest16(value) {
|
|
74888
|
-
return
|
|
75561
|
+
return createHash85("sha256").update(canonicalJson14(value)).digest("hex");
|
|
74889
75562
|
}
|
|
74890
75563
|
function amountFor2(usage) {
|
|
74891
75564
|
return usage.reduce((sum2, item) => sum2 + item.units * item.rateMinorPerUnit, 0);
|
|
@@ -74957,7 +75630,7 @@ function createPostgresAssistantBillingStore(options = {}) {
|
|
|
74957
75630
|
FROM assistant.commands command WHERE command.owner_user_id=$1 AND command.public_id=$14
|
|
74958
75631
|
RETURNING *, $14::text AS command_ref`, [
|
|
74959
75632
|
input.ownerUserId.toString(),
|
|
74960
|
-
|
|
75633
|
+
randomUUID60(),
|
|
74961
75634
|
input.billingRef,
|
|
74962
75635
|
input.idempotencyKey,
|
|
74963
75636
|
input.requestDigest,
|
|
@@ -74977,7 +75650,7 @@ function createPostgresAssistantBillingStore(options = {}) {
|
|
|
74977
75650
|
SELECT $1,$2,billing.id,$3,$4,'authorize',$5,$6,$7 FROM assistant.billing_holds billing
|
|
74978
75651
|
WHERE billing.owner_user_id=$1 AND billing.public_id=$8`, [
|
|
74979
75652
|
input.ownerUserId.toString(),
|
|
74980
|
-
|
|
75653
|
+
randomUUID60(),
|
|
74981
75654
|
`authorize:${input.idempotencyKey}`,
|
|
74982
75655
|
inputDigest,
|
|
74983
75656
|
input.requestDigest,
|
|
@@ -75043,7 +75716,7 @@ function createPostgresAssistantBillingStore(options = {}) {
|
|
|
75043
75716
|
FROM assistant.billing_holds billing WHERE billing.owner_user_id=$1 AND billing.public_id=$9`,
|
|
75044
75717
|
[
|
|
75045
75718
|
input.ownerUserId.toString(),
|
|
75046
|
-
|
|
75719
|
+
randomUUID60(),
|
|
75047
75720
|
input.eventKey,
|
|
75048
75721
|
eventDigest,
|
|
75049
75722
|
input.outcome,
|
|
@@ -75091,7 +75764,7 @@ function createPostgresAssistantBillingStore(options = {}) {
|
|
|
75091
75764
|
FROM assistant.billing_holds billing WHERE billing.owner_user_id=$1 AND billing.public_id=$8`,
|
|
75092
75765
|
[
|
|
75093
75766
|
input.ownerUserId.toString(),
|
|
75094
|
-
|
|
75767
|
+
randomUUID60(),
|
|
75095
75768
|
input.eventKey,
|
|
75096
75769
|
eventDigest,
|
|
75097
75770
|
input.evidenceDigest,
|
|
@@ -75120,7 +75793,7 @@ function createPostgresAssistantBillingStore(options = {}) {
|
|
|
75120
75793
|
import {
|
|
75121
75794
|
createCipheriv as createCipheriv3,
|
|
75122
75795
|
createDecipheriv as createDecipheriv3,
|
|
75123
|
-
createHash as
|
|
75796
|
+
createHash as createHash86,
|
|
75124
75797
|
createHmac as createHmac14,
|
|
75125
75798
|
randomBytes as randomBytes10
|
|
75126
75799
|
} from "crypto";
|
|
@@ -75178,7 +75851,7 @@ function canonicalContext(input) {
|
|
|
75178
75851
|
});
|
|
75179
75852
|
}
|
|
75180
75853
|
function contextDigest(context) {
|
|
75181
|
-
return
|
|
75854
|
+
return createHash86("sha256").update(context, "utf8").digest("hex");
|
|
75182
75855
|
}
|
|
75183
75856
|
function decodeBase64Url(value, expectedBytes) {
|
|
75184
75857
|
if (!value || !BASE64URL.test(value)) throw new PersonalAssistantProtectedDataCryptoError("protected_data_envelope_invalid");
|
|
@@ -75367,8 +76040,8 @@ async function resolvePersonalAssistantProtectedDataCryptoFactory(options) {
|
|
|
75367
76040
|
}
|
|
75368
76041
|
|
|
75369
76042
|
// src/api/twilio-first-text-context-postgres.ts
|
|
75370
|
-
import { createHash as
|
|
75371
|
-
var digest17 = (value) =>
|
|
76043
|
+
import { createHash as createHash87 } from "crypto";
|
|
76044
|
+
var digest17 = (value) => createHash87("sha256").update(value).digest("hex");
|
|
75372
76045
|
function createPostgresTwilioFirstTextDiagnosticContextResolver(options = {}) {
|
|
75373
76046
|
const queryable = options.queryable ?? getAssistantPool();
|
|
75374
76047
|
return async (input) => {
|
|
@@ -75413,10 +76086,10 @@ function createPostgresTwilioFirstTextDiagnosticContextResolver(options = {}) {
|
|
|
75413
76086
|
}
|
|
75414
76087
|
|
|
75415
76088
|
// src/api/twilio-first-text-diagnostic-postgres.ts
|
|
75416
|
-
import { createHash as
|
|
76089
|
+
import { createHash as createHash89, randomBytes as randomBytes12, randomUUID as randomUUID61 } from "crypto";
|
|
75417
76090
|
|
|
75418
76091
|
// src/api/twilio-first-text-diagnostic.ts
|
|
75419
|
-
import { createHash as
|
|
76092
|
+
import { createHash as createHash88, randomBytes as randomBytes11 } from "crypto";
|
|
75420
76093
|
var TWILIO_FIRST_TEXT_BODY = ASSISTANT_CONSENT_CONTENT_V1.diagnosticMessage;
|
|
75421
76094
|
var TwilioFirstTextDiagnosticError = class extends Error {
|
|
75422
76095
|
constructor(code) {
|
|
@@ -75427,10 +76100,10 @@ var TwilioFirstTextDiagnosticError = class extends Error {
|
|
|
75427
76100
|
code;
|
|
75428
76101
|
};
|
|
75429
76102
|
function digest18(value) {
|
|
75430
|
-
return
|
|
76103
|
+
return createHash88("sha256").update(JSON.stringify(value)).digest("hex");
|
|
75431
76104
|
}
|
|
75432
76105
|
function stableRef2(prefix, identity) {
|
|
75433
|
-
return `${prefix}_${
|
|
76106
|
+
return `${prefix}_${createHash88("sha256").update(identity).digest("hex").slice(0, 32)}`;
|
|
75434
76107
|
}
|
|
75435
76108
|
function providerSid(result3) {
|
|
75436
76109
|
const value = result3.receipt.providerMessageSid;
|
|
@@ -75542,14 +76215,14 @@ function createTwilioFirstTextDiagnosticService(dependencies) {
|
|
|
75542
76215
|
var COLUMNS = `owner_user_id::text,public_id,idempotency_key,request_digest,policy_version,recipient_ref,sender_ref,
|
|
75543
76216
|
state,mode,stages,provider_message_sid,inbound_event_ref,routing_receipt_ref,acknowledgement_receipt_ref,
|
|
75544
76217
|
retry_eligible,failure_code,execution_token_digest,created_at,updated_at`;
|
|
75545
|
-
var digest19 = (value) =>
|
|
76218
|
+
var digest19 = (value) => createHash89("sha256").update(value).digest("hex");
|
|
75546
76219
|
var iso5 = (value) => new Date(value).toISOString();
|
|
75547
76220
|
function receipt3(row) {
|
|
75548
76221
|
return Object.freeze({
|
|
75549
76222
|
diagnosticRef: row.public_id,
|
|
75550
76223
|
ownerUserId: row.owner_user_id,
|
|
75551
76224
|
idempotencyKey: row.idempotency_key,
|
|
75552
|
-
executionRef: `execution_${
|
|
76225
|
+
executionRef: `execution_${createHash89("sha256").update(row.public_id).digest("hex").slice(0, 32)}`,
|
|
75553
76226
|
requestDigest: row.request_digest,
|
|
75554
76227
|
policyVersion: row.policy_version,
|
|
75555
76228
|
recipientRef: row.recipient_ref,
|
|
@@ -75590,7 +76263,7 @@ function createPostgresTwilioFirstTextDiagnosticStore(options = {}) {
|
|
|
75590
76263
|
ON CONFLICT (owner_user_id,idempotency_key) DO NOTHING RETURNING ${COLUMNS}`,
|
|
75591
76264
|
[
|
|
75592
76265
|
input.ownerUserId,
|
|
75593
|
-
|
|
76266
|
+
randomUUID61(),
|
|
75594
76267
|
input.diagnosticRef,
|
|
75595
76268
|
input.idempotencyKey,
|
|
75596
76269
|
input.requestDigest,
|
|
@@ -75717,10 +76390,10 @@ function createTwilioInboundQuarantineClaimAuthorizer(options) {
|
|
|
75717
76390
|
}
|
|
75718
76391
|
|
|
75719
76392
|
// src/api/twilio-inbound-claim-control-plane-postgres.ts
|
|
75720
|
-
import { createHash as
|
|
75721
|
-
var stableRef3 = (prefix, value) => `${prefix}_${
|
|
76393
|
+
import { createHash as createHash90, randomUUID as randomUUID62 } from "crypto";
|
|
76394
|
+
var stableRef3 = (prefix, value) => `${prefix}_${createHash90("sha256").update(value).digest("hex").slice(0, 32)}`;
|
|
75722
76395
|
var stableUuid = (value) => {
|
|
75723
|
-
const hex =
|
|
76396
|
+
const hex = createHash90("sha256").update(value).digest("hex").slice(0, 32).split("");
|
|
75724
76397
|
hex[12] = "5";
|
|
75725
76398
|
hex[16] = (Number.parseInt(hex[16], 16) & 3 | 8).toString(16);
|
|
75726
76399
|
return `${hex.slice(0, 8).join("")}-${hex.slice(8, 12).join("")}-${hex.slice(12, 16).join("")}-${hex.slice(16, 20).join("")}-${hex.slice(20).join("")}`;
|
|
@@ -75771,7 +76444,7 @@ function createPostgresTwilioInboundClaimControlPlane(options) {
|
|
|
75771
76444
|
(owner_user_id,id,public_id,endpoint_key,revision,contact_id,channel,address_ciphertext,address_hash,masked_display,state,reason_code,created_at)
|
|
75772
76445
|
VALUES ($1::bigint,$2,$3,$4,1,$5,'sms',$6,$7,$8,'unverified','claimed_inbound_requires_enrollment',$9::timestamptz)
|
|
75773
76446
|
ON CONFLICT (owner_user_id,public_id) DO NOTHING`,
|
|
75774
|
-
[input.ownerUserId,
|
|
76447
|
+
[input.ownerUserId, randomUUID62(), endpointRef, endpointKey, contact.rows[0].id, sender.ciphertext, sender.digest, mask(input.sender), input.occurredAt]
|
|
75775
76448
|
);
|
|
75776
76449
|
const route = number.rows[0];
|
|
75777
76450
|
const conversationRef = stableRef3(
|
|
@@ -75802,12 +76475,12 @@ function createPostgresTwilioInboundClaimControlPlane(options) {
|
|
|
75802
76475
|
}
|
|
75803
76476
|
|
|
75804
76477
|
// src/api/twilio-inbound-envelope-postgres.ts
|
|
75805
|
-
import { createHash as
|
|
76478
|
+
import { createHash as createHash92 } from "crypto";
|
|
75806
76479
|
|
|
75807
76480
|
// src/api/twilio-inbound-admission-postgres.ts
|
|
75808
|
-
import { createHash as
|
|
76481
|
+
import { createHash as createHash91, randomBytes as randomBytes13, randomUUID as randomUUID63 } from "crypto";
|
|
75809
76482
|
function tokenHash4(value) {
|
|
75810
|
-
return
|
|
76483
|
+
return createHash91("sha256").update(value).digest("hex");
|
|
75811
76484
|
}
|
|
75812
76485
|
function rowToRecord(row) {
|
|
75813
76486
|
return Object.freeze({
|
|
@@ -75852,7 +76525,7 @@ function createPostgresTwilioInboundAdmissionControl(options = {}) {
|
|
|
75852
76525
|
DO UPDATE SET request_count=assistant.twilio_webhook_rate_buckets.request_count+1,updated_at=EXCLUDED.updated_at
|
|
75853
76526
|
RETURNING request_count`, [
|
|
75854
76527
|
input.ownerUserId,
|
|
75855
|
-
|
|
76528
|
+
randomUUID63(),
|
|
75856
76529
|
input.providerAccountRef,
|
|
75857
76530
|
input.scope,
|
|
75858
76531
|
input.subjectKey,
|
|
@@ -75886,7 +76559,7 @@ function createPostgresTwilioInboundAdmissionStore(options = {}) {
|
|
|
75886
76559
|
provider_message_sid,provider_messaging_service_sid,lane_key,routing_state,payload_digest,protected_envelope,state,attempt,admitted_at`,
|
|
75887
76560
|
[
|
|
75888
76561
|
input.ownerUserId,
|
|
75889
|
-
|
|
76562
|
+
randomUUID63(),
|
|
75890
76563
|
input.ingressRef,
|
|
75891
76564
|
input.ownerBindingRef,
|
|
75892
76565
|
input.providerAccountRef,
|
|
@@ -75976,7 +76649,7 @@ function createPostgresTwilioInboundAdmissionStore(options = {}) {
|
|
|
75976
76649
|
|
|
75977
76650
|
// src/api/twilio-inbound-envelope-postgres.ts
|
|
75978
76651
|
function stableRef4(prefix, identity) {
|
|
75979
|
-
return `${prefix}_${
|
|
76652
|
+
return `${prefix}_${createHash92("sha256").update(identity).digest("hex").slice(0, 32)}`;
|
|
75980
76653
|
}
|
|
75981
76654
|
function parseStoredEnvelope(value) {
|
|
75982
76655
|
let parsed;
|
|
@@ -76190,7 +76863,7 @@ function createPostgresTwilioInboundAdmissionRuntime(options) {
|
|
|
76190
76863
|
}
|
|
76191
76864
|
|
|
76192
76865
|
// src/api/twilio-inbound-quarantine-postgres.ts
|
|
76193
|
-
import { randomUUID as
|
|
76866
|
+
import { randomUUID as randomUUID64 } from "crypto";
|
|
76194
76867
|
function createPostgresTwilioInboundQuarantineAdmissionControl(options = {}) {
|
|
76195
76868
|
const transaction2 = options.transaction ?? ((work) => withAssistantTransaction((client2) => work(client2)));
|
|
76196
76869
|
const windowSeconds = options.windowSeconds ?? 60;
|
|
@@ -76270,7 +76943,7 @@ function createPostgresTwilioInboundQuarantineStore(options = {}) {
|
|
|
76270
76943
|
) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,'pending',$11,$12::timestamptz,$13::timestamptz,$14::timestamptz,$14::timestamptz)
|
|
76271
76944
|
ON CONFLICT DO NOTHING RETURNING ${COLUMNS2}`,
|
|
76272
76945
|
[
|
|
76273
|
-
|
|
76946
|
+
randomUUID64(),
|
|
76274
76947
|
input.quarantineRef,
|
|
76275
76948
|
input.providerAccountDigest,
|
|
76276
76949
|
input.providerMessageDigest,
|
|
@@ -76338,11 +77011,11 @@ function createPostgresTwilioInboundQuarantineStore(options = {}) {
|
|
|
76338
77011
|
}
|
|
76339
77012
|
|
|
76340
77013
|
// src/api/twilio-inbound-quarantine.ts
|
|
76341
|
-
import { createHash as
|
|
77014
|
+
import { createHash as createHash93, createHmac as createHmac15, timingSafeEqual as timingSafeEqual10 } from "crypto";
|
|
76342
77015
|
var DIGEST7 = /^[a-f0-9]{64}$/u;
|
|
76343
77016
|
var OPAQUE2 = /^[A-Za-z][A-Za-z0-9_.:-]{2,199}$/u;
|
|
76344
77017
|
function digest20(value) {
|
|
76345
|
-
return
|
|
77018
|
+
return createHash93("sha256").update(value).digest("hex");
|
|
76346
77019
|
}
|
|
76347
77020
|
function stableRef5(prefix, identity) {
|
|
76348
77021
|
return `${prefix}_${digest20(identity).slice(0, 32)}`;
|
|
@@ -76657,10 +77330,10 @@ async function createPersonalAssistantTwilioTransportProduction(options) {
|
|
|
76657
77330
|
}
|
|
76658
77331
|
|
|
76659
77332
|
// src/api/twilio-number-production.ts
|
|
76660
|
-
import { createHash as
|
|
77333
|
+
import { createHash as createHash95, randomUUID as randomUUID66 } from "crypto";
|
|
76661
77334
|
|
|
76662
77335
|
// src/api/twilio-number-repository.ts
|
|
76663
|
-
import { createHash as
|
|
77336
|
+
import { createHash as createHash94, randomUUID as randomUUID65 } from "crypto";
|
|
76664
77337
|
var PUBLIC_REF3 = /^[a-z][a-z0-9_]*_[A-Za-z0-9_-]{3,128}$/;
|
|
76665
77338
|
var DIGEST8 = /^[a-f0-9]{64}$/;
|
|
76666
77339
|
var ACCOUNT_SID4 = /^AC[0-9a-f]{32}$/i;
|
|
@@ -76749,7 +77422,7 @@ function priceValue(value) {
|
|
|
76749
77422
|
}), blocker: null });
|
|
76750
77423
|
}
|
|
76751
77424
|
function digest21(value) {
|
|
76752
|
-
return
|
|
77425
|
+
return createHash94("sha256").update(JSON.stringify(value, (_key, entry) => {
|
|
76753
77426
|
if (!entry || typeof entry !== "object" || Array.isArray(entry)) return entry;
|
|
76754
77427
|
return Object.fromEntries(Object.entries(entry).sort(([a], [b]) => a.localeCompare(b)));
|
|
76755
77428
|
})).digest("hex");
|
|
@@ -76876,7 +77549,7 @@ function createPostgresTwilioNumberOwnerRepository(options) {
|
|
|
76876
77549
|
const ownerUserId2 = requireOwner(options.ownerUserId);
|
|
76877
77550
|
const queryable = options.queryable ?? getAssistantPool();
|
|
76878
77551
|
const transaction2 = options.transaction ?? ((work) => withAssistantTransaction((client2) => work(client2)));
|
|
76879
|
-
const newId = options.newId ??
|
|
77552
|
+
const newId = options.newId ?? randomUUID65;
|
|
76880
77553
|
const now = options.now ?? (() => /* @__PURE__ */ new Date());
|
|
76881
77554
|
const snapshot = validateSnapshot(options.resourceSnapshot, ownerUserId2, now());
|
|
76882
77555
|
async function numberRow(numberRef) {
|
|
@@ -77536,13 +78209,13 @@ function createPostgresTwilioNumberProductionAdapters(options) {
|
|
|
77536
78209
|
}
|
|
77537
78210
|
function twilioProviderAccountDigest(providerAccountRef) {
|
|
77538
78211
|
if (!ACCOUNT_SID4.test(providerAccountRef)) throw new TwilioNumberRepositoryError("invalid_provider_account", "Twilio account assignment is invalid.", 400);
|
|
77539
|
-
return
|
|
78212
|
+
return createHash94("sha256").update(providerAccountRef).digest("hex");
|
|
77540
78213
|
}
|
|
77541
78214
|
|
|
77542
78215
|
// src/api/twilio-number-production.ts
|
|
77543
78216
|
var DIGEST9 = /^[a-f0-9]{64}$/u;
|
|
77544
78217
|
function hash3(value) {
|
|
77545
|
-
return
|
|
78218
|
+
return createHash95("sha256").update(typeof value === "string" ? value : JSON.stringify(value, (_key, entry) => {
|
|
77546
78219
|
if (!entry || typeof entry !== "object" || Array.isArray(entry)) return entry;
|
|
77547
78220
|
return Object.fromEntries(Object.entries(entry).sort(([a], [b]) => a.localeCompare(b)));
|
|
77548
78221
|
})).digest("hex");
|
|
@@ -77795,12 +78468,12 @@ function createPostgresTwilioNumberAuthorityAdapters(options) {
|
|
|
77795
78468
|
WHERE approval.owner_user_id=$1 AND approval.state IN ('pending','approved') AND command.owner_user_id=approval.owner_user_id
|
|
77796
78469
|
AND command.id=approval.command_id AND command.assistant_id=$2`, [ownerUserId2.toString(), row.assistant_id]);
|
|
77797
78470
|
const authorityEpoch = hash3({ ownerUserId: ownerUserId2.toString(), numberRef: input.numberRef, releaseRef: input.releaseRef, occurredAt: input.occurredAt });
|
|
77798
|
-
const auditRef = `audit_${
|
|
78471
|
+
const auditRef = `audit_${randomUUID66().replace(/-/g, "")}`;
|
|
77799
78472
|
await client2.query(
|
|
77800
78473
|
`INSERT INTO assistant.audit_events(owner_user_id,id,public_id,assistant_id,actor_kind,event_type,
|
|
77801
78474
|
operation,decision,reason_code,correlation_id,evidence_digest,details,occurred_at)
|
|
77802
78475
|
VALUES($1,$2,$3,$4,'system','twilio.number.release.freeze','twilio.number.release','allow','authority_invalidated',$5,$6,$7::jsonb,$8)`,
|
|
77803
|
-
[ownerUserId2.toString(),
|
|
78476
|
+
[ownerUserId2.toString(), randomUUID66(), auditRef, row.assistant_id, authorityEpoch, hash3(input.releaseRef), JSON.stringify({ numberRef: input.numberRef, releaseRef: input.releaseRef }), input.occurredAt]
|
|
77804
78477
|
);
|
|
77805
78478
|
return {
|
|
77806
78479
|
authorityEpoch,
|
|
@@ -77955,7 +78628,7 @@ function createTwilioNumberProductionInterfaces(options) {
|
|
|
77955
78628
|
}
|
|
77956
78629
|
|
|
77957
78630
|
// src/api/twilio-number-service.ts
|
|
77958
|
-
import { createHash as
|
|
78631
|
+
import { createHash as createHash96, randomUUID as randomUUID67 } from "crypto";
|
|
77959
78632
|
var DEFAULT_RESERVATION_TTL_MS = 5 * 60 * 1e3;
|
|
77960
78633
|
var MIN_RESERVATION_TTL_MS = 60 * 1e3;
|
|
77961
78634
|
var MAX_RESERVATION_TTL_MS = 10 * 60 * 1e3;
|
|
@@ -78091,7 +78764,7 @@ function canonicalJson15(value) {
|
|
|
78091
78764
|
});
|
|
78092
78765
|
}
|
|
78093
78766
|
function digest22(value) {
|
|
78094
|
-
return
|
|
78767
|
+
return createHash96("sha256").update(canonicalJson15(value)).digest("hex");
|
|
78095
78768
|
}
|
|
78096
78769
|
function requireIdempotencyKey(value) {
|
|
78097
78770
|
if (typeof value !== "string" || !/^[A-Za-z0-9][A-Za-z0-9:._/-]{7,239}$/.test(value)) {
|
|
@@ -78212,7 +78885,7 @@ function publicReleaseReceipt(receipt4, replayed = receipt4.replayed) {
|
|
|
78212
78885
|
}
|
|
78213
78886
|
function createTwilioNumberService(dependencies = {}) {
|
|
78214
78887
|
const now = dependencies.now ?? (() => /* @__PURE__ */ new Date());
|
|
78215
|
-
const newId = dependencies.newId ??
|
|
78888
|
+
const newId = dependencies.newId ?? randomUUID67;
|
|
78216
78889
|
const ttlMs = dependencies.reservationTtlMs ?? DEFAULT_RESERVATION_TTL_MS;
|
|
78217
78890
|
if (!Number.isInteger(ttlMs) || ttlMs < MIN_RESERVATION_TTL_MS || ttlMs > MAX_RESERVATION_TTL_MS) {
|
|
78218
78891
|
throw new TwilioNumberServiceError("invalid_configuration", "Number reservation lifetime must be from one through ten minutes.", 500);
|
|
@@ -79520,7 +80193,7 @@ function presence(env) {
|
|
|
79520
80193
|
}
|
|
79521
80194
|
function fingerprintDigest(env) {
|
|
79522
80195
|
const value = env.PA_NEON_BINDING_FINGERPRINT?.trim();
|
|
79523
|
-
return value ?
|
|
80196
|
+
return value ? createHash97("sha256").update("personal-assistant-binding-v1\0").update(value).digest("hex") : null;
|
|
79524
80197
|
}
|
|
79525
80198
|
function missingHostedBindings(env) {
|
|
79526
80199
|
return Object.entries(REQUIRED_HOSTED_BINDINGS).filter(([, variable]) => !env[variable]?.trim()).map(([name]) => `binding_${name}_missing`);
|
|
@@ -79753,7 +80426,7 @@ function shouldRunSiteExtractInBackground(input) {
|
|
|
79753
80426
|
}
|
|
79754
80427
|
|
|
79755
80428
|
// src/api/page-media-artifacts.ts
|
|
79756
|
-
import { createHash as
|
|
80429
|
+
import { createHash as createHash98, randomBytes as randomBytes14 } from "crypto";
|
|
79757
80430
|
import { homedir as homedir4 } from "os";
|
|
79758
80431
|
import { basename, extname, join as join9 } from "path";
|
|
79759
80432
|
import pLimit6 from "p-limit";
|
|
@@ -79900,7 +80573,7 @@ async function fetchMedia(rawUrl, expectedType) {
|
|
|
79900
80573
|
finalUrl: checked.parsed.href,
|
|
79901
80574
|
width: dimensions?.width ?? null,
|
|
79902
80575
|
height: dimensions?.height ?? null,
|
|
79903
|
-
sha256:
|
|
80576
|
+
sha256: createHash98("sha256").update(bytes2).digest("hex")
|
|
79904
80577
|
};
|
|
79905
80578
|
}
|
|
79906
80579
|
throw new Error("media_redirect_rejected");
|
|
@@ -80106,13 +80779,13 @@ async function reconcileSiteExtractSettlements(limit = 25) {
|
|
|
80106
80779
|
}
|
|
80107
80780
|
|
|
80108
80781
|
// src/api/page-diff.ts
|
|
80109
|
-
import { createHash as
|
|
80782
|
+
import { createHash as createHash99 } from "crypto";
|
|
80110
80783
|
import { diffLines } from "diff";
|
|
80111
80784
|
var MAX_SNAPSHOT_CONTENT_CHARS = 25e4;
|
|
80112
80785
|
var MAX_DIFF_HUNKS = 200;
|
|
80113
80786
|
var MAX_DIFF_LINES_PER_RESPONSE = 2e3;
|
|
80114
80787
|
function sha256Hex(value) {
|
|
80115
|
-
return
|
|
80788
|
+
return createHash99("sha256").update(value).digest("hex");
|
|
80116
80789
|
}
|
|
80117
80790
|
function truncateForStorage(value, maxChars = MAX_SNAPSHOT_CONTENT_CHARS) {
|
|
80118
80791
|
if (value.length <= maxChars) return { value, truncated: false };
|
|
@@ -80226,10 +80899,10 @@ async function persistScrapeBody(user, opts) {
|
|
|
80226
80899
|
}
|
|
80227
80900
|
|
|
80228
80901
|
// src/api/scrape-image-sink.ts
|
|
80229
|
-
import { createHash as
|
|
80902
|
+
import { createHash as createHash100 } from "crypto";
|
|
80230
80903
|
var MAX_IMAGES_PER_SCRAPE = 25;
|
|
80231
80904
|
function idempotencyKey3(userId, vault, input) {
|
|
80232
|
-
return `scrape-image-${
|
|
80905
|
+
return `scrape-image-${createHash100("sha256").update(`${userId}\0${vault}\0${input.sourceKind}\0${input.sourceUrl}\0${input.imageUrl ?? ""}\0${input.imageBase64 ?? ""}`).digest("hex")}`;
|
|
80233
80906
|
}
|
|
80234
80907
|
async function persistScrapeImagesToMemory(user, inputs, vault) {
|
|
80235
80908
|
const selected = inputs.slice(0, MAX_IMAGES_PER_SCRAPE);
|
|
@@ -80701,7 +81374,7 @@ function inferredWaybackCapturedAt(content) {
|
|
|
80701
81374
|
}
|
|
80702
81375
|
|
|
80703
81376
|
// src/api/connection-memory-import.ts
|
|
80704
|
-
import { createHash as
|
|
81377
|
+
import { createHash as createHash101 } from "crypto";
|
|
80705
81378
|
var CONNECTION_MEMORY_IMPORT_MAX_ARGS_BYTES = 64 * 1024;
|
|
80706
81379
|
var CONNECTION_MEMORY_IMPORT_MAX_RESULT_BYTES = 1e6;
|
|
80707
81380
|
var CONNECTION_MEMORY_IMPORT_MAX_STRING_CHARS = 256e3;
|
|
@@ -80731,7 +81404,7 @@ function canonicalJson16(value) {
|
|
|
80731
81404
|
return JSON.stringify(value);
|
|
80732
81405
|
}
|
|
80733
81406
|
function sha2562(value) {
|
|
80734
|
-
return
|
|
81407
|
+
return createHash101("sha256").update(value).digest("hex");
|
|
80735
81408
|
}
|
|
80736
81409
|
function sensitiveKey(key3) {
|
|
80737
81410
|
const normalized = key3.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
@@ -81000,7 +81673,7 @@ async function cleanupExpiredScrapeBlobs(maxAgeMs = SCRAPE_BLOB_TTL_MS) {
|
|
|
81000
81673
|
}
|
|
81001
81674
|
|
|
81002
81675
|
// src/api/site-export-reader.ts
|
|
81003
|
-
import { createHash as
|
|
81676
|
+
import { createHash as createHash102 } from "crypto";
|
|
81004
81677
|
var SiteExportFormatUnavailableError = class extends Error {
|
|
81005
81678
|
constructor(format) {
|
|
81006
81679
|
super(`The ${format} representation was not retained for this export page.`);
|
|
@@ -81010,7 +81683,7 @@ var SiteExportFormatUnavailableError = class extends Error {
|
|
|
81010
81683
|
format;
|
|
81011
81684
|
};
|
|
81012
81685
|
function sha2563(value) {
|
|
81013
|
-
return
|
|
81686
|
+
return createHash102("sha256").update(value).digest("hex");
|
|
81014
81687
|
}
|
|
81015
81688
|
function publicPageRecord(page3) {
|
|
81016
81689
|
const { bodyMarkdown: _body, contentRef: _contentRef, discoveryLinks: _discovery, ...metadata } = page3;
|
|
@@ -81120,7 +81793,7 @@ async function readOwnedSiteExportImage(input) {
|
|
|
81120
81793
|
}
|
|
81121
81794
|
|
|
81122
81795
|
// src/api/search-console-table-export.ts
|
|
81123
|
-
import { randomUUID as
|
|
81796
|
+
import { randomUUID as randomUUID68 } from "crypto";
|
|
81124
81797
|
var SEARCH_CONSOLE_TABLE_EXPORT_MAX_ROWS = 5e4;
|
|
81125
81798
|
var SEARCH_CONSOLE_TABLE_EXPORT_PAGE_SIZE = 2e3;
|
|
81126
81799
|
var SEARCH_CONSOLE_TABLE_EXPORT_MAX_BYTES = 50 * 1024 * 1024;
|
|
@@ -81220,7 +81893,7 @@ async function exportSearchConsoleTableData(args) {
|
|
|
81220
81893
|
offset += rows.length;
|
|
81221
81894
|
if (stoppedForBytes || rows.length < limit || offset >= matchedRows) break;
|
|
81222
81895
|
}
|
|
81223
|
-
const exportId =
|
|
81896
|
+
const exportId = randomUUID68();
|
|
81224
81897
|
const artifact = await args.writeArtifact({
|
|
81225
81898
|
ownerId: args.ownerId,
|
|
81226
81899
|
exportId,
|
|
@@ -81575,7 +82248,7 @@ async function dbUsage(identity, plan) {
|
|
|
81575
82248
|
}
|
|
81576
82249
|
|
|
81577
82250
|
// src/api/resend-control.ts
|
|
81578
|
-
import { createHash as
|
|
82251
|
+
import { createHash as createHash103 } from "crypto";
|
|
81579
82252
|
var DEFAULT_CONNECTION_CONTROL_URL = "https://mcp-scraper-scheduler.vercel.app";
|
|
81580
82253
|
var RESEND_PROVIDER_CONFIG_KEY = "resend";
|
|
81581
82254
|
var RESEND_LOGO_URL = "https://cdn.resend.com/brand/resend-icon-black.svg";
|
|
@@ -81834,7 +82507,7 @@ async function callResendRead(identity, connectionId, tool, args) {
|
|
|
81834
82507
|
return isRecord9(data) ? data.result ?? data : data;
|
|
81835
82508
|
}
|
|
81836
82509
|
async function callResendAction(identity, connectionId, tool, input, idempotencyKey4) {
|
|
81837
|
-
const requestId = `main-resend-action:${
|
|
82510
|
+
const requestId = `main-resend-action:${createHash103("sha256").update(identity).update("\0").update(idempotencyKey4.trim()).digest("hex")}`;
|
|
81838
82511
|
const body3 = await controlRequest2("/api/internal/resend/actions/call", {
|
|
81839
82512
|
method: "POST",
|
|
81840
82513
|
headers: { "x-request-id": requestId },
|
|
@@ -81998,7 +82671,7 @@ var requirePaidSchedulingTier = createMiddleware5(async (c, next) => {
|
|
|
81998
82671
|
if (!hasPaidSchedulingAccess(user)) return c.json(paidPlanRequiredPayload(), 403);
|
|
81999
82672
|
return next();
|
|
82000
82673
|
});
|
|
82001
|
-
var app = new
|
|
82674
|
+
var app = new Hono49();
|
|
82002
82675
|
app.use("*", async (_c, next) => {
|
|
82003
82676
|
await personalAssistantProductionStartup;
|
|
82004
82677
|
return next();
|
|
@@ -83050,7 +83723,7 @@ app.post("/schedule-connections/actions/gmail/send-message", auth5, requireInteg
|
|
|
83050
83723
|
}
|
|
83051
83724
|
try {
|
|
83052
83725
|
const result3 = await directGmailService.sendMessage({
|
|
83053
|
-
ownerId:
|
|
83726
|
+
ownerId: createHash104("sha256").update(user.api_key).digest("hex").slice(0, 24),
|
|
83054
83727
|
providerIdentity: user.email,
|
|
83055
83728
|
connectionId,
|
|
83056
83729
|
to: body3.to,
|
|
@@ -83812,7 +84485,7 @@ app.post("/harvest", auth5, async (c) => {
|
|
|
83812
84485
|
if (!harvestOk) return c.json(insufficientBalanceResponse(harvestBal, harvestCost), 402);
|
|
83813
84486
|
jobId2 = await createJob(user.id, options.query, { ...options, billingHoldMc: harvestCost }, body3.callback_url);
|
|
83814
84487
|
} else {
|
|
83815
|
-
jobId2 = derivedJobId ??
|
|
84488
|
+
jobId2 = derivedJobId ?? randomUUID69();
|
|
83816
84489
|
const billingDebitKey = `paa-harvest:${jobId2}:hold`;
|
|
83817
84490
|
const description = `PAA harvest: ${options.query}`.slice(0, 500);
|
|
83818
84491
|
const hold2 = await debitMcIdempotent(
|
|
@@ -85367,7 +86040,7 @@ app.get("/cron/tick", async (c) => {
|
|
|
85367
86040
|
return c.json({ error: "Unauthorized" }, 401);
|
|
85368
86041
|
}
|
|
85369
86042
|
const startedAt = Date.now();
|
|
85370
|
-
const { drainQueue } = await import("./worker-
|
|
86043
|
+
const { drainQueue } = await import("./worker-OQSFSLNG.js");
|
|
85371
86044
|
const budget = { maxJobs: 10, deadlineMs: startedAt + CRON_TICK_DRAIN_BUDGET_MS };
|
|
85372
86045
|
const origin = `${new URL(c.req.url).protocol}//${new URL(c.req.url).host}`;
|
|
85373
86046
|
const unfinished = [];
|
|
@@ -85491,8 +86164,8 @@ app.post("/api/internal/extract-refinalize/:id", async (c) => {
|
|
|
85491
86164
|
finishExtractJob: finishExtractJob2,
|
|
85492
86165
|
terminalExtractJobStatus: terminalExtractJobStatus2,
|
|
85493
86166
|
extractJobLimitInfo: extractJobLimitInfo2
|
|
85494
|
-
} = await import("./site-extract-repository-
|
|
85495
|
-
const { assembleExtractArtifacts } = await import("./extract-bundle-
|
|
86167
|
+
} = await import("./site-extract-repository-S5FYNFDY.js");
|
|
86168
|
+
const { assembleExtractArtifacts } = await import("./extract-bundle-FALNLKYY.js");
|
|
85496
86169
|
const existing = await getExtractJob2(jobId2);
|
|
85497
86170
|
if (!existing) return c.json({ error: "job not found" }, 404);
|
|
85498
86171
|
if (existing.status !== "failed") {
|
|
@@ -85519,7 +86192,7 @@ app.post("/api/internal/extract-refinalize/:id", async (c) => {
|
|
|
85519
86192
|
if (!updated) return c.json({ error: "job state changed during re-finalization" }, 409);
|
|
85520
86193
|
let settlement = "already_settled_or_refunded";
|
|
85521
86194
|
if (job.billedMc == null && job.userId != null) {
|
|
85522
|
-
const { settleExtractJob: settleExtractJob3, countSuccessfulPages: countSuccessfulPages2 } = await import("./site-extract-repository-
|
|
86195
|
+
const { settleExtractJob: settleExtractJob3, countSuccessfulPages: countSuccessfulPages2 } = await import("./site-extract-repository-S5FYNFDY.js");
|
|
85523
86196
|
const heldMc = Number(job.options.heldMc ?? 0);
|
|
85524
86197
|
const successful = await countSuccessfulPages2(jobId2);
|
|
85525
86198
|
const usedMc = Math.min(successful * MC_COSTS.page_scrape, heldMc);
|
|
@@ -85575,6 +86248,8 @@ app.route("/workshops", workshopRegistrationApp);
|
|
|
85575
86248
|
app.route("/editorial-reading-room", editorialReadingRoomApp);
|
|
85576
86249
|
app.route("/commons", commonsApp);
|
|
85577
86250
|
app.route("/analytics", analyticsApp);
|
|
86251
|
+
app.route("/crm", crmApp);
|
|
86252
|
+
app.route("/research", researchApp);
|
|
85578
86253
|
app.route("/", scheduledResultApp);
|
|
85579
86254
|
app.route("/public", publicScheduledResultApp);
|
|
85580
86255
|
app.route("/api/internal/scheduled-artifacts", scheduledArtifactInternalApp);
|