@indigoai-us/hq-cli 5.345.143 → 5.345.145
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 +90 -0
- package/dist/command-catalog.generated.d.ts +286 -6
- package/dist/command-catalog.generated.js +351 -6
- package/dist/command-registration-plan.d.ts +6 -0
- package/dist/command-registration-plan.js +1 -0
- package/dist/commands/agent-enroll.d.ts +1 -0
- package/dist/commands/agent-enroll.js +7 -0
- package/dist/commands/agents.d.ts +25 -3
- package/dist/commands/agents.js +57 -4
- package/dist/commands/api-keys.js +66 -8
- package/dist/commands/billing-sponsor.d.ts +4 -0
- package/dist/commands/billing-sponsor.js +48 -5
- package/dist/commands/billing-usage.d.ts +59 -0
- package/dist/commands/billing-usage.js +162 -0
- package/dist/commands/billing.d.ts +9 -0
- package/dist/commands/billing.js +29 -2
- package/dist/commands/core-checkpoint-native.d.ts +30 -0
- package/dist/commands/core-checkpoint-native.js +167 -10
- package/dist/commands/core-job-notify-native.js +53 -3
- package/dist/commands/core-jobs-native.d.ts +8 -0
- package/dist/commands/core-jobs-native.js +34 -2
- package/dist/commands/core-policy.js +76 -13
- package/dist/commands/library-add.d.ts +120 -0
- package/dist/commands/library-add.js +434 -0
- package/dist/commands/library-caption.d.ts +112 -0
- package/dist/commands/library-caption.js +393 -0
- package/dist/commands/library-link.d.ts +32 -0
- package/dist/commands/library-link.js +95 -0
- package/dist/commands/library.d.ts +72 -0
- package/dist/commands/library.js +527 -0
- package/dist/commands/meetings.d.ts +8 -0
- package/dist/commands/meetings.js +25 -2
- package/dist/commands/members.d.ts +20 -0
- package/dist/commands/members.js +51 -2
- package/dist/commands/storage-offload.d.ts +16 -2
- package/dist/commands/storage-offload.js +55 -4
- package/dist/commands/storage.d.ts +8 -1
- package/dist/commands/storage.js +6 -2
- package/dist/commands/whoami.js +9 -0
- package/dist/hq-cloud-sync-runner/bin/sync-runner.js +2410 -2063
- package/dist/hq-cloud-sync-runner/package.json +1 -1
- package/dist/lib/billing/plan-lock.d.ts +15 -1
- package/dist/lib/billing/plan-lock.js +45 -5
- package/dist/lib/billing/usage-card.d.ts +82 -0
- package/dist/lib/billing/usage-card.js +198 -0
- package/dist/lib/billing/usage-cost.d.ts +214 -0
- package/dist/lib/billing/usage-cost.js +440 -0
- package/dist/lib/billing/usage-only.d.ts +87 -0
- package/dist/lib/billing/usage-only.js +262 -0
- package/dist/lib/billing/usage-rate-card.d.ts +51 -0
- package/dist/lib/billing/usage-rate-card.js +62 -0
- package/dist/lib/flag-registry-worker-source.generated.d.ts +1 -1
- package/dist/lib/flag-registry-worker-source.generated.js +1 -1
- package/dist/lib/plan-limit-nag.d.ts +4 -6
- package/dist/lib/plan-limit-nag.js +19 -1
- package/dist/lib/provider-launcher.d.ts +22 -0
- package/dist/lib/provider-launcher.js +65 -0
- package/dist/lib/search-index/index.d.ts +2 -0
- package/dist/lib/search-index/index.js +34 -0
- package/dist/lib/search-index/max-doc-bytes.d.ts +2 -1
- package/dist/lib/search-index/max-doc-bytes.js +2 -1
- package/dist/main.d.ts +9 -0
- package/dist/main.js +20 -3
- package/dist/utils/billing-gate.d.ts +19 -4
- package/dist/utils/billing-gate.js +25 -4
- package/dist/utils/plan-gate-error.d.ts +10 -0
- package/dist/utils/plan-gate-error.js +54 -0
- package/dist/utils/vault-api.js +4 -1
- package/package.json +2 -2
package/dist/commands/members.js
CHANGED
|
@@ -237,6 +237,30 @@ export async function listPendingInvites(token, companyUid) {
|
|
|
237
237
|
const data = (await res.json());
|
|
238
238
|
return data?.pending ?? data?.invites ?? [];
|
|
239
239
|
}
|
|
240
|
+
/** JSON row for `hq members list --json`. `person_id` is the prs_/agt_ id grants use. */
|
|
241
|
+
export function activeMemberJson(m) {
|
|
242
|
+
return {
|
|
243
|
+
person_id: m.personUid,
|
|
244
|
+
email: m.personEmail ?? null,
|
|
245
|
+
name: m.personName ?? null,
|
|
246
|
+
slug: m.personSlug ?? null,
|
|
247
|
+
role: m.role,
|
|
248
|
+
status: m.status,
|
|
249
|
+
membership_key: m.membershipKey,
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
/** JSON row for `hq members list --pending --json`. */
|
|
253
|
+
export function pendingInviteJson(inv) {
|
|
254
|
+
return {
|
|
255
|
+
person_id: inv.personUid ?? null,
|
|
256
|
+
email: inv.inviteeEmail ?? null,
|
|
257
|
+
role: inv.role,
|
|
258
|
+
status: inv.status,
|
|
259
|
+
invited_by: inv.invitedBy,
|
|
260
|
+
invited_at: inv.invitedAt,
|
|
261
|
+
membership_key: inv.membershipKey,
|
|
262
|
+
};
|
|
263
|
+
}
|
|
240
264
|
export async function listActiveMembers(token, companyUid) {
|
|
241
265
|
const res = await vaultApiFetch({
|
|
242
266
|
token,
|
|
@@ -750,6 +774,8 @@ export function registerMembersCommand(program) {
|
|
|
750
774
|
.command("list")
|
|
751
775
|
.description("List the company's active members (use --pending for pending invites)")
|
|
752
776
|
.option("--pending", "List pending invites instead of active members")
|
|
777
|
+
.option("--ids", "Add a PERSON_ID column (the prs_ id used in grants and membership keys)")
|
|
778
|
+
.option("--json", "Print machine-readable JSON, including each person id")
|
|
753
779
|
.action(async (opts) => {
|
|
754
780
|
try {
|
|
755
781
|
const token = (await resolveVaultCredential()).token;
|
|
@@ -758,6 +784,13 @@ export function registerMembersCommand(program) {
|
|
|
758
784
|
if (opts.pending) {
|
|
759
785
|
// --pending: preserve the original pending-invites view verbatim.
|
|
760
786
|
const invites = await listPendingInvites(token, companyUid);
|
|
787
|
+
if (opts.json) {
|
|
788
|
+
console.log(JSON.stringify({
|
|
789
|
+
company_uid: companyUid,
|
|
790
|
+
pending: invites.map(pendingInviteJson),
|
|
791
|
+
}, null, 2));
|
|
792
|
+
return;
|
|
793
|
+
}
|
|
761
794
|
if (invites.length === 0) {
|
|
762
795
|
console.log(chalk.gray("No pending invites for this company."));
|
|
763
796
|
return;
|
|
@@ -788,17 +821,33 @@ export function registerMembersCommand(program) {
|
|
|
788
821
|
// Default: list ACTIVE members so their emails drop straight into
|
|
789
822
|
// `hq secrets share <path> --with <email>`.
|
|
790
823
|
const activeMembers = await listActiveMembers(token, companyUid);
|
|
824
|
+
if (opts.json) {
|
|
825
|
+
console.log(JSON.stringify({
|
|
826
|
+
company_uid: companyUid,
|
|
827
|
+
members: activeMembers.map(activeMemberJson),
|
|
828
|
+
}, null, 2));
|
|
829
|
+
return;
|
|
830
|
+
}
|
|
791
831
|
if (activeMembers.length === 0) {
|
|
792
832
|
console.log(chalk.gray("No active members found for this company."));
|
|
793
833
|
return;
|
|
794
834
|
}
|
|
795
835
|
const emailW = Math.max(5, ...activeMembers.map((m) => (m.personEmail ?? m.personUid).length));
|
|
796
836
|
const roleW = Math.max(4, ...activeMembers.map((m) => m.role.length));
|
|
797
|
-
|
|
837
|
+
const idW = Math.max(9, ...activeMembers.map((m) => m.personUid.length));
|
|
838
|
+
const header = ["EMAIL".padEnd(emailW), "ROLE".padEnd(roleW)];
|
|
839
|
+
if (opts.ids)
|
|
840
|
+
header.push("PERSON_ID".padEnd(idW));
|
|
841
|
+
header.push("NAME");
|
|
842
|
+
console.log(chalk.bold(header.join(" ")));
|
|
798
843
|
for (const m of activeMembers) {
|
|
799
844
|
const email = m.personEmail ?? m.personUid;
|
|
800
845
|
const name = m.personName ?? m.personSlug ?? "";
|
|
801
|
-
|
|
846
|
+
const row = [email.padEnd(emailW), m.role.padEnd(roleW)];
|
|
847
|
+
if (opts.ids)
|
|
848
|
+
row.push(m.personUid.padEnd(idW));
|
|
849
|
+
row.push(name);
|
|
850
|
+
console.log(row.join(" "));
|
|
802
851
|
}
|
|
803
852
|
}
|
|
804
853
|
catch (err) {
|
|
@@ -96,19 +96,33 @@ export interface Pointer {
|
|
|
96
96
|
/** Set by sync when a teammate deleted the remote file. */
|
|
97
97
|
orphaned?: boolean;
|
|
98
98
|
}
|
|
99
|
-
|
|
99
|
+
/** Company-vault key for library bytes: content-addressed by sha256, relative to the company bucket. */
|
|
100
|
+
export declare function companyOffloadKey(sha256: string): string;
|
|
101
|
+
/**
|
|
102
|
+
* Render a placeholder. `assetBlock` is the fenced `hq-asset` metadata block
|
|
103
|
+
* (from hq-cloud's `formatCloudAssetBlock`) that `hq library add` appends after
|
|
104
|
+
* the footer so the placeholder is a searchable library asset.
|
|
105
|
+
*/
|
|
106
|
+
export declare function renderPointer(p: Pointer, assetBlock?: string): string;
|
|
100
107
|
/** ETags compare without the surrounding quotes S3 returns. */
|
|
101
108
|
export declare function normalizeEtag(etag: string | undefined): string;
|
|
102
109
|
/**
|
|
103
110
|
* Parse pointer text. Returns null for anything that is not a valid v1 pointer.
|
|
104
111
|
*
|
|
105
|
-
*
|
|
112
|
+
* Three shapes are valid:
|
|
106
113
|
* - an offload copy: `vault: personal`, key = offloadKey(git-blob), with a
|
|
107
114
|
* git blob id to verify against;
|
|
115
|
+
* - a library copy: `vault: company`, key = companyOffloadKey(sha256), with
|
|
116
|
+
* the sha256 to verify against (written by `hq library add`);
|
|
108
117
|
* - a vault object recorded by sync: either vault, a non-offload key, and a
|
|
109
118
|
* `remote-etag` to verify against (sha256 may be `unknown`).
|
|
110
119
|
*/
|
|
111
120
|
export declare function parsePointer(text: string): Pointer | null;
|
|
121
|
+
/**
|
|
122
|
+
* Library copy in a company vault: content-addressed under
|
|
123
|
+
* `.hq-offload/blobs/<sha256>`, verified by that sha256 (no git blob, no ETag).
|
|
124
|
+
*/
|
|
125
|
+
export declare function isCompanyOffloadCopy(p: Pointer): boolean;
|
|
112
126
|
export interface FileDigest {
|
|
113
127
|
size: number;
|
|
114
128
|
sha256: string;
|
|
@@ -119,7 +119,16 @@ export function resolveMinBytes(flag, env) {
|
|
|
119
119
|
return parseSize(fromEnv);
|
|
120
120
|
return DEFAULT_MIN_BYTES;
|
|
121
121
|
}
|
|
122
|
-
|
|
122
|
+
/** Company-vault key for library bytes: content-addressed by sha256, relative to the company bucket. */
|
|
123
|
+
export function companyOffloadKey(sha256) {
|
|
124
|
+
return `${OFFLOAD_PREFIX}${sha256}`;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Render a placeholder. `assetBlock` is the fenced `hq-asset` metadata block
|
|
128
|
+
* (from hq-cloud's `formatCloudAssetBlock`) that `hq library add` appends after
|
|
129
|
+
* the footer so the placeholder is a searchable library asset.
|
|
130
|
+
*/
|
|
131
|
+
export function renderPointer(p, assetBlock) {
|
|
123
132
|
const lines = [POINTER_HEADER, `path: ${p.path}`, `size: ${p.size}`, `sha256: ${p.sha256 ?? "unknown"}`];
|
|
124
133
|
if (p.gitBlob)
|
|
125
134
|
lines.push(`git-blob: ${p.gitBlob}`);
|
|
@@ -131,6 +140,8 @@ export function renderPointer(p) {
|
|
|
131
140
|
if (p.orphaned)
|
|
132
141
|
lines.push("orphaned: true");
|
|
133
142
|
lines.push(`retrieve: hq storage fetch "${p.path}"`, POINTER_FOOTER, "");
|
|
143
|
+
if (assetBlock)
|
|
144
|
+
lines.push(assetBlock.endsWith("\n") ? assetBlock : `${assetBlock}\n`);
|
|
134
145
|
return lines.join("\n");
|
|
135
146
|
}
|
|
136
147
|
/** ETags compare without the surrounding quotes S3 returns. */
|
|
@@ -142,9 +153,11 @@ const HEX64 = /^[0-9a-f]{64}$/;
|
|
|
142
153
|
/**
|
|
143
154
|
* Parse pointer text. Returns null for anything that is not a valid v1 pointer.
|
|
144
155
|
*
|
|
145
|
-
*
|
|
156
|
+
* Three shapes are valid:
|
|
146
157
|
* - an offload copy: `vault: personal`, key = offloadKey(git-blob), with a
|
|
147
158
|
* git blob id to verify against;
|
|
159
|
+
* - a library copy: `vault: company`, key = companyOffloadKey(sha256), with
|
|
160
|
+
* the sha256 to verify against (written by `hq library add`);
|
|
148
161
|
* - a vault object recorded by sync: either vault, a non-offload key, and a
|
|
149
162
|
* `remote-etag` to verify against (sha256 may be `unknown`).
|
|
150
163
|
*/
|
|
@@ -191,10 +204,22 @@ export function parsePointer(text) {
|
|
|
191
204
|
const isOffloadCopy = p.gitBlob !== undefined && p.key === offloadKey(p.gitBlob);
|
|
192
205
|
if (isOffloadCopy)
|
|
193
206
|
return p.vault === "personal" ? p : null;
|
|
207
|
+
if (isCompanyOffloadCopy(p))
|
|
208
|
+
return p;
|
|
194
209
|
if (p.key.startsWith(OFFLOAD_PREFIX) || !p.remoteEtag)
|
|
195
210
|
return null;
|
|
196
211
|
return p;
|
|
197
212
|
}
|
|
213
|
+
/**
|
|
214
|
+
* Library copy in a company vault: content-addressed under
|
|
215
|
+
* `.hq-offload/blobs/<sha256>`, verified by that sha256 (no git blob, no ETag).
|
|
216
|
+
*/
|
|
217
|
+
export function isCompanyOffloadCopy(p) {
|
|
218
|
+
return (p.vault === "company" &&
|
|
219
|
+
p.sha256 !== null &&
|
|
220
|
+
p.gitBlob === undefined &&
|
|
221
|
+
p.key === companyOffloadKey(p.sha256));
|
|
222
|
+
}
|
|
198
223
|
/** sha256 and git blob id (sha1 of "blob <size>\0" + bytes) in one pass. */
|
|
199
224
|
export async function digestFile(file) {
|
|
200
225
|
const size = (await fs.promises.stat(file)).size;
|
|
@@ -1320,7 +1345,7 @@ async function downloadVerified(download, key, dest, expect) {
|
|
|
1320
1345
|
/** Company slug for a company-vault placeholder, checked against its key. */
|
|
1321
1346
|
export function companyForPointer(pointer) {
|
|
1322
1347
|
const m = /^companies\/([^/]+)\/(.+)$/.exec(pointer.path);
|
|
1323
|
-
if (!m || m[2] !== pointer.key) {
|
|
1348
|
+
if (!m || (!isCompanyOffloadCopy(pointer) && m[2] !== pointer.key)) {
|
|
1324
1349
|
throw new Error(`Placeholder for '${pointer.path}' names company vault key '${pointer.key}', which does not match its location. Nothing was changed.`);
|
|
1325
1350
|
}
|
|
1326
1351
|
return m[1];
|
|
@@ -1377,7 +1402,10 @@ async function fetchPlaceholder(arg, deps, opts) {
|
|
|
1377
1402
|
throw new Error(`'${pointer.path}' already exists locally. Move it aside first.`);
|
|
1378
1403
|
}
|
|
1379
1404
|
let digest;
|
|
1380
|
-
if (pointer
|
|
1405
|
+
if (isCompanyOffloadCopy(pointer)) {
|
|
1406
|
+
digest = await fetchCompanyOffload(pointer, target, deps);
|
|
1407
|
+
}
|
|
1408
|
+
else if (pointer.remoteEtag === undefined) {
|
|
1381
1409
|
// Offload copy in the personal vault, verified by git blob id and sha256.
|
|
1382
1410
|
const store = await deps.openPersonal();
|
|
1383
1411
|
digest = await downloadVerified((partial) => store.download(pointer.key, partial), pointer.key, target, {
|
|
@@ -1392,6 +1420,29 @@ async function fetchPlaceholder(arg, deps, opts) {
|
|
|
1392
1420
|
await fs.promises.rm(placeholder, { force: true });
|
|
1393
1421
|
return { path: pointer.path, bytes: digest.size, sha256: digest.sha256 };
|
|
1394
1422
|
}
|
|
1423
|
+
/**
|
|
1424
|
+
* Library copy (`hq library add`): download `.hq-offload/blobs/<sha256>` from
|
|
1425
|
+
* the company vault and verify the bytes against that sha256. The object is
|
|
1426
|
+
* content-addressed, so the current ETag is pinned only to keep one download
|
|
1427
|
+
* consistent. Opened only for a company the caller is an active member of.
|
|
1428
|
+
*/
|
|
1429
|
+
async function fetchCompanyOffload(pointer, target, deps) {
|
|
1430
|
+
if (!deps.openVaultObjects)
|
|
1431
|
+
throw new Error("This HQ build cannot fetch files from a company library.");
|
|
1432
|
+
const slug = companyForPointer(pointer);
|
|
1433
|
+
const active = deps.activeCompanySlugs ? await deps.activeCompanySlugs() : [];
|
|
1434
|
+
if (!active.includes(slug)) {
|
|
1435
|
+
throw new Error(`You are not an active member of '${slug}', so HQ cannot download this file for you.`);
|
|
1436
|
+
}
|
|
1437
|
+
const store = await deps.openVaultObjects({ vault: "company", slug });
|
|
1438
|
+
const head = await store.head(pointer.key);
|
|
1439
|
+
if (!head)
|
|
1440
|
+
throw new Error(`This file is no longer in the cloud (${pointer.key}).`);
|
|
1441
|
+
return downloadVerified((partial) => store.download(pointer.key, partial, head.etag), pointer.key, target, {
|
|
1442
|
+
sha256: pointer.sha256,
|
|
1443
|
+
size: pointer.size,
|
|
1444
|
+
});
|
|
1445
|
+
}
|
|
1395
1446
|
/**
|
|
1396
1447
|
* Placeholder that sync rewrote to a vault object: download pinned to the
|
|
1397
1448
|
* recorded ETag and verify size (and sha256 when known). A company vault is
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
import { Command } from "commander";
|
|
37
37
|
import { type ReclaimReport } from "./storage-core.js";
|
|
38
38
|
import { S3Client, ListObjectVersionsCommand, DeleteObjectsCommand, type ListObjectVersionsCommandOutput, type DeleteObjectsCommandOutput } from "@aws-sdk/client-s3";
|
|
39
|
-
import { type OffloadResult, type OffloadStatus } from "./storage-offload.js";
|
|
39
|
+
import { type OffloadDeps, type OffloadResult, type OffloadStatus } from "./storage-offload.js";
|
|
40
40
|
export type TrancheId = "7d" | "30d" | "90d" | "365d" | "older";
|
|
41
41
|
export declare const TRANCHES: readonly {
|
|
42
42
|
id: TrancheId;
|
|
@@ -265,6 +265,11 @@ export declare const NEEDS_YES = "No terminal to confirm in. Re-run with --yes t
|
|
|
265
265
|
export declare function confirmOnTty(message: string, input?: NodeJS.ReadableStream & {
|
|
266
266
|
isTTY?: boolean;
|
|
267
267
|
}, output?: NodeJS.WritableStream): Promise<boolean>;
|
|
268
|
+
/**
|
|
269
|
+
* Deps for offload/fetch. The only store is the caller's personal vault,
|
|
270
|
+
* resolved from their canonical person entity and vended with `/sts/vend-self`.
|
|
271
|
+
*/
|
|
272
|
+
export declare function buildOffloadDeps(): Promise<OffloadDeps>;
|
|
268
273
|
/**
|
|
269
274
|
* An S3 client for one vault whose credentials are re-vended before they
|
|
270
275
|
* expire, plus `revend`, which vends now and returns a client on the new
|
|
@@ -296,5 +301,7 @@ export declare function refreshingVendedCredentials(vend: () => Promise<VendedCr
|
|
|
296
301
|
sessionToken: string;
|
|
297
302
|
expiration?: Date;
|
|
298
303
|
}>;
|
|
304
|
+
/** Production deps. Exported for `hq billing usage`, which reads cloud status only. */
|
|
305
|
+
export declare function buildStorageDeps(): Promise<StorageDeps>;
|
|
299
306
|
export declare function registerStorageCommand(program: Command): Command;
|
|
300
307
|
//# sourceMappingURL=storage.d.ts.map
|
package/dist/commands/storage.js
CHANGED
|
@@ -1003,7 +1003,7 @@ async function signedInVault() {
|
|
|
1003
1003
|
* Deps for offload/fetch. The only store is the caller's personal vault,
|
|
1004
1004
|
* resolved from their canonical person entity and vended with `/sts/vend-self`.
|
|
1005
1005
|
*/
|
|
1006
|
-
async function buildOffloadDeps() {
|
|
1006
|
+
export async function buildOffloadDeps() {
|
|
1007
1007
|
const hqRoot = findHqRoot();
|
|
1008
1008
|
const personalVault = async () => {
|
|
1009
1009
|
const { vault } = await signedInVault();
|
|
@@ -1189,6 +1189,10 @@ export function refreshingVendedCredentials(vend, now = Date.now, marginMs = 5 *
|
|
|
1189
1189
|
return pending;
|
|
1190
1190
|
};
|
|
1191
1191
|
}
|
|
1192
|
+
/** Production deps. Exported for `hq billing usage`, which reads cloud status only. */
|
|
1193
|
+
export async function buildStorageDeps() {
|
|
1194
|
+
return buildDeps();
|
|
1195
|
+
}
|
|
1192
1196
|
async function buildDeps() {
|
|
1193
1197
|
// Sign-in is lazy so `status` can still report local sections when signed out,
|
|
1194
1198
|
// and it is resolved again for every cloud call (never once at the start): the
|
|
@@ -1323,7 +1327,7 @@ export function registerStorageCommand(program) {
|
|
|
1323
1327
|
paths: Array.isArray(opts.current) ? opts.current : undefined,
|
|
1324
1328
|
dryRun: Boolean(opts.dryRun),
|
|
1325
1329
|
yes: Boolean(opts.yes),
|
|
1326
|
-
}, await buildOffloadDeps());
|
|
1330
|
+
}, { ...(await buildOffloadDeps()), log: (line) => (opts.json ? console.error(line) : console.log(line)) });
|
|
1327
1331
|
if (!result)
|
|
1328
1332
|
return;
|
|
1329
1333
|
console.log(opts.json ? JSON.stringify(result, null, 2) : formatOffload(result));
|
package/dist/commands/whoami.js
CHANGED
|
@@ -153,6 +153,15 @@ export function registerWhoamiCommand(program) {
|
|
|
153
153
|
authenticated: machine ? Boolean(machineCreds) : Boolean(cached && !isExpiring(cached, 0)),
|
|
154
154
|
tokenSource: machine ? 'machine' : 'person',
|
|
155
155
|
email: machine ? null : displayedIdentity.email ?? null,
|
|
156
|
+
// Cognito subject of the person shown in `email` (null for machine
|
|
157
|
+
// identities). Outpost jobs record owners by this id.
|
|
158
|
+
sub: machine ? null : displayedIdentity.sub ?? null,
|
|
159
|
+
// The human an Outpost session acts for, from the token's
|
|
160
|
+
// delegated claims, for machine and person sources alike.
|
|
161
|
+
delegatedEmail: identity.delegatedEmail !== undefined && identity.delegatedSub !== undefined
|
|
162
|
+
? identity.delegatedEmail : null,
|
|
163
|
+
delegatedSub: identity.delegatedEmail !== undefined && identity.delegatedSub !== undefined
|
|
164
|
+
? identity.delegatedSub : null,
|
|
156
165
|
personUid: !machine && identity.entityType === 'person' ? identity.entityUid ?? null : null,
|
|
157
166
|
agentUid,
|
|
158
167
|
username: machineCreds?.username ?? null,
|