@hraness/peopleblade 0.1.1 → 0.1.2
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/README.md +11 -5
- package/THIRD_PARTY_NOTICES.md +2 -2
- package/dist/cli.ts +31 -0
- package/dist/cloud-sync-client.js +1827 -0
- package/dist/migrations/016_source_binding_metadata_incarnations.sql +205 -0
- package/dist/peopleblade.js +442 -378
- package/package.json +3 -2
package/dist/peopleblade.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
// @bun
|
|
3
|
+
var __require = import.meta.require;
|
|
3
4
|
|
|
4
5
|
// src/cli/main.ts
|
|
5
6
|
import { existsSync as existsSync5 } from "fs";
|
|
@@ -5800,6 +5801,9 @@ function parseGranolaImportJson(raw) {
|
|
|
5800
5801
|
|
|
5801
5802
|
// src/local/cloud-client.ts
|
|
5802
5803
|
import { createHash as createHash2, randomBytes } from "crypto";
|
|
5804
|
+
import { z as z6 } from "zod";
|
|
5805
|
+
|
|
5806
|
+
// src/local/cloud-configuration.ts
|
|
5803
5807
|
import { z as z5 } from "zod";
|
|
5804
5808
|
|
|
5805
5809
|
// src/local/config.ts
|
|
@@ -5856,6 +5860,100 @@ function writeLocalConfig(config) {
|
|
|
5856
5860
|
renameSync(temporary, path);
|
|
5857
5861
|
}
|
|
5858
5862
|
|
|
5863
|
+
// src/local/cloud-configuration.ts
|
|
5864
|
+
var cloudConfigurationSchema = z5.object({
|
|
5865
|
+
baseUrl: z5.url().max(2048),
|
|
5866
|
+
deviceId: z5.uuid(),
|
|
5867
|
+
token: z5.string().min(20).max(512)
|
|
5868
|
+
}).strict();
|
|
5869
|
+
function cloudConfiguration(override) {
|
|
5870
|
+
const config = override ?? readLocalConfig().cloud;
|
|
5871
|
+
if (config === null)
|
|
5872
|
+
throw new Error("Run `peopleblade cloud signin` first.");
|
|
5873
|
+
return cloudConfigurationSchema.parse(config);
|
|
5874
|
+
}
|
|
5875
|
+
|
|
5876
|
+
// src/local/cloud-transport.ts
|
|
5877
|
+
class CloudHttpError extends Error {
|
|
5878
|
+
status;
|
|
5879
|
+
constructor(status, message) {
|
|
5880
|
+
super(message);
|
|
5881
|
+
this.status = status;
|
|
5882
|
+
this.name = "CloudHttpError";
|
|
5883
|
+
}
|
|
5884
|
+
}
|
|
5885
|
+
async function postJson(fetcher, url, body, bearer, timeoutMs = 45000, signal) {
|
|
5886
|
+
const response = await fetcher(url, {
|
|
5887
|
+
method: "POST",
|
|
5888
|
+
headers: { "content-type": "application/json", ...bearer === undefined ? {} : { authorization: `Bearer ${bearer}` } },
|
|
5889
|
+
body: JSON.stringify(body),
|
|
5890
|
+
redirect: "error",
|
|
5891
|
+
signal: signal === undefined ? AbortSignal.timeout(timeoutMs) : AbortSignal.any([signal, AbortSignal.timeout(timeoutMs)])
|
|
5892
|
+
});
|
|
5893
|
+
if (response.bodyUsed || response.body?.locked)
|
|
5894
|
+
await response.text();
|
|
5895
|
+
const reader = response.body?.getReader();
|
|
5896
|
+
let reachedEof = false;
|
|
5897
|
+
let failed = false;
|
|
5898
|
+
try {
|
|
5899
|
+
const raw = reader === undefined ? "" : await readBoundedText(reader);
|
|
5900
|
+
reachedEof = true;
|
|
5901
|
+
return parseResponse(raw, response);
|
|
5902
|
+
} catch (error) {
|
|
5903
|
+
failed = true;
|
|
5904
|
+
throw error;
|
|
5905
|
+
} finally {
|
|
5906
|
+
if (reader !== undefined) {
|
|
5907
|
+
if (!reachedEof) {
|
|
5908
|
+
try {
|
|
5909
|
+
reader.cancel().catch(() => {
|
|
5910
|
+
return;
|
|
5911
|
+
});
|
|
5912
|
+
} catch {}
|
|
5913
|
+
}
|
|
5914
|
+
try {
|
|
5915
|
+
reader.releaseLock();
|
|
5916
|
+
} catch (error) {
|
|
5917
|
+
if (!failed)
|
|
5918
|
+
throw error;
|
|
5919
|
+
}
|
|
5920
|
+
}
|
|
5921
|
+
}
|
|
5922
|
+
}
|
|
5923
|
+
var MAX_RESPONSE_BYTES = 2 * 1024 * 1024;
|
|
5924
|
+
async function readBoundedText(reader) {
|
|
5925
|
+
const bytes = new Uint8Array(MAX_RESPONSE_BYTES + 3);
|
|
5926
|
+
let length = 0;
|
|
5927
|
+
for (;; ) {
|
|
5928
|
+
const next = await reader.read();
|
|
5929
|
+
if (next.done)
|
|
5930
|
+
break;
|
|
5931
|
+
if (next.value.byteLength > bytes.length - length)
|
|
5932
|
+
throw new Error("PeopleBlade cloud response is too large.");
|
|
5933
|
+
bytes.set(next.value, length);
|
|
5934
|
+
length += next.value.byteLength;
|
|
5935
|
+
}
|
|
5936
|
+
const raw = new TextDecoder().decode(bytes.subarray(0, length));
|
|
5937
|
+
if (Buffer.byteLength(raw) > MAX_RESPONSE_BYTES)
|
|
5938
|
+
throw new Error("PeopleBlade cloud response is too large.");
|
|
5939
|
+
return raw;
|
|
5940
|
+
}
|
|
5941
|
+
function parseResponse(raw, response) {
|
|
5942
|
+
let value;
|
|
5943
|
+
try {
|
|
5944
|
+
value = JSON.parse(raw);
|
|
5945
|
+
} catch {
|
|
5946
|
+
if (!response.ok)
|
|
5947
|
+
throw new CloudHttpError(response.status, `PeopleBlade cloud returned HTTP ${response.status} without a JSON error response.`);
|
|
5948
|
+
throw new Error("PeopleBlade cloud returned invalid JSON.");
|
|
5949
|
+
}
|
|
5950
|
+
if (!response.ok) {
|
|
5951
|
+
const message = value !== null && typeof value === "object" && typeof value.message === "string" ? value.message : `PeopleBlade cloud returned HTTP ${response.status}.`;
|
|
5952
|
+
throw new CloudHttpError(response.status, message);
|
|
5953
|
+
}
|
|
5954
|
+
return value;
|
|
5955
|
+
}
|
|
5956
|
+
|
|
5859
5957
|
// src/local/projection.ts
|
|
5860
5958
|
function parseStringArray(value) {
|
|
5861
5959
|
const parsed = JSON.parse(value);
|
|
@@ -5872,12 +5970,6 @@ function iso(value) {
|
|
|
5872
5970
|
function localDatabaseFingerprint(database) {
|
|
5873
5971
|
return localDatabaseInstanceId(database);
|
|
5874
5972
|
}
|
|
5875
|
-
function localSchemaVersion(database) {
|
|
5876
|
-
const row = database.query("SELECT count(*) AS count FROM schema_migrations").get();
|
|
5877
|
-
if (row === null || !Number.isSafeInteger(row.count) || row.count < 1)
|
|
5878
|
-
throw new Error("PeopleBlade schema is not initialized.");
|
|
5879
|
-
return row.count;
|
|
5880
|
-
}
|
|
5881
5973
|
function projectCloudContacts(database) {
|
|
5882
5974
|
const rows = database.query(`
|
|
5883
5975
|
WITH
|
|
@@ -6090,77 +6182,49 @@ function projectCloudContacts(database) {
|
|
|
6090
6182
|
}
|
|
6091
6183
|
|
|
6092
6184
|
// src/local/cloud-client.ts
|
|
6093
|
-
var deviceStartResponse =
|
|
6185
|
+
var deviceStartResponse = z6.object({
|
|
6094
6186
|
deviceCode: deviceCodeSchema,
|
|
6095
|
-
userCode:
|
|
6096
|
-
verificationUri:
|
|
6097
|
-
expiresIn:
|
|
6098
|
-
interval:
|
|
6187
|
+
userCode: z6.string().regex(/^[23456789A-HJ-NP-Z]{8}$/u),
|
|
6188
|
+
verificationUri: z6.url().max(2048),
|
|
6189
|
+
expiresIn: z6.number().int().min(60).max(3600),
|
|
6190
|
+
interval: z6.number().int().min(1).max(30)
|
|
6099
6191
|
}).strict();
|
|
6100
|
-
var deviceStatusResponse =
|
|
6101
|
-
|
|
6102
|
-
|
|
6103
|
-
|
|
6192
|
+
var deviceStatusResponse = z6.discriminatedUnion("status", [
|
|
6193
|
+
z6.object({ status: z6.literal("pending") }).strict(),
|
|
6194
|
+
z6.object({ status: z6.literal("expired") }).strict(),
|
|
6195
|
+
z6.object({ status: z6.literal("authorized"), deviceId: z6.uuid() }).strict()
|
|
6104
6196
|
]);
|
|
6105
|
-
var
|
|
6106
|
-
|
|
6107
|
-
|
|
6108
|
-
|
|
6109
|
-
|
|
6110
|
-
uploadedPageContactCounts: z5.array(z5.number().int().min(1).max(200)).max(1e5)
|
|
6111
|
-
}).strict().superRefine((value, context) => {
|
|
6112
|
-
if (value.uploadedPageContactCounts.length !== value.uploadedPages)
|
|
6113
|
-
context.addIssue({
|
|
6114
|
-
code: "custom",
|
|
6115
|
-
path: ["uploadedPageContactCounts"],
|
|
6116
|
-
message: "Uploaded sync-page manifest length does not match its page count"
|
|
6117
|
-
});
|
|
6118
|
-
const contactCount = value.uploadedPageContactCounts.reduce((sum, count) => sum + count, 0);
|
|
6119
|
-
if (contactCount !== value.uploadedContacts)
|
|
6120
|
-
context.addIssue({
|
|
6121
|
-
code: "custom",
|
|
6122
|
-
path: ["uploadedContacts"],
|
|
6123
|
-
message: "Uploaded sync-page manifest does not match its contact count"
|
|
6124
|
-
});
|
|
6125
|
-
if (!value.resumed && (value.uploadedContacts !== 0 || value.uploadedPages !== 0))
|
|
6126
|
-
context.addIssue({
|
|
6127
|
-
code: "custom",
|
|
6128
|
-
path: ["resumed"],
|
|
6129
|
-
message: "A fresh sync snapshot cannot report uploaded progress"
|
|
6130
|
-
});
|
|
6131
|
-
});
|
|
6132
|
-
var SYNC_PAGE_TIMEOUT_MS = 240000;
|
|
6133
|
-
var boundedModelCoordinateSchema = z5.string().min(1).max(256).regex(/^[A-Za-z0-9][A-Za-z0-9._:/-]*$/u);
|
|
6134
|
-
var usageOperationSchema = z5.string().regex(/^[a-z][a-z0-9_]{0,63}$/u);
|
|
6135
|
-
var usageProviderSchema = z5.string().regex(/^[a-z][a-z0-9_-]{0,63}$/u);
|
|
6136
|
-
var usageUnitSchema = z5.string().regex(/^[a-z][a-z0-9_-]{0,63}$/u);
|
|
6137
|
-
var cliEnrichmentUsageLimitResponse = z5.object({
|
|
6197
|
+
var boundedModelCoordinateSchema = z6.string().min(1).max(256).regex(/^[A-Za-z0-9][A-Za-z0-9._:/-]*$/u);
|
|
6198
|
+
var usageOperationSchema = z6.string().regex(/^[a-z][a-z0-9_]{0,63}$/u);
|
|
6199
|
+
var usageProviderSchema = z6.string().regex(/^[a-z][a-z0-9_-]{0,63}$/u);
|
|
6200
|
+
var usageUnitSchema = z6.string().regex(/^[a-z][a-z0-9_-]{0,63}$/u);
|
|
6201
|
+
var cliEnrichmentUsageLimitResponse = z6.object({
|
|
6138
6202
|
operation: usageOperationSchema,
|
|
6139
6203
|
provider: usageProviderSchema,
|
|
6140
6204
|
unit: usageUnitSchema,
|
|
6141
|
-
maximum:
|
|
6205
|
+
maximum: z6.number().int().min(0).max(100)
|
|
6142
6206
|
}).strict();
|
|
6143
|
-
var cliEnrichmentPreviewResponse =
|
|
6144
|
-
previewId:
|
|
6207
|
+
var cliEnrichmentPreviewResponse = z6.object({
|
|
6208
|
+
previewId: z6.uuid(),
|
|
6145
6209
|
confirmationToken: cliEnrichmentConfirmationTokenSchema,
|
|
6146
|
-
selectedCount:
|
|
6147
|
-
availableCredits:
|
|
6148
|
-
usageLimits:
|
|
6149
|
-
policyVersion:
|
|
6210
|
+
selectedCount: z6.number().int().min(1).max(100),
|
|
6211
|
+
availableCredits: z6.number().int().min(0),
|
|
6212
|
+
usageLimits: z6.array(cliEnrichmentUsageLimitResponse).min(1).max(16),
|
|
6213
|
+
policyVersion: z6.literal(enrichmentPolicyVersion),
|
|
6150
6214
|
model: boundedModelCoordinateSchema,
|
|
6151
|
-
expiresAt:
|
|
6215
|
+
expiresAt: z6.iso.datetime({ offset: true })
|
|
6152
6216
|
}).strict();
|
|
6153
|
-
var cliPrioritizedEnrichmentContactResponse =
|
|
6154
|
-
localPersonId:
|
|
6155
|
-
enrichmentInputVersion:
|
|
6156
|
-
enrichmentInputSha256:
|
|
6157
|
-
rank:
|
|
6158
|
-
score:
|
|
6159
|
-
components:
|
|
6160
|
-
engagement:
|
|
6161
|
-
reciprocity:
|
|
6162
|
-
dataGaps:
|
|
6163
|
-
identityReadiness:
|
|
6217
|
+
var cliPrioritizedEnrichmentContactResponse = z6.object({
|
|
6218
|
+
localPersonId: z6.string().regex(/^[1-9][0-9]{0,18}$/u),
|
|
6219
|
+
enrichmentInputVersion: z6.literal(2),
|
|
6220
|
+
enrichmentInputSha256: z6.string().regex(/^[a-f0-9]{64}$/u),
|
|
6221
|
+
rank: z6.number().int().min(1).max(100),
|
|
6222
|
+
score: z6.number().int().min(0).max(1e4),
|
|
6223
|
+
components: z6.object({
|
|
6224
|
+
engagement: z6.number().int().min(0).max(5500),
|
|
6225
|
+
reciprocity: z6.number().int().min(0).max(1000),
|
|
6226
|
+
dataGaps: z6.number().int().min(0).max(2000),
|
|
6227
|
+
identityReadiness: z6.number().int().min(0).max(1500)
|
|
6164
6228
|
}).strict()
|
|
6165
6229
|
}).strict().superRefine((value, context) => {
|
|
6166
6230
|
const total = value.components.engagement + value.components.reciprocity + value.components.dataGaps + value.components.identityReadiness;
|
|
@@ -6168,39 +6232,39 @@ var cliPrioritizedEnrichmentContactResponse = z5.object({
|
|
|
6168
6232
|
context.addIssue({ code: "custom", path: ["score"], message: "Priority score components drifted" });
|
|
6169
6233
|
});
|
|
6170
6234
|
var cliPrioritizedEnrichmentPreviewResponse = cliEnrichmentPreviewResponse.extend({
|
|
6171
|
-
contacts:
|
|
6172
|
-
priority:
|
|
6173
|
-
policyVersion:
|
|
6174
|
-
asOf:
|
|
6175
|
-
receiptSha256:
|
|
6176
|
-
eligibleCount:
|
|
6177
|
-
executionCapacity:
|
|
6178
|
-
operation:
|
|
6179
|
-
maximum:
|
|
6235
|
+
contacts: z6.array(cliPrioritizedEnrichmentContactResponse).min(1).max(100),
|
|
6236
|
+
priority: z6.object({
|
|
6237
|
+
policyVersion: z6.literal(enrichmentPriorityPolicyVersion),
|
|
6238
|
+
asOf: z6.iso.datetime({ offset: true }),
|
|
6239
|
+
receiptSha256: z6.string().regex(/^[a-f0-9]{64}$/u),
|
|
6240
|
+
eligibleCount: z6.number().int().min(1).max(1e6),
|
|
6241
|
+
executionCapacity: z6.tuple([z6.object({
|
|
6242
|
+
operation: z6.literal("enrich_email"),
|
|
6243
|
+
maximum: z6.number().int().min(0).max(100)
|
|
6180
6244
|
}).strict()])
|
|
6181
6245
|
}).strict()
|
|
6182
6246
|
}).strict();
|
|
6183
|
-
var cliEnrichmentDispatchResponse =
|
|
6184
|
-
jobId:
|
|
6185
|
-
dispatchStatus:
|
|
6186
|
-
replayed:
|
|
6247
|
+
var cliEnrichmentDispatchResponse = z6.object({
|
|
6248
|
+
jobId: z6.uuid(),
|
|
6249
|
+
dispatchStatus: z6.enum(["dispatching", "launched", "indeterminate"]),
|
|
6250
|
+
replayed: z6.boolean()
|
|
6187
6251
|
}).strict();
|
|
6188
|
-
var enrichmentFieldSchema =
|
|
6189
|
-
var usageBillingSurfaceSchema =
|
|
6252
|
+
var enrichmentFieldSchema = z6.enum(["headline", "organization", "role", "location", "website", "publicEmail"]);
|
|
6253
|
+
var usageBillingSurfaceSchema = z6.string().regex(/^[a-z][a-z0-9_-]{0,63}$/u);
|
|
6190
6254
|
var usageModelSchema = boundedModelCoordinateSchema.nullable();
|
|
6191
|
-
var usageBillingUnitSchema =
|
|
6192
|
-
var usageBillingCertaintySchema =
|
|
6193
|
-
var usageOutcomeSchema =
|
|
6194
|
-
var usageErrorCodeSchema =
|
|
6195
|
-
var usageCostCertaintySchema =
|
|
6196
|
-
var usageExecutionRouteSchema =
|
|
6197
|
-
var usageExecutionProfileSha256Schema =
|
|
6198
|
-
var boundedUsageCount =
|
|
6199
|
-
var cliEnrichmentUsageCoverageResponse =
|
|
6200
|
-
ledgerRuns:
|
|
6201
|
-
legacyRuns:
|
|
6255
|
+
var usageBillingUnitSchema = z6.string().regex(/^[a-z][a-z0-9_-]{0,63}$/u).nullable();
|
|
6256
|
+
var usageBillingCertaintySchema = z6.enum(["unknown", "reported", "contractual", "conservative"]);
|
|
6257
|
+
var usageOutcomeSchema = z6.string().regex(/^[a-z][a-z0-9_]{0,63}$/u);
|
|
6258
|
+
var usageErrorCodeSchema = z6.string().regex(/^[A-Z0-9][A-Z0-9_:.-]{2,159}$/u).nullable();
|
|
6259
|
+
var usageCostCertaintySchema = z6.enum(["reported", "contractual", "estimated", "unknown", "reconciled"]);
|
|
6260
|
+
var usageExecutionRouteSchema = z6.string().regex(/^[a-z][a-z0-9_]{0,63}$/u);
|
|
6261
|
+
var usageExecutionProfileSha256Schema = z6.string().regex(/^[0-9a-f]{64}$/u).nullable();
|
|
6262
|
+
var boundedUsageCount = z6.number().int().min(0).max(Number.MAX_SAFE_INTEGER);
|
|
6263
|
+
var cliEnrichmentUsageCoverageResponse = z6.object({
|
|
6264
|
+
ledgerRuns: z6.number().int().min(0).max(100),
|
|
6265
|
+
legacyRuns: z6.number().int().min(0).max(100)
|
|
6202
6266
|
}).strict();
|
|
6203
|
-
var cliEnrichmentProviderUsageResponse =
|
|
6267
|
+
var cliEnrichmentProviderUsageResponse = z6.object({
|
|
6204
6268
|
operation: usageOperationSchema,
|
|
6205
6269
|
executionRoute: usageExecutionRouteSchema,
|
|
6206
6270
|
executionProfileSha256: usageExecutionProfileSha256Schema,
|
|
@@ -6218,57 +6282,57 @@ var cliEnrichmentProviderUsageResponse = z5.object({
|
|
|
6218
6282
|
inputTokens: boundedUsageCount,
|
|
6219
6283
|
outputTokens: boundedUsageCount,
|
|
6220
6284
|
billingUnit: usageBillingUnitSchema,
|
|
6221
|
-
billedUnits:
|
|
6285
|
+
billedUnits: z6.number().min(0).max(Number.MAX_SAFE_INTEGER),
|
|
6222
6286
|
billingCertainty: usageBillingCertaintySchema,
|
|
6223
|
-
billingUnknown:
|
|
6224
|
-
knownCostUsd:
|
|
6287
|
+
billingUnknown: z6.boolean(),
|
|
6288
|
+
knownCostUsd: z6.number().min(0).max(Number.MAX_SAFE_INTEGER),
|
|
6225
6289
|
costCertainty: usageCostCertaintySchema,
|
|
6226
6290
|
unknownCostAttempts: boundedUsageCount
|
|
6227
6291
|
}).strict();
|
|
6228
|
-
var cliEnrichmentAggregateFieldSourceResponse =
|
|
6292
|
+
var cliEnrichmentAggregateFieldSourceResponse = z6.object({
|
|
6229
6293
|
field: enrichmentFieldSchema,
|
|
6230
6294
|
operation: usageOperationSchema,
|
|
6231
6295
|
provider: usageProviderSchema,
|
|
6232
|
-
contacts:
|
|
6296
|
+
contacts: z6.number().int().min(0).max(100)
|
|
6233
6297
|
}).strict();
|
|
6234
|
-
var cliEnrichmentFailureResponse =
|
|
6298
|
+
var cliEnrichmentFailureResponse = z6.object({
|
|
6235
6299
|
operation: usageOperationSchema,
|
|
6236
|
-
count:
|
|
6300
|
+
count: z6.number().int().min(1).max(100)
|
|
6237
6301
|
}).strict();
|
|
6238
|
-
var cliEnrichmentJobStatusV4Response =
|
|
6239
|
-
id:
|
|
6240
|
-
status:
|
|
6241
|
-
dispatchStatus:
|
|
6242
|
-
selectedCount:
|
|
6243
|
-
completedCount:
|
|
6244
|
-
failedCount:
|
|
6245
|
-
productCreditsSpent:
|
|
6302
|
+
var cliEnrichmentJobStatusV4Response = z6.object({
|
|
6303
|
+
id: z6.uuid(),
|
|
6304
|
+
status: z6.enum(["queued", "running", "complete", "partial", "failed"]),
|
|
6305
|
+
dispatchStatus: z6.enum(["dispatching", "launched", "indeterminate"]),
|
|
6306
|
+
selectedCount: z6.number().int().min(1).max(100),
|
|
6307
|
+
completedCount: z6.number().int().min(0).max(100),
|
|
6308
|
+
failedCount: z6.number().int().min(0).max(100),
|
|
6309
|
+
productCreditsSpent: z6.number().int().min(0).max(100),
|
|
6246
6310
|
usageCoverage: cliEnrichmentUsageCoverageResponse,
|
|
6247
|
-
providerUsage:
|
|
6248
|
-
fieldSources:
|
|
6249
|
-
failures:
|
|
6250
|
-
createdAt:
|
|
6251
|
-
completedAt:
|
|
6311
|
+
providerUsage: z6.array(cliEnrichmentProviderUsageResponse).max(256),
|
|
6312
|
+
fieldSources: z6.array(cliEnrichmentAggregateFieldSourceResponse).max(600),
|
|
6313
|
+
failures: z6.array(cliEnrichmentFailureResponse).max(9),
|
|
6314
|
+
createdAt: z6.iso.datetime({ offset: true }),
|
|
6315
|
+
completedAt: z6.iso.datetime({ offset: true }).nullable()
|
|
6252
6316
|
}).strict();
|
|
6253
|
-
var cliEnrichmentRunDetailResponse =
|
|
6254
|
-
localPersonId:
|
|
6255
|
-
status:
|
|
6256
|
-
errorCode:
|
|
6317
|
+
var cliEnrichmentRunDetailResponse = z6.object({
|
|
6318
|
+
localPersonId: z6.string().regex(/^[1-9][0-9]{0,18}$/u),
|
|
6319
|
+
status: z6.enum(["pending", "running", "complete", "failed"]),
|
|
6320
|
+
errorCode: z6.string().min(1).max(200).nullable(),
|
|
6257
6321
|
failureOperation: usageOperationSchema.nullable(),
|
|
6258
|
-
identityMatch:
|
|
6259
|
-
confidence:
|
|
6260
|
-
fieldsPresent:
|
|
6261
|
-
claimFields:
|
|
6322
|
+
identityMatch: z6.enum(["confirmed", "possible", "insufficient"]).nullable(),
|
|
6323
|
+
confidence: z6.number().int().min(0).max(100).nullable(),
|
|
6324
|
+
fieldsPresent: z6.array(enrichmentFieldSchema).max(6),
|
|
6325
|
+
claimFields: z6.array(enrichmentFieldSchema).max(6)
|
|
6262
6326
|
}).strict();
|
|
6263
|
-
var cliEnrichmentRunUsageResponse =
|
|
6327
|
+
var cliEnrichmentRunUsageResponse = z6.object({
|
|
6264
6328
|
operation: usageOperationSchema,
|
|
6265
6329
|
executionRoute: usageExecutionRouteSchema,
|
|
6266
6330
|
executionProfileSha256: usageExecutionProfileSha256Schema,
|
|
6267
|
-
attempt:
|
|
6331
|
+
attempt: z6.number().int().min(1).max(16),
|
|
6268
6332
|
billingSurface: usageBillingSurfaceSchema,
|
|
6269
6333
|
provider: usageProviderSchema,
|
|
6270
6334
|
model: usageModelSchema,
|
|
6271
|
-
status:
|
|
6335
|
+
status: z6.enum(["open", "succeeded", "failed", "indeterminate"]),
|
|
6272
6336
|
outcome: usageOutcomeSchema,
|
|
6273
6337
|
errorCode: usageErrorCodeSchema,
|
|
6274
6338
|
results: boundedUsageCount,
|
|
@@ -6276,10 +6340,10 @@ var cliEnrichmentRunUsageResponse = z5.object({
|
|
|
6276
6340
|
inputTokens: boundedUsageCount,
|
|
6277
6341
|
outputTokens: boundedUsageCount,
|
|
6278
6342
|
billingUnit: usageBillingUnitSchema,
|
|
6279
|
-
billedUnits:
|
|
6343
|
+
billedUnits: z6.number().min(0).max(Number.MAX_SAFE_INTEGER),
|
|
6280
6344
|
billingCertainty: usageBillingCertaintySchema,
|
|
6281
|
-
billingUnknown:
|
|
6282
|
-
costUsd:
|
|
6345
|
+
billingUnknown: z6.boolean(),
|
|
6346
|
+
costUsd: z6.number().min(0).max(Number.MAX_SAFE_INTEGER).nullable(),
|
|
6283
6347
|
costCertainty: usageCostCertaintySchema
|
|
6284
6348
|
}).strict().superRefine((value, context) => {
|
|
6285
6349
|
if ((value.status === "open" || value.status === "succeeded") && value.errorCode !== null) {
|
|
@@ -6290,27 +6354,22 @@ var cliEnrichmentRunUsageResponse = z5.object({
|
|
|
6290
6354
|
});
|
|
6291
6355
|
}
|
|
6292
6356
|
});
|
|
6293
|
-
var cliEnrichmentRunFieldSourceResponse =
|
|
6357
|
+
var cliEnrichmentRunFieldSourceResponse = z6.object({
|
|
6294
6358
|
field: enrichmentFieldSchema,
|
|
6295
|
-
sources:
|
|
6359
|
+
sources: z6.array(z6.object({
|
|
6296
6360
|
operation: usageOperationSchema,
|
|
6297
6361
|
provider: usageProviderSchema,
|
|
6298
|
-
evidenceRows:
|
|
6362
|
+
evidenceRows: z6.number().int().min(1).max(5)
|
|
6299
6363
|
}).strict()).max(5)
|
|
6300
6364
|
}).strict();
|
|
6301
|
-
var cliEnrichmentJobDetailsV4Response =
|
|
6302
|
-
jobId:
|
|
6303
|
-
runs:
|
|
6304
|
-
usageCoverage:
|
|
6305
|
-
usage:
|
|
6306
|
-
fieldSources:
|
|
6365
|
+
var cliEnrichmentJobDetailsV4Response = z6.object({
|
|
6366
|
+
jobId: z6.uuid(),
|
|
6367
|
+
runs: z6.array(cliEnrichmentRunDetailResponse.extend({
|
|
6368
|
+
usageCoverage: z6.enum(["ledger", "legacy"]),
|
|
6369
|
+
usage: z6.array(cliEnrichmentRunUsageResponse).max(512),
|
|
6370
|
+
fieldSources: z6.array(cliEnrichmentRunFieldSourceResponse).max(6)
|
|
6307
6371
|
}).strict()).max(100)
|
|
6308
6372
|
}).strict();
|
|
6309
|
-
var cloudConfigurationSchema = z5.object({
|
|
6310
|
-
baseUrl: z5.url().max(2048),
|
|
6311
|
-
deviceId: z5.uuid(),
|
|
6312
|
-
token: z5.string().min(20).max(512)
|
|
6313
|
-
}).strict();
|
|
6314
6373
|
function baseUrl(value) {
|
|
6315
6374
|
const parsed = new URL(value);
|
|
6316
6375
|
if (parsed.protocol !== "https:" && !(parsed.protocol === "http:" && ["localhost", "127.0.0.1"].includes(parsed.hostname))) {
|
|
@@ -6321,40 +6380,6 @@ function baseUrl(value) {
|
|
|
6321
6380
|
parsed.hash = "";
|
|
6322
6381
|
return parsed.toString().replace(/\/$/u, "");
|
|
6323
6382
|
}
|
|
6324
|
-
|
|
6325
|
-
class CloudHttpError extends Error {
|
|
6326
|
-
status;
|
|
6327
|
-
constructor(status, message) {
|
|
6328
|
-
super(message);
|
|
6329
|
-
this.status = status;
|
|
6330
|
-
this.name = "CloudHttpError";
|
|
6331
|
-
}
|
|
6332
|
-
}
|
|
6333
|
-
async function postJson(fetcher, url, body, bearer, timeoutMs = 45000) {
|
|
6334
|
-
const response = await fetcher(url, {
|
|
6335
|
-
method: "POST",
|
|
6336
|
-
headers: { "content-type": "application/json", ...bearer === undefined ? {} : { authorization: `Bearer ${bearer}` } },
|
|
6337
|
-
body: JSON.stringify(body),
|
|
6338
|
-
redirect: "error",
|
|
6339
|
-
signal: AbortSignal.timeout(timeoutMs)
|
|
6340
|
-
});
|
|
6341
|
-
const raw = await response.text();
|
|
6342
|
-
if (Buffer.byteLength(raw) > 2 * 1024 * 1024)
|
|
6343
|
-
throw new Error("PeopleBlade cloud response is too large.");
|
|
6344
|
-
let value;
|
|
6345
|
-
try {
|
|
6346
|
-
value = JSON.parse(raw);
|
|
6347
|
-
} catch {
|
|
6348
|
-
if (!response.ok)
|
|
6349
|
-
throw new CloudHttpError(response.status, `PeopleBlade cloud returned HTTP ${response.status} without a JSON error response.`);
|
|
6350
|
-
throw new Error("PeopleBlade cloud returned invalid JSON.");
|
|
6351
|
-
}
|
|
6352
|
-
if (!response.ok) {
|
|
6353
|
-
const message = value !== null && typeof value === "object" && typeof value.message === "string" ? value.message : `PeopleBlade cloud returned HTTP ${response.status}.`;
|
|
6354
|
-
throw new CloudHttpError(response.status, message);
|
|
6355
|
-
}
|
|
6356
|
-
return value;
|
|
6357
|
-
}
|
|
6358
6383
|
function clearCloudCredentials(options) {
|
|
6359
6384
|
(options.clearCredentials ?? (() => writeLocalConfig({ cloud: null })))();
|
|
6360
6385
|
}
|
|
@@ -6421,62 +6446,8 @@ async function signOutCloud(options = {}) {
|
|
|
6421
6446
|
}
|
|
6422
6447
|
}
|
|
6423
6448
|
async function syncCloud(database, options = {}) {
|
|
6424
|
-
const
|
|
6425
|
-
|
|
6426
|
-
throw new Error("Run `peopleblade cloud signin` first.");
|
|
6427
|
-
const validatedConfig = cloudConfigurationSchema.parse(config);
|
|
6428
|
-
const fetcher = options.fetcher ?? fetch;
|
|
6429
|
-
const pageSize = Math.max(1, Math.min(200, options.pageSize ?? 200));
|
|
6430
|
-
const contacts = projectCloudContacts(database);
|
|
6431
|
-
const startInput = syncStartSchema.parse({
|
|
6432
|
-
contactCount: contacts.length,
|
|
6433
|
-
databaseFingerprint: localDatabaseFingerprint(database),
|
|
6434
|
-
schemaVersion: localSchemaVersion(database),
|
|
6435
|
-
resumeVersion: 1
|
|
6436
|
-
});
|
|
6437
|
-
const started = syncStartResponse.parse(await postJson(fetcher, `${validatedConfig.baseUrl}/api/cli/sync/start`, startInput, validatedConfig.token, 285000));
|
|
6438
|
-
if (started.uploadedContacts > contacts.length) {
|
|
6439
|
-
throw new Error("Cloud sync resume progress exceeds the current local projection.");
|
|
6440
|
-
}
|
|
6441
|
-
let pages = 0;
|
|
6442
|
-
let offset = 0;
|
|
6443
|
-
for (const priorPageContacts of started.uploadedPageContactCounts) {
|
|
6444
|
-
const replayContacts = contacts.slice(offset, offset + priorPageContacts);
|
|
6445
|
-
if (replayContacts.length !== priorPageContacts) {
|
|
6446
|
-
throw new Error("Cloud sync resume manifest exceeds the current local projection.");
|
|
6447
|
-
}
|
|
6448
|
-
const input = syncPageSchema.parse({ snapshotId: started.snapshotId, ordinal: pages, contacts: replayContacts });
|
|
6449
|
-
await postJson(fetcher, `${validatedConfig.baseUrl}/api/cli/sync/page`, input, validatedConfig.token, SYNC_PAGE_TIMEOUT_MS);
|
|
6450
|
-
pages += 1;
|
|
6451
|
-
offset += priorPageContacts;
|
|
6452
|
-
}
|
|
6453
|
-
if (offset !== started.uploadedContacts || pages !== started.uploadedPages) {
|
|
6454
|
-
throw new Error("Cloud sync resume manifest did not reproduce its reported progress.");
|
|
6455
|
-
}
|
|
6456
|
-
for (;offset < contacts.length; offset += pageSize) {
|
|
6457
|
-
const input = syncPageSchema.parse({ snapshotId: started.snapshotId, ordinal: pages, contacts: contacts.slice(offset, offset + pageSize) });
|
|
6458
|
-
await postJson(fetcher, `${validatedConfig.baseUrl}/api/cli/sync/page`, input, validatedConfig.token, SYNC_PAGE_TIMEOUT_MS);
|
|
6459
|
-
pages += 1;
|
|
6460
|
-
}
|
|
6461
|
-
const finish = syncFinishSchema.parse({ snapshotId: started.snapshotId, pages, contactCount: contacts.length });
|
|
6462
|
-
await postJson(fetcher, `${validatedConfig.baseUrl}/api/cli/sync/finish`, finish, validatedConfig.token);
|
|
6463
|
-
database.query(`INSERT INTO cloud_sync_state(singleton,base_url,device_id,last_snapshot_id,last_synced_at)
|
|
6464
|
-
VALUES (1,?,?,?,CURRENT_TIMESTAMP)
|
|
6465
|
-
ON CONFLICT(singleton) DO UPDATE SET base_url=excluded.base_url, device_id=excluded.device_id,
|
|
6466
|
-
last_snapshot_id=excluded.last_snapshot_id, last_synced_at=excluded.last_synced_at`).run(validatedConfig.baseUrl, validatedConfig.deviceId, started.snapshotId);
|
|
6467
|
-
return {
|
|
6468
|
-
snapshotId: started.snapshotId,
|
|
6469
|
-
contacts: contacts.length,
|
|
6470
|
-
pages,
|
|
6471
|
-
resumed: started.resumed,
|
|
6472
|
-
replayedPages: started.uploadedPages
|
|
6473
|
-
};
|
|
6474
|
-
}
|
|
6475
|
-
function cloudConfiguration(override) {
|
|
6476
|
-
const config = override ?? readLocalConfig().cloud;
|
|
6477
|
-
if (config === null)
|
|
6478
|
-
throw new Error("Run `peopleblade cloud signin` first.");
|
|
6479
|
-
return cloudConfigurationSchema.parse(config);
|
|
6449
|
+
const { startCloudSync } = __require("./cloud-sync-client.js");
|
|
6450
|
+
return startCloudSync(database, options, postJson);
|
|
6480
6451
|
}
|
|
6481
6452
|
function selectedLocalContacts(database, personIds, config) {
|
|
6482
6453
|
const unique = [...new Set(personIds)].sort((left, right) => left - right);
|
|
@@ -6504,11 +6475,13 @@ function selectedLocalContacts(database, personIds, config) {
|
|
|
6504
6475
|
async function previewCloudEnrichment(database, personIds, options = {}) {
|
|
6505
6476
|
const config = cloudConfiguration(options.configuration);
|
|
6506
6477
|
const contacts = selectedLocalContacts(database, personIds, config);
|
|
6507
|
-
const response = cliEnrichmentPreviewResponse.parse(await postJson(options.fetcher ?? fetch, `${config.baseUrl}/api/cli/enrich/preview`, {
|
|
6508
|
-
|
|
6509
|
-
|
|
6510
|
-
|
|
6511
|
-
|
|
6478
|
+
const response = cliEnrichmentPreviewResponse.parse(await postJson(options.fetcher ?? fetch, `${config.baseUrl}/api/cli/enrich/preview`, {
|
|
6479
|
+
contacts: contacts.map((contact) => ({
|
|
6480
|
+
localPersonId: contact.localPersonId,
|
|
6481
|
+
enrichmentInputVersion: contact.enrichmentInputVersion,
|
|
6482
|
+
enrichmentInputSha256: contact.enrichmentInputSha256
|
|
6483
|
+
}))
|
|
6484
|
+
}, config.token));
|
|
6512
6485
|
const contactCreditLimits = response.usageLimits.filter((limit) => limit.operation === "enrich_contact" && limit.unit === "credit");
|
|
6513
6486
|
if (response.selectedCount !== contacts.length || contactCreditLimits.length !== 1 || contactCreditLimits[0]?.maximum !== contacts.length || new Set(response.usageLimits.map((limit) => `${limit.operation}\x00${limit.provider}\x00${limit.unit}`)).size !== response.usageLimits.length) {
|
|
6514
6487
|
throw new Error("PeopleBlade cloud enrichment preview count drifted.");
|
|
@@ -6886,12 +6859,13 @@ function assertSourceBindingCurrent(database, authority, binding) {
|
|
|
6886
6859
|
const current = readSourceBindingState(database, authority, binding.authId);
|
|
6887
6860
|
if (current === null)
|
|
6888
6861
|
return;
|
|
6889
|
-
if (current.subjectSha256 !== binding.subjectSha256 || current.authSha256 !== binding.authSha256) {
|
|
6890
|
-
throw new Error("Source authorization changed its bound provider target. Run the provider's explicit rebind transition before syncing.");
|
|
6862
|
+
if (current.subjectSha256 !== binding.subjectSha256 || current.authSha256 !== binding.authSha256 || canonicalJson(current.metadata) !== canonicalJson(binding.metadata)) {
|
|
6863
|
+
throw new Error("Source authorization changed its bound provider target or reviewed metadata. Run the provider's explicit rebind transition before syncing.");
|
|
6891
6864
|
}
|
|
6892
6865
|
}
|
|
6893
6866
|
function bindSourceBinding(database, authority, binding, observedAt) {
|
|
6894
|
-
const byAuth = getRow(database, `SELECT binding.id,incarnation.subject_sha256,incarnation.auth_sha256
|
|
6867
|
+
const byAuth = getRow(database, `SELECT binding.id,incarnation.subject_sha256,incarnation.auth_sha256,
|
|
6868
|
+
incarnation.metadata_json
|
|
6895
6869
|
FROM source_bindings binding
|
|
6896
6870
|
JOIN current_source_binding_incarnations incarnation
|
|
6897
6871
|
ON incarnation.source_binding_id=binding.id
|
|
@@ -6904,29 +6878,47 @@ function bindSourceBinding(database, authority, binding, observedAt) {
|
|
|
6904
6878
|
if (byAuth !== null && (byAuth.subject_sha256 !== binding.subjectSha256 || byAuth.auth_sha256 !== binding.authSha256) || bySubject !== null && (bySubject.auth_id !== binding.authId || bySubject.auth_sha256 !== binding.authSha256)) {
|
|
6905
6879
|
throw new Error("Source authorization is already bound to a different stable realm.");
|
|
6906
6880
|
}
|
|
6881
|
+
const metadataJson = canonicalJson(binding.metadata);
|
|
6882
|
+
if (byAuth !== null && byAuth.metadata_json !== metadataJson) {
|
|
6883
|
+
throw new Error("Source authorization changed its reviewed metadata. Run the provider's explicit rebind transition before syncing.");
|
|
6884
|
+
}
|
|
6907
6885
|
if (byAuth === null) {
|
|
6908
6886
|
return insertedId(database.query(`INSERT INTO source_bindings(
|
|
6909
6887
|
authority,auth_id,subject_sha256,auth_sha256,first_seen_at,last_seen_at,metadata_json
|
|
6910
|
-
) VALUES (?,?,?,?,?,?,?)`).run(authority, binding.authId, binding.subjectSha256, binding.authSha256, observedAt, observedAt,
|
|
6888
|
+
) VALUES (?,?,?,?,?,?,?)`).run(authority, binding.authId, binding.subjectSha256, binding.authSha256, observedAt, observedAt, metadataJson));
|
|
6911
6889
|
}
|
|
6912
6890
|
const current = getRow(database, "SELECT last_seen_at FROM source_bindings WHERE id=?", byAuth.id);
|
|
6913
6891
|
if (current === null) {
|
|
6914
6892
|
throw new Error("Source authorization disappeared while it was being bound.");
|
|
6915
6893
|
}
|
|
6916
6894
|
if (isAtLeastAsRecent(observedAt, current.last_seen_at)) {
|
|
6917
|
-
database.query("UPDATE source_bindings SET last_seen_at=?,metadata_json=? WHERE id=?").run(observedAt,
|
|
6895
|
+
database.query("UPDATE source_bindings SET last_seen_at=?,metadata_json=? WHERE id=?").run(observedAt, metadataJson, byAuth.id);
|
|
6918
6896
|
database.query(`UPDATE source_binding_incarnations SET last_seen_at=?,metadata_json=?
|
|
6919
|
-
WHERE source_binding_id=? AND retired_at IS NULL`).run(observedAt,
|
|
6897
|
+
WHERE source_binding_id=? AND retired_at IS NULL`).run(observedAt, metadataJson, byAuth.id);
|
|
6920
6898
|
}
|
|
6921
6899
|
return byAuth.id;
|
|
6922
6900
|
}
|
|
6923
|
-
function
|
|
6901
|
+
function commitSourceBindingTransition(database, input, transition) {
|
|
6924
6902
|
if (input.next.authId !== input.authId) {
|
|
6925
6903
|
throw new Error("Source binding transition cannot change the authorization ID.");
|
|
6926
6904
|
}
|
|
6927
|
-
|
|
6905
|
+
const identityChanged = input.next.subjectSha256 !== input.expected.subjectSha256 || input.next.authSha256 !== input.expected.authSha256;
|
|
6906
|
+
const metadataChanged = canonicalJson(input.next.metadata) !== input.expected.metadataJson;
|
|
6907
|
+
if (transition === "identity" && !identityChanged) {
|
|
6928
6908
|
throw new Error("Source binding transition requires a changed subject or authorization identity.");
|
|
6929
6909
|
}
|
|
6910
|
+
if (transition === "metadata" && identityChanged) {
|
|
6911
|
+
throw new Error("Source binding metadata transition cannot change subject or authorization identity.");
|
|
6912
|
+
}
|
|
6913
|
+
if (transition === "metadata" && !metadataChanged) {
|
|
6914
|
+
throw new Error("Source binding metadata transition requires changed metadata.");
|
|
6915
|
+
}
|
|
6916
|
+
if (transition === "metadata" && (input.expected.completeRealmInventoryObservedAt === null || input.expected.completeRealmInventorySha256 === null || input.completeRealmInventorySha256 !== input.expected.completeRealmInventorySha256 || input.verifyLocked === undefined)) {
|
|
6917
|
+
throw new Error("Source binding metadata transition requires an exact complete inventory proof.");
|
|
6918
|
+
}
|
|
6919
|
+
if (input.next.subjectSha256 === input.expected.subjectSha256 && input.next.authSha256 === input.expected.authSha256 && canonicalJson(input.next.metadata) === input.expected.metadataJson) {
|
|
6920
|
+
throw new Error("Source binding transition cannot append an unchanged incarnation.");
|
|
6921
|
+
}
|
|
6930
6922
|
const evidenceJson = canonicalJson(input.evidence);
|
|
6931
6923
|
if (Buffer.byteLength(evidenceJson, "utf8") > 64 * 1024) {
|
|
6932
6924
|
throw new Error("Source binding transition evidence exceeds 64 KiB.");
|
|
@@ -6978,6 +6970,26 @@ function transitionSourceBinding(database, input) {
|
|
|
6978
6970
|
throw error;
|
|
6979
6971
|
}
|
|
6980
6972
|
}
|
|
6973
|
+
function transitionSourceBinding(database, input) {
|
|
6974
|
+
return commitSourceBindingTransition(database, input, "identity");
|
|
6975
|
+
}
|
|
6976
|
+
function transitionSourceBindingMetadata(database, input) {
|
|
6977
|
+
return commitSourceBindingTransition(database, {
|
|
6978
|
+
authority: input.authority,
|
|
6979
|
+
authId: input.authId,
|
|
6980
|
+
expected: input.expected,
|
|
6981
|
+
next: {
|
|
6982
|
+
authId: input.authId,
|
|
6983
|
+
subjectSha256: input.expected.subjectSha256,
|
|
6984
|
+
authSha256: input.expected.authSha256,
|
|
6985
|
+
metadata: input.nextMetadata
|
|
6986
|
+
},
|
|
6987
|
+
observedAt: input.observedAt,
|
|
6988
|
+
completeRealmInventorySha256: input.completeRealmInventorySha256,
|
|
6989
|
+
evidence: input.evidence,
|
|
6990
|
+
verifyLocked: input.verifyLocked
|
|
6991
|
+
}, "metadata");
|
|
6992
|
+
}
|
|
6981
6993
|
function bindSourceRealmCoordinates(database, authority, accountKey, binding, realm, observedAt) {
|
|
6982
6994
|
const sourceBindingId = bindSourceBinding(database, authority, binding, observedAt);
|
|
6983
6995
|
const existingRealm = getRow(database, `SELECT id,source_binding_id,identity_namespace,external_id_sha256,state_observed_at
|
|
@@ -7440,16 +7452,16 @@ import {
|
|
|
7440
7452
|
import { basename as basename2, dirname as dirname3, join as join3, resolve as resolve2 } from "path";
|
|
7441
7453
|
|
|
7442
7454
|
// src/lib/ensoul-contracts.ts
|
|
7443
|
-
import { z as
|
|
7455
|
+
import { z as z7 } from "zod";
|
|
7444
7456
|
var ensoulSourcePacketVersion = "ensoul.source-packet.v1";
|
|
7445
7457
|
var peoplebladeEnsoulAdapter = "peopleblade";
|
|
7446
7458
|
var peoplebladeEnsoulPayloadSchema = "ensoul.public-enrichment-source.v1";
|
|
7447
7459
|
var ensoulDigestCanonicalization = "JCS-RFC8785";
|
|
7448
|
-
var digestSchema =
|
|
7449
|
-
var prefixedDigestSchema =
|
|
7450
|
-
var timestampSchema =
|
|
7451
|
-
var boundedText2 = (maximum) =>
|
|
7452
|
-
var positiveSafeInteger =
|
|
7460
|
+
var digestSchema = z7.string().regex(/^[a-f0-9]{64}$/u);
|
|
7461
|
+
var prefixedDigestSchema = z7.string().regex(/^sha256:[a-f0-9]{64}$/u);
|
|
7462
|
+
var timestampSchema = z7.iso.datetime({ offset: true });
|
|
7463
|
+
var boundedText2 = (maximum) => z7.string().trim().min(1).max(maximum);
|
|
7464
|
+
var positiveSafeInteger = z7.number().int().positive().max(Number.MAX_SAFE_INTEGER);
|
|
7453
7465
|
function assertWellFormedUnicode(value) {
|
|
7454
7466
|
for (let index = 0;index < value.length; index += 1) {
|
|
7455
7467
|
const code = value.charCodeAt(index);
|
|
@@ -7491,7 +7503,7 @@ function ensoulJcsCanonicalJson(value) {
|
|
|
7491
7503
|
}
|
|
7492
7504
|
throw new Error("JCS input is not valid JSON.");
|
|
7493
7505
|
}
|
|
7494
|
-
var ensoulSourceClassSchema =
|
|
7506
|
+
var ensoulSourceClassSchema = z7.enum([
|
|
7495
7507
|
"private_capture",
|
|
7496
7508
|
"polished_self_presentation",
|
|
7497
7509
|
"observed_behavior",
|
|
@@ -7500,24 +7512,24 @@ var ensoulSourceClassSchema = z6.enum([
|
|
|
7500
7512
|
"metadata",
|
|
7501
7513
|
"public_web_evidence"
|
|
7502
7514
|
]);
|
|
7503
|
-
var ensoulSourceRecordSemanticSchema =
|
|
7515
|
+
var ensoulSourceRecordSemanticSchema = z7.object({
|
|
7504
7516
|
id: boundedText2(200),
|
|
7505
7517
|
kind: boundedText2(100),
|
|
7506
7518
|
occurredAt: timestampSchema.optional(),
|
|
7507
7519
|
observedAt: timestampSchema.optional(),
|
|
7508
|
-
authorRole:
|
|
7509
|
-
contentRole:
|
|
7510
|
-
authorshipConfidence:
|
|
7511
|
-
sentStatus:
|
|
7512
|
-
visibility:
|
|
7520
|
+
authorRole: z7.enum(["subject", "counterpart", "third_party", "mixed", "unknown"]),
|
|
7521
|
+
contentRole: z7.enum(["original", "quoted", "forwarded", "summary", "ai_assisted", "mixed", "unknown"]),
|
|
7522
|
+
authorshipConfidence: z7.enum(["verified", "strong", "weak", "unknown"]),
|
|
7523
|
+
sentStatus: z7.enum(["sent", "draft", "received", "published", "unknown"]),
|
|
7524
|
+
visibility: z7.enum(["public", "private"]),
|
|
7513
7525
|
sourceClass: ensoulSourceClassSchema,
|
|
7514
|
-
content:
|
|
7515
|
-
text:
|
|
7516
|
-
title:
|
|
7526
|
+
content: z7.object({
|
|
7527
|
+
text: z7.string().max(50000).optional(),
|
|
7528
|
+
title: z7.string().max(1000).optional(),
|
|
7517
7529
|
url: httpUrlSchema.optional(),
|
|
7518
|
-
truncated:
|
|
7530
|
+
truncated: z7.boolean().optional()
|
|
7519
7531
|
}).strict().refine((content) => content.text !== undefined || content.title !== undefined || content.url !== undefined, "Record content requires text, title, or URL"),
|
|
7520
|
-
provenance:
|
|
7532
|
+
provenance: z7.object({
|
|
7521
7533
|
provider: boundedText2(100),
|
|
7522
7534
|
operation: boundedText2(160).optional(),
|
|
7523
7535
|
sourceId: boundedText2(300).optional(),
|
|
@@ -7530,17 +7542,17 @@ var ensoulSourceRecordSemanticSchema = z6.object({
|
|
|
7530
7542
|
var ensoulSourceRecordSchema = ensoulSourceRecordSemanticSchema.extend({
|
|
7531
7543
|
digest: prefixedDigestSchema
|
|
7532
7544
|
}).strict();
|
|
7533
|
-
var ensoulClaimSchema =
|
|
7545
|
+
var ensoulClaimSchema = z7.object({
|
|
7534
7546
|
id: boundedText2(200),
|
|
7535
7547
|
text: boundedText2(4000),
|
|
7536
|
-
recordIds:
|
|
7537
|
-
status:
|
|
7538
|
-
claimantRole:
|
|
7539
|
-
claimKind:
|
|
7548
|
+
recordIds: z7.array(boundedText2(200)).min(1).max(50).refine((values) => new Set(values).size === values.length, "Claim record IDs must be unique"),
|
|
7549
|
+
status: z7.enum(["source_reported", "adapter_structured", "contested"]),
|
|
7550
|
+
claimantRole: z7.enum(["subject", "counterpart", "third_party", "institutional", "adapter", "unknown"]),
|
|
7551
|
+
claimKind: z7.enum(["fact", "stated_belief", "reported_observation", "derived_index"]),
|
|
7540
7552
|
subjectLocalId: boundedText2(200),
|
|
7541
|
-
sensitivity:
|
|
7553
|
+
sensitivity: z7.enum(["ordinary", "sensitive_explicit"])
|
|
7542
7554
|
}).strict();
|
|
7543
|
-
var ensoulLimitationSchema =
|
|
7555
|
+
var ensoulLimitationSchema = z7.enum([
|
|
7544
7556
|
"Public-web evidence plus bounded local subject background only; this packet is not a complete account of the person.",
|
|
7545
7557
|
"Web authorship is unknown; no record is a direct subject voice sample.",
|
|
7546
7558
|
"Private messages and CRM notes are excluded.",
|
|
@@ -7548,41 +7560,41 @@ var ensoulLimitationSchema = z6.enum([
|
|
|
7548
7560
|
"Raw provider payloads, credentials, and unrelated contacts are excluded.",
|
|
7549
7561
|
"Do not infer sensitive traits, diagnoses, consent, or permission to act from this packet."
|
|
7550
7562
|
]);
|
|
7551
|
-
var peoplebladeEnsoulPacketBodySchema =
|
|
7552
|
-
schemaVersion:
|
|
7553
|
-
digestCanonicalization:
|
|
7563
|
+
var peoplebladeEnsoulPacketBodySchema = z7.object({
|
|
7564
|
+
schemaVersion: z7.literal(ensoulSourcePacketVersion),
|
|
7565
|
+
digestCanonicalization: z7.literal(ensoulDigestCanonicalization),
|
|
7554
7566
|
generatedAt: timestampSchema,
|
|
7555
|
-
subject:
|
|
7567
|
+
subject: z7.object({
|
|
7556
7568
|
localId: boundedText2(200),
|
|
7557
|
-
kind:
|
|
7569
|
+
kind: z7.literal("person"),
|
|
7558
7570
|
displayName: boundedText2(300).optional(),
|
|
7559
7571
|
identityBasis: boundedText2(1000)
|
|
7560
7572
|
}).strict(),
|
|
7561
|
-
scope:
|
|
7562
|
-
adapter:
|
|
7563
|
-
payloadSchema:
|
|
7573
|
+
scope: z7.object({
|
|
7574
|
+
adapter: z7.literal(peoplebladeEnsoulAdapter),
|
|
7575
|
+
payloadSchema: z7.literal(peoplebladeEnsoulPayloadSchema),
|
|
7564
7576
|
asOf: timestampSchema,
|
|
7565
7577
|
sourceCutoff: timestampSchema.optional(),
|
|
7566
|
-
completeness:
|
|
7578
|
+
completeness: z7.enum(["complete", "sampled", "bounded", "unknown"]),
|
|
7567
7579
|
sourceRevision: boundedText2(300),
|
|
7568
|
-
limits:
|
|
7580
|
+
limits: z7.object({
|
|
7569
7581
|
maxCurrentEnrichments: positiveSafeInteger,
|
|
7570
7582
|
maxRecords: positiveSafeInteger,
|
|
7571
7583
|
maxClaims: positiveSafeInteger,
|
|
7572
7584
|
maxPacketBytes: positiveSafeInteger,
|
|
7573
7585
|
oldestObservedAt: timestampSchema.nullable(),
|
|
7574
|
-
exactContactCoordinates:
|
|
7575
|
-
notes:
|
|
7576
|
-
messages:
|
|
7577
|
-
rawProviderPayloads:
|
|
7586
|
+
exactContactCoordinates: z7.literal("excluded-or-redacted"),
|
|
7587
|
+
notes: z7.literal("excluded"),
|
|
7588
|
+
messages: z7.literal("excluded"),
|
|
7589
|
+
rawProviderPayloads: z7.literal("excluded")
|
|
7578
7590
|
}).strict()
|
|
7579
7591
|
}).strict(),
|
|
7580
|
-
records:
|
|
7581
|
-
claims:
|
|
7582
|
-
limitations:
|
|
7592
|
+
records: z7.array(ensoulSourceRecordSchema).max(2000),
|
|
7593
|
+
claims: z7.array(ensoulClaimSchema).max(500),
|
|
7594
|
+
limitations: z7.array(ensoulLimitationSchema).min(1).max(32)
|
|
7583
7595
|
}).strict();
|
|
7584
7596
|
var peoplebladeEnsoulPacketSemanticSchema = peoplebladeEnsoulPacketBodySchema.extend({
|
|
7585
|
-
packetId:
|
|
7597
|
+
packetId: z7.string().trim().min(8).max(160)
|
|
7586
7598
|
}).strict();
|
|
7587
7599
|
var ensoulSourcePacketSchema = peoplebladeEnsoulPacketSemanticSchema.extend({
|
|
7588
7600
|
packetDigest: prefixedDigestSchema
|
|
@@ -10158,15 +10170,15 @@ function syncAppleContacts(database, options = {}) {
|
|
|
10158
10170
|
}
|
|
10159
10171
|
|
|
10160
10172
|
// src/local/source-ingestion.ts
|
|
10161
|
-
import { z as
|
|
10162
|
-
var providerSchema =
|
|
10163
|
-
var boundedText3 = (maximum) =>
|
|
10173
|
+
import { z as z8 } from "zod";
|
|
10174
|
+
var providerSchema = z8.string().regex(/^[a-z][a-z0-9-]{0,63}$/u);
|
|
10175
|
+
var boundedText3 = (maximum) => z8.string().min(1).max(maximum).refine((value) => !/[\u0000\r]/u.test(value), "Text contains an unsupported control character");
|
|
10164
10176
|
var nullableText3 = (maximum) => boundedText3(maximum).nullable();
|
|
10165
|
-
var digestSchema2 =
|
|
10166
|
-
var timestampSchema2 =
|
|
10177
|
+
var digestSchema2 = z8.string().regex(/^[a-f0-9]{64}$/u);
|
|
10178
|
+
var timestampSchema2 = z8.iso.datetime({ offset: true });
|
|
10167
10179
|
var sqliteNoCase = (value) => value.replace(/[A-Z]/gu, (character) => character.toLowerCase());
|
|
10168
|
-
var jsonObjectSchema =
|
|
10169
|
-
var personSchema =
|
|
10180
|
+
var jsonObjectSchema = z8.record(z8.string(), z8.json()).refine((value) => Buffer.byteLength(canonicalJson(value), "utf8") <= 64 * 1024, "Metadata exceeds 64 KiB");
|
|
10181
|
+
var personSchema = z8.object({
|
|
10170
10182
|
displayName: nullableText3(1024),
|
|
10171
10183
|
givenName: nullableText3(1024),
|
|
10172
10184
|
middleName: nullableText3(1024),
|
|
@@ -10179,16 +10191,16 @@ var personSchema = z7.object({
|
|
|
10179
10191
|
title: nullableText3(1024),
|
|
10180
10192
|
birthday: birthdaySchema,
|
|
10181
10193
|
observationBasis: boundedText3(128),
|
|
10182
|
-
observationPriority:
|
|
10194
|
+
observationPriority: z8.number().int().min(0).max(1000),
|
|
10183
10195
|
metadata: jsonObjectSchema
|
|
10184
10196
|
}).strict();
|
|
10185
|
-
var resourceSchema =
|
|
10197
|
+
var resourceSchema = z8.object({
|
|
10186
10198
|
type: boundedText3(64),
|
|
10187
10199
|
id: boundedText3(4096),
|
|
10188
10200
|
username: nullableText3(2048),
|
|
10189
10201
|
profileUrl: nullableText3(4096),
|
|
10190
|
-
profileUrlIdentityEligible:
|
|
10191
|
-
nameIdentityEligible:
|
|
10202
|
+
profileUrlIdentityEligible: z8.boolean(),
|
|
10203
|
+
nameIdentityEligible: z8.boolean(),
|
|
10192
10204
|
displayName: nullableText3(2048),
|
|
10193
10205
|
metadata: jsonObjectSchema
|
|
10194
10206
|
}).strict().superRefine((resource, context) => {
|
|
@@ -10199,20 +10211,20 @@ var resourceSchema = z7.object({
|
|
|
10199
10211
|
message: "An identity-eligible profile URL must be a stored HTTP(S) profile URL"
|
|
10200
10212
|
});
|
|
10201
10213
|
});
|
|
10202
|
-
var methodSchema =
|
|
10203
|
-
kind:
|
|
10214
|
+
var methodSchema = z8.object({
|
|
10215
|
+
kind: z8.enum(["email", "phone", "url", "address", "date", "social", "other"]),
|
|
10204
10216
|
value: boundedText3(8192),
|
|
10205
10217
|
normalizedValue: boundedText3(8192),
|
|
10206
|
-
label:
|
|
10207
|
-
primary:
|
|
10208
|
-
confidence:
|
|
10209
|
-
identityEligible:
|
|
10218
|
+
label: z8.string().max(256),
|
|
10219
|
+
primary: z8.boolean(),
|
|
10220
|
+
confidence: z8.enum(["exact", "likely", "possible", "unknown"]),
|
|
10221
|
+
identityEligible: z8.boolean(),
|
|
10210
10222
|
metadata: jsonObjectSchema
|
|
10211
10223
|
}).strict();
|
|
10212
|
-
var contactSchema =
|
|
10224
|
+
var contactSchema = z8.object({
|
|
10213
10225
|
person: personSchema,
|
|
10214
10226
|
resource: resourceSchema,
|
|
10215
|
-
methods:
|
|
10227
|
+
methods: z8.array(methodSchema).max(1000)
|
|
10216
10228
|
}).strict().superRefine((contact, context) => {
|
|
10217
10229
|
const coordinates = new Set;
|
|
10218
10230
|
contact.methods.forEach((method, index) => {
|
|
@@ -10223,24 +10235,24 @@ var contactSchema = z7.object({
|
|
|
10223
10235
|
coordinates.add(coordinate);
|
|
10224
10236
|
});
|
|
10225
10237
|
});
|
|
10226
|
-
var completenessSchema =
|
|
10227
|
-
var coverageSchema =
|
|
10228
|
-
localEnumerationComplete:
|
|
10229
|
-
remoteSetComplete:
|
|
10230
|
-
truncated:
|
|
10231
|
-
absencePolicy:
|
|
10232
|
-
warnings:
|
|
10238
|
+
var completenessSchema = z8.enum(["complete", "partial", "lower-bound", "unknown"]);
|
|
10239
|
+
var coverageSchema = z8.object({
|
|
10240
|
+
localEnumerationComplete: z8.boolean(),
|
|
10241
|
+
remoteSetComplete: z8.boolean(),
|
|
10242
|
+
truncated: z8.boolean(),
|
|
10243
|
+
absencePolicy: z8.enum(["reconcile-observed", "preserve"]),
|
|
10244
|
+
warnings: z8.array(boundedText3(128)).max(32)
|
|
10233
10245
|
}).strict();
|
|
10234
|
-
var interactionSchema =
|
|
10246
|
+
var interactionSchema = z8.object({
|
|
10235
10247
|
resourceType: boundedText3(64),
|
|
10236
10248
|
resourceId: boundedText3(4096),
|
|
10237
|
-
sentCount:
|
|
10238
|
-
receivedCount:
|
|
10239
|
-
interactionCount:
|
|
10240
|
-
conversationCount:
|
|
10249
|
+
sentCount: z8.number().int().min(0).max(Number.MAX_SAFE_INTEGER),
|
|
10250
|
+
receivedCount: z8.number().int().min(0).max(Number.MAX_SAFE_INTEGER),
|
|
10251
|
+
interactionCount: z8.number().int().min(0).max(Number.MAX_SAFE_INTEGER),
|
|
10252
|
+
conversationCount: z8.number().int().min(0).max(Number.MAX_SAFE_INTEGER).nullable(),
|
|
10241
10253
|
firstInteractionAt: timestampSchema2.nullable(),
|
|
10242
10254
|
lastInteractionAt: timestampSchema2.nullable(),
|
|
10243
|
-
reciprocal:
|
|
10255
|
+
reciprocal: z8.boolean(),
|
|
10244
10256
|
completeness: completenessSchema,
|
|
10245
10257
|
metadata: jsonObjectSchema
|
|
10246
10258
|
}).strict().superRefine((interaction, context) => {
|
|
@@ -10253,32 +10265,32 @@ var interactionSchema = z7.object({
|
|
|
10253
10265
|
if (interaction.interactionCount === 0 && (interaction.firstInteractionAt !== null || interaction.lastInteractionAt !== null) || interaction.interactionCount > 0 && (interaction.firstInteractionAt === null || interaction.lastInteractionAt === null) || interaction.firstInteractionAt !== null && interaction.lastInteractionAt !== null && Date.parse(interaction.firstInteractionAt) > Date.parse(interaction.lastInteractionAt))
|
|
10254
10266
|
context.addIssue({ code: "custom", path: ["firstInteractionAt"], message: "Interaction timestamps do not match the observed count" });
|
|
10255
10267
|
});
|
|
10256
|
-
var sourceBindingSchema =
|
|
10268
|
+
var sourceBindingSchema = z8.object({
|
|
10257
10269
|
authId: boundedText3(128),
|
|
10258
10270
|
authSha256: digestSchema2,
|
|
10259
10271
|
subjectSha256: digestSchema2,
|
|
10260
10272
|
metadata: jsonObjectSchema
|
|
10261
10273
|
}).strict();
|
|
10262
|
-
var sourceRealmSchema =
|
|
10274
|
+
var sourceRealmSchema = z8.object({
|
|
10263
10275
|
service: boundedText3(64),
|
|
10264
10276
|
identityNamespace: boundedText3(128),
|
|
10265
10277
|
externalIdSha256: digestSchema2,
|
|
10266
10278
|
metadata: jsonObjectSchema
|
|
10267
10279
|
}).strict();
|
|
10268
|
-
var sourceRealmInventoryEntrySchema =
|
|
10280
|
+
var sourceRealmInventoryEntrySchema = z8.object({
|
|
10269
10281
|
accountKey: boundedText3(256),
|
|
10270
10282
|
sourceRealm: sourceRealmSchema
|
|
10271
10283
|
}).strict();
|
|
10272
|
-
var sourceRealmInventorySchema =
|
|
10273
|
-
schemaVersion:
|
|
10284
|
+
var sourceRealmInventorySchema = z8.object({
|
|
10285
|
+
schemaVersion: z8.literal(1),
|
|
10274
10286
|
provider: providerSchema,
|
|
10275
10287
|
observedAt: timestampSchema2,
|
|
10276
10288
|
sourceBinding: sourceBindingSchema,
|
|
10277
|
-
localEnumerationComplete:
|
|
10278
|
-
truncated:
|
|
10279
|
-
absencePolicy:
|
|
10280
|
-
realms:
|
|
10281
|
-
warnings:
|
|
10289
|
+
localEnumerationComplete: z8.boolean(),
|
|
10290
|
+
truncated: z8.boolean(),
|
|
10291
|
+
absencePolicy: z8.enum(["reconcile-observed", "preserve"]),
|
|
10292
|
+
realms: z8.array(sourceRealmInventoryEntrySchema).max(128),
|
|
10293
|
+
warnings: z8.array(boundedText3(128)).max(32)
|
|
10282
10294
|
}).strict().superRefine((inventory, context) => {
|
|
10283
10295
|
if (inventory.absencePolicy === "reconcile-observed" && (!inventory.localEnumerationComplete || inventory.truncated)) {
|
|
10284
10296
|
context.addIssue({
|
|
@@ -10301,8 +10313,8 @@ var sourceRealmInventorySchema = z7.object({
|
|
|
10301
10313
|
externalIds.add(entry.sourceRealm.externalIdSha256);
|
|
10302
10314
|
});
|
|
10303
10315
|
});
|
|
10304
|
-
var contactSourceSnapshotSchema =
|
|
10305
|
-
schemaVersion:
|
|
10316
|
+
var contactSourceSnapshotSchema = z8.object({
|
|
10317
|
+
schemaVersion: z8.literal(1),
|
|
10306
10318
|
provider: providerSchema,
|
|
10307
10319
|
accountKey: boundedText3(256),
|
|
10308
10320
|
mode: boundedText3(64),
|
|
@@ -10313,8 +10325,8 @@ var contactSourceSnapshotSchema = z7.object({
|
|
|
10313
10325
|
observedAt: timestampSchema2,
|
|
10314
10326
|
sourceBinding: sourceBindingSchema,
|
|
10315
10327
|
sourceRealm: sourceRealmSchema,
|
|
10316
|
-
contacts:
|
|
10317
|
-
interactions:
|
|
10328
|
+
contacts: z8.array(contactSchema).max(250000),
|
|
10329
|
+
interactions: z8.array(interactionSchema).max(250000),
|
|
10318
10330
|
metadata: jsonObjectSchema
|
|
10319
10331
|
}).strict().superRefine((snapshot, context) => {
|
|
10320
10332
|
if (snapshot.coverage.absencePolicy === "reconcile-observed" && (!snapshot.coverage.localEnumerationComplete || snapshot.coverage.truncated)) {
|
|
@@ -10354,19 +10366,19 @@ function resourceStableKey(snapshot, resource) {
|
|
|
10354
10366
|
return `source:${sha256(canonicalJson([snapshot.provider, snapshot.accountKey, resource.type, resource.id]))}`;
|
|
10355
10367
|
}
|
|
10356
10368
|
function parseCachedResult(value) {
|
|
10357
|
-
return
|
|
10358
|
-
account_key:
|
|
10359
|
-
source_rows:
|
|
10360
|
-
people_created:
|
|
10361
|
-
people_matched:
|
|
10362
|
-
methods_touched:
|
|
10363
|
-
interactions_touched:
|
|
10364
|
-
resources_removed:
|
|
10365
|
-
reconciled:
|
|
10369
|
+
return z8.object({
|
|
10370
|
+
account_key: z8.string(),
|
|
10371
|
+
source_rows: z8.number().int(),
|
|
10372
|
+
people_created: z8.number().int(),
|
|
10373
|
+
people_matched: z8.number().int(),
|
|
10374
|
+
methods_touched: z8.number().int(),
|
|
10375
|
+
interactions_touched: z8.number().int(),
|
|
10376
|
+
resources_removed: z8.number().int(),
|
|
10377
|
+
reconciled: z8.boolean(),
|
|
10366
10378
|
completeness: completenessSchema,
|
|
10367
|
-
local_enumeration_complete:
|
|
10368
|
-
remote_set_complete:
|
|
10369
|
-
truncated:
|
|
10379
|
+
local_enumeration_complete: z8.boolean(),
|
|
10380
|
+
remote_set_complete: z8.boolean(),
|
|
10381
|
+
truncated: z8.boolean()
|
|
10370
10382
|
}).strict().transform((result) => ({ ...result, cached: true })).parse(JSON.parse(value));
|
|
10371
10383
|
}
|
|
10372
10384
|
function bindSourceRealm(database, snapshot) {
|
|
@@ -11994,8 +12006,8 @@ function invokeCapabilitySync(request, options = {}) {
|
|
|
11994
12006
|
return parsed.live;
|
|
11995
12007
|
}
|
|
11996
12008
|
|
|
11997
|
-
// node_modules/@hraness/wrench/dist/index-
|
|
11998
|
-
var WRENCH_VERSION = "0.16.
|
|
12009
|
+
// node_modules/@hraness/wrench/dist/index-j1f3cp88.js
|
|
12010
|
+
var WRENCH_VERSION = "0.16.8";
|
|
11999
12011
|
|
|
12000
12012
|
// node_modules/@hraness/wrench/dist/beeper-client.js
|
|
12001
12013
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
@@ -16980,8 +16992,8 @@ function projectBeeperContactInteractions(summary, coordinates) {
|
|
|
16980
16992
|
// src/local/providers/beeper-compatibility.ts
|
|
16981
16993
|
var BEEPER_WRENCH_COMPATIBILITY = Object.freeze({
|
|
16982
16994
|
wrench: Object.freeze({
|
|
16983
|
-
version: "0.16.
|
|
16984
|
-
commit: "
|
|
16995
|
+
version: "0.16.8",
|
|
16996
|
+
commit: "b0cf2ecbc1113fcc8ef673a824be475c3d7bbb46"
|
|
16985
16997
|
}),
|
|
16986
16998
|
adapter: Object.freeze({
|
|
16987
16999
|
id: "beeper-local",
|
|
@@ -17018,6 +17030,22 @@ var BEEPER_WRENCH_COMPATIBILITY = Object.freeze({
|
|
|
17018
17030
|
commit: "b9c1714410139c2139b597338cd002d785653e85"
|
|
17019
17031
|
})
|
|
17020
17032
|
});
|
|
17033
|
+
var PEOPLEBLADE_010_WRENCH_0150_BEEPER_SOURCE_BINDING_METADATA = Object.freeze({
|
|
17034
|
+
transport: "local-cli",
|
|
17035
|
+
wrenchVersion: "0.15.0",
|
|
17036
|
+
wrenchCommit: "41b16fcbf9ed0e8d8a332aa380b7187642aac2e3",
|
|
17037
|
+
adapterId: "beeper-local",
|
|
17038
|
+
adapterVersion: "2.0.0",
|
|
17039
|
+
adapterSha256: "e0e1adb52a667af64289db74bad0016753fff2e9fc784ed3cdaae457eb1f19c6",
|
|
17040
|
+
cliId: "beeper-cli",
|
|
17041
|
+
cliVersion: "0.6.2",
|
|
17042
|
+
cliCommit: "a416af06023449a87312dc11e54643fd9dc94b8c",
|
|
17043
|
+
contracts: Object.freeze({
|
|
17044
|
+
contactsList: "eac1536860bc19ff8b9c59abe44c33414ee559e9c550be9d1185ed8375e27d7f",
|
|
17045
|
+
contactsSearch: "bc88cfbca7b8bd9cf5f297cb7d3c922d70dedcaf6d5000e20ed97f9e7b864482",
|
|
17046
|
+
messagingSearch: "27196d8d2cc5eeb855d61d8e27134e81dc56b64f20ea8033d4406c959dffd6f6"
|
|
17047
|
+
})
|
|
17048
|
+
});
|
|
17021
17049
|
var PREVIOUS_BEEPER_SOURCE_BINDING_METADATA = Object.freeze({
|
|
17022
17050
|
transport: "local-cli",
|
|
17023
17051
|
wrenchVersion: "0.16.6",
|
|
@@ -17066,6 +17094,22 @@ var LEGACY_WRENCH_0167_SEARCH_V1_SOURCE_BINDING_METADATA = Object.freeze({
|
|
|
17066
17094
|
messagingSearch: "27b45f4fd370bddaf94c991bf65393556f246fc466c17a360689e467539e41c2"
|
|
17067
17095
|
})
|
|
17068
17096
|
});
|
|
17097
|
+
var PREVIOUS_WRENCH_0167_BEEPER_SOURCE_BINDING_METADATA = Object.freeze({
|
|
17098
|
+
transport: "local-cli",
|
|
17099
|
+
wrenchVersion: "0.16.7",
|
|
17100
|
+
wrenchCommit: "a2b321081335ac28e5df0ccbb67ebea0424d49f5",
|
|
17101
|
+
adapterId: "beeper-local",
|
|
17102
|
+
adapterVersion: "2.4.0",
|
|
17103
|
+
adapterSha256: "2714af7e821b799c1d0b57106e8e193cb9787e5a6da37e1269f4aae0710a4ddc",
|
|
17104
|
+
cliId: "beeper-cli",
|
|
17105
|
+
cliVersion: "0.6.2",
|
|
17106
|
+
cliCommit: "a416af06023449a87312dc11e54643fd9dc94b8c",
|
|
17107
|
+
contracts: Object.freeze({
|
|
17108
|
+
contactsList: "8048565547c2a09078528d0a35f7a0c3a2e8850b17b075dc572e8b59115fcb57",
|
|
17109
|
+
contactsSearch: "e57cdcc9012ed5fb8f956e16a2368e95adf0a6b8bb404f903e64df85061b1ca1",
|
|
17110
|
+
messagingSearch: "2fc54d139a54d19c31a82237e4b417994e12679db3da5fd71ec9265e3622b0bf"
|
|
17111
|
+
})
|
|
17112
|
+
});
|
|
17069
17113
|
var LEGACY_BEEPER_WRENCH_COMPATIBILITY = Object.freeze({
|
|
17070
17114
|
wrenchVersion: "0.14.0",
|
|
17071
17115
|
adapterId: "beeper-local",
|
|
@@ -17523,6 +17567,9 @@ function classifyReviewedBeeperPredecessor(value, currentMetadata) {
|
|
|
17523
17567
|
if (isLegacyBindingMetadata(value))
|
|
17524
17568
|
return "wrench-0.14-beeper-1.1";
|
|
17525
17569
|
const encoded = canonicalJson(value);
|
|
17570
|
+
if (encoded === canonicalJson(PEOPLEBLADE_010_WRENCH_0150_BEEPER_SOURCE_BINDING_METADATA)) {
|
|
17571
|
+
return "peopleblade-0.1.0-wrench-0.15-beeper-2.0";
|
|
17572
|
+
}
|
|
17526
17573
|
if (encoded === canonicalJson(LEGACY_MISLABELED_BEEPER_SOURCE_BINDING_METADATA)) {
|
|
17527
17574
|
return "peopleblade-pre-0.1.1-mislabeled-beeper-search";
|
|
17528
17575
|
}
|
|
@@ -17532,8 +17579,11 @@ function classifyReviewedBeeperPredecessor(value, currentMetadata) {
|
|
|
17532
17579
|
if (encoded === canonicalJson(LEGACY_WRENCH_0167_SEARCH_V1_SOURCE_BINDING_METADATA)) {
|
|
17533
17580
|
return "wrench-0.16.7-beeper-2.4-search-v1";
|
|
17534
17581
|
}
|
|
17535
|
-
if (encoded ===
|
|
17582
|
+
if (encoded === canonicalJson(PREVIOUS_WRENCH_0167_BEEPER_SOURCE_BINDING_METADATA)) {
|
|
17536
17583
|
return "wrench-0.16.7-beeper-2.4";
|
|
17584
|
+
}
|
|
17585
|
+
if (encoded === currentMetadata)
|
|
17586
|
+
return "wrench-0.16.8-beeper-2.4";
|
|
17537
17587
|
return null;
|
|
17538
17588
|
}
|
|
17539
17589
|
function assertStoredRealmInventory(database, sourceBindingId, accounts, storedSha256) {
|
|
@@ -17596,10 +17646,9 @@ function rebindBeeperSource(database, options = {}) {
|
|
|
17596
17646
|
}
|
|
17597
17647
|
const verifiedInventorySha256 = assertStoredRealmInventory(database, current.id, inventory.accounts, current.completeRealmInventorySha256);
|
|
17598
17648
|
const currentMetadata = canonicalJson(beeperSourceBindingMetadata());
|
|
17599
|
-
|
|
17600
|
-
|
|
17601
|
-
|
|
17602
|
-
}
|
|
17649
|
+
const sameIdentity = current.subjectSha256 === next.subjectSha256 && current.authSha256 === next.authSha256;
|
|
17650
|
+
const storedMetadata = canonicalJson(current.metadata);
|
|
17651
|
+
if (sameIdentity && storedMetadata === currentMetadata) {
|
|
17603
17652
|
return {
|
|
17604
17653
|
transitioned: false,
|
|
17605
17654
|
source_binding_id: current.id,
|
|
@@ -17613,6 +17662,10 @@ function rebindBeeperSource(database, options = {}) {
|
|
|
17613
17662
|
if (predecessor === null) {
|
|
17614
17663
|
throw new Error("Beeper rebind source coordinates are not a reviewed predecessor.");
|
|
17615
17664
|
}
|
|
17665
|
+
const metadataOnly = sameIdentity && (predecessor === "peopleblade-0.1.0-wrench-0.15-beeper-2.0" || predecessor === "wrench-0.16.7-beeper-2.4");
|
|
17666
|
+
if (sameIdentity && !metadataOnly) {
|
|
17667
|
+
throw new Error("Beeper metadata-only rebind requires an exact reviewed same-identity predecessor.");
|
|
17668
|
+
}
|
|
17616
17669
|
if (predecessor === "wrench-0.14-beeper-1.1") {
|
|
17617
17670
|
assertLegacyBeeperReceipt(database, current);
|
|
17618
17671
|
const derivedLegacySubjectSha256 = sha256(legacyBeeperAccountSubject(inventory.accounts));
|
|
@@ -17622,7 +17675,7 @@ function rebindBeeperSource(database, options = {}) {
|
|
|
17622
17675
|
}
|
|
17623
17676
|
const evidence = {
|
|
17624
17677
|
schemaVersion: 1,
|
|
17625
|
-
kind: "beeper-source-binding-rebind",
|
|
17678
|
+
kind: metadataOnly ? "beeper-source-binding-metadata-rebind" : "beeper-source-binding-rebind",
|
|
17626
17679
|
authority: PROVIDER4,
|
|
17627
17680
|
authId,
|
|
17628
17681
|
sourceBindingId: current.id,
|
|
@@ -17653,25 +17706,36 @@ function rebindBeeperSource(database, options = {}) {
|
|
|
17653
17706
|
finishedAt: inventory.execution.finishedAt
|
|
17654
17707
|
}
|
|
17655
17708
|
};
|
|
17656
|
-
const
|
|
17709
|
+
const expected = {
|
|
17710
|
+
subjectSha256: current.subjectSha256,
|
|
17711
|
+
authSha256: current.authSha256,
|
|
17712
|
+
incarnationId: current.incarnationId,
|
|
17713
|
+
lastSeenAt: current.lastSeenAt,
|
|
17714
|
+
metadataJson: storedMetadata,
|
|
17715
|
+
completeRealmInventoryObservedAt: current.completeRealmInventoryObservedAt,
|
|
17716
|
+
completeRealmInventorySha256: current.completeRealmInventorySha256
|
|
17717
|
+
};
|
|
17718
|
+
const verifyLocked = () => {
|
|
17719
|
+
assertStoredRealmInventory(database, current.id, inventory.accounts, current.completeRealmInventorySha256);
|
|
17720
|
+
};
|
|
17721
|
+
const result = metadataOnly ? transitionSourceBindingMetadata(database, {
|
|
17657
17722
|
authority: PROVIDER4,
|
|
17658
17723
|
authId,
|
|
17659
|
-
expected
|
|
17660
|
-
|
|
17661
|
-
|
|
17662
|
-
|
|
17663
|
-
|
|
17664
|
-
|
|
17665
|
-
|
|
17666
|
-
|
|
17667
|
-
|
|
17724
|
+
expected,
|
|
17725
|
+
nextMetadata: next.metadata,
|
|
17726
|
+
observedAt: inventory.execution.finishedAt,
|
|
17727
|
+
completeRealmInventorySha256: verifiedInventorySha256,
|
|
17728
|
+
evidence,
|
|
17729
|
+
verifyLocked
|
|
17730
|
+
}) : transitionSourceBinding(database, {
|
|
17731
|
+
authority: PROVIDER4,
|
|
17732
|
+
authId,
|
|
17733
|
+
expected,
|
|
17668
17734
|
next,
|
|
17669
17735
|
observedAt: inventory.execution.finishedAt,
|
|
17670
17736
|
completeRealmInventorySha256: verifiedInventorySha256,
|
|
17671
17737
|
evidence,
|
|
17672
|
-
verifyLocked
|
|
17673
|
-
assertStoredRealmInventory(database, current.id, inventory.accounts, current.completeRealmInventorySha256);
|
|
17674
|
-
}
|
|
17738
|
+
verifyLocked
|
|
17675
17739
|
});
|
|
17676
17740
|
return {
|
|
17677
17741
|
transitioned: true,
|
|
@@ -17694,9 +17758,9 @@ function syncBeeperContacts(database, options = {}) {
|
|
|
17694
17758
|
}, options.invoke);
|
|
17695
17759
|
const inventoryInput = { limit: 1 };
|
|
17696
17760
|
const inventory = parseBeeperContactPage(invoke(inventoryInput), inventoryInput, authId);
|
|
17697
|
-
ledgerBeeperContactRead(database, `beeper:binding:${sha256(inventory.accountSubject)}`, inventory);
|
|
17698
17761
|
const inventoryBinding = sourceBinding(inventory, authId);
|
|
17699
17762
|
assertSourceBindingCurrent(database, PROVIDER4, inventoryBinding);
|
|
17763
|
+
ledgerBeeperContactRead(database, `beeper:binding:${sha256(inventory.accountSubject)}`, inventory);
|
|
17700
17764
|
const inventorySha256 = accountInventorySha256(inventory.accounts);
|
|
17701
17765
|
const orderedAccounts = [...inventory.accounts].sort((left, right) => {
|
|
17702
17766
|
const serviceOrder = normalizeService(left).localeCompare(normalizeService(right));
|
|
@@ -18362,6 +18426,12 @@ function backfillBeeperSearch(database, options) {
|
|
|
18362
18426
|
const invoke = (operation, input) => callPeopleBladeWrench({ adapterId: ADAPTER_ID2, operationId: operation, authId, input }, options.invoke);
|
|
18363
18427
|
const inventoryInput = { limit: 1 };
|
|
18364
18428
|
const inventory = parseBeeperContactPage(invoke("contacts.list", inventoryInput), inventoryInput, authId);
|
|
18429
|
+
assertSourceBindingCurrent(database, PROVIDER5, {
|
|
18430
|
+
authId,
|
|
18431
|
+
authSha256: inventory.execution.authSha256,
|
|
18432
|
+
subjectSha256: sha256(inventory.accountSubject),
|
|
18433
|
+
metadata: beeperSourceBindingMetadata()
|
|
18434
|
+
});
|
|
18365
18435
|
let executionReceiptsRecorded = 0;
|
|
18366
18436
|
if (!ledgerPeopleBladeWrenchInvocation(database, {
|
|
18367
18437
|
provider: PROVIDER5,
|
|
@@ -18372,12 +18442,6 @@ function backfillBeeperSearch(database, options) {
|
|
|
18372
18442
|
metadata: { subjectSha256: sha256(inventory.accountSubject) }
|
|
18373
18443
|
}).replayed)
|
|
18374
18444
|
executionReceiptsRecorded += 1;
|
|
18375
|
-
assertSourceBindingCurrent(database, PROVIDER5, {
|
|
18376
|
-
authId,
|
|
18377
|
-
authSha256: inventory.execution.authSha256,
|
|
18378
|
-
subjectSha256: sha256(inventory.accountSubject),
|
|
18379
|
-
metadata: beeperSourceBindingMetadata()
|
|
18380
|
-
});
|
|
18381
18445
|
const accounts = [...inventory.accounts].filter((account) => requestedServices === null || requestedServices.has(normalizeService2(account))).sort((left, right) => normalizeService2(left).localeCompare(normalizeService2(right)) || left.accountId.localeCompare(right.accountId));
|
|
18382
18446
|
if (requestedServices !== null) {
|
|
18383
18447
|
const found = new Set(accounts.map(normalizeService2));
|
|
@@ -23924,7 +23988,7 @@ function syncWhatsAppRelationships(database, options = {}) {
|
|
|
23924
23988
|
}
|
|
23925
23989
|
|
|
23926
23990
|
// src/cli/version.ts
|
|
23927
|
-
var peoplebladeVersion = "0.1.
|
|
23991
|
+
var peoplebladeVersion = "0.1.2";
|
|
23928
23992
|
|
|
23929
23993
|
// src/cli/main.ts
|
|
23930
23994
|
var usage = `PeopleBlade \u2014 local-first contact intelligence
|
|
@@ -24500,7 +24564,7 @@ ${verification}`) });
|
|
|
24500
24564
|
if (options.length)
|
|
24501
24565
|
fail3(`Unknown argument: ${options[0]}`);
|
|
24502
24566
|
if (!confirm)
|
|
24503
|
-
fail3("beeper rebind requires --confirm after reviewing the Wrench
|
|
24567
|
+
fail3("beeper rebind requires --confirm after reviewing the current Wrench binding, release, and connected-account inventory.");
|
|
24504
24568
|
console.error("Beeper binding \xB7 verifying the complete connected-account inventory before an append-only transition");
|
|
24505
24569
|
print(rebindBeeperSource(database, { ...authId3 === undefined ? {} : { authId: authId3 } }), asJson);
|
|
24506
24570
|
return;
|