clearotron 0.3.0-beta.2 → 0.3.0-beta.4
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/INSTALL.md +32 -6
- package/bin/connect.mjs +68 -25
- package/bin/disconnect.mjs +16 -11
- package/bin/onboard.mjs +65 -6
- package/bin/start.mjs +7 -1
- package/build-info.json +2 -2
- package/driver/CHANGELOG.md +38 -0
- package/driver/driver.config.mjs +5 -0
- package/driver/engine/anthropic-agent.mjs +34 -17
- package/driver/gateway.mjs +76 -15
- package/driver/package.json +1 -1
- package/driver/portal-service.mjs +1 -1
- package/driver/profile-service.mjs +31 -3
- package/driver/publish/index.mjs +12 -9
- package/driver/publish/knockout.mjs +4 -2
- package/driver/publish/office-record-links.mjs +56 -21
- package/driver/recipe-service.mjs +14 -5
- package/driver/record-origins.mjs +14 -0
- package/driver/suite-census.json +34 -28
- package/mcp-server/CHANGELOG.md +8 -0
- package/mcp-server/lib/driver.mjs +2 -0
- package/mcp-server/lib/knockout.mjs +2 -2
- package/mcp-server/lib/options.mjs +9 -2
- package/mcp-server/package.json +1 -1
- package/package.json +1 -1
- package/portal-ui/dist/assets/{index-CsCuPshD.css → index-Cv-E_agg.css} +199 -86
- package/portal-ui/dist/assets/{index-CcFjgM78.js → index-DWYCsOCJ.js} +514 -380
- package/portal-ui/dist/index.html +2 -2
- package/portal-ui/package.json +1 -1
- package/providers/clarivate/src/core.js +5 -0
- package/providers/oauth-mcp-bridge/CHANGELOG.md +8 -0
- package/providers/oauth-mcp-bridge/package.json +1 -1
- package/scripts/e2e-unread-terminals.mjs +1 -1
- package/scripts/e2e.mjs +114 -9
- package/scripts/revisit-render-check.mjs +22 -4
- package/scripts/travelling-predicates.mjs +1 -1
- package/shared/connect-clients.mjs +282 -321
- package/shared/names-in-force.mjs +1 -0
- package/shared/stdio-connect.mjs +63 -0
- package/shared/store-in-repo.mjs +50 -2
|
@@ -10764,7 +10764,33 @@ var api = {
|
|
|
10764
10764
|
...asString(r["sub"]) ? { sub: asString(r["sub"]) } : {},
|
|
10765
10765
|
...asString(r["verifiedOn"]) ? { verifiedOn: asString(r["verifiedOn"]) } : {},
|
|
10766
10766
|
...asString(r["by"]) ? { by: asString(r["by"]) } : {},
|
|
10767
|
-
steps: asArray(r["steps"]).
|
|
10767
|
+
steps: asArray(r["steps"]).flatMap((x) => {
|
|
10768
|
+
const s = asRecord(x);
|
|
10769
|
+
const text = asString(s["text"]);
|
|
10770
|
+
if (!text) return [];
|
|
10771
|
+
const hint = asString(s["hint"]);
|
|
10772
|
+
const c = s["copy"] == null ? null : asRecord(s["copy"]);
|
|
10773
|
+
let copy;
|
|
10774
|
+
if (c) {
|
|
10775
|
+
const kind = asString(c["kind"]);
|
|
10776
|
+
if (kind === "block" && asString(c["text"])) copy = {
|
|
10777
|
+
kind,
|
|
10778
|
+
text: asString(c["text"])
|
|
10779
|
+
};
|
|
10780
|
+
else if (kind === "secret" && asString(c["label"]) && asString(c["template"]) && asString(c["slot"]) && asString(c["template"]).includes(asString(c["slot"]))) copy = {
|
|
10781
|
+
kind,
|
|
10782
|
+
label: asString(c["label"]),
|
|
10783
|
+
template: asString(c["template"]),
|
|
10784
|
+
slot: asString(c["slot"])
|
|
10785
|
+
};
|
|
10786
|
+
else return [];
|
|
10787
|
+
}
|
|
10788
|
+
return [{
|
|
10789
|
+
text,
|
|
10790
|
+
...hint ? { hint } : {},
|
|
10791
|
+
...copy ? { copy } : {}
|
|
10792
|
+
}];
|
|
10793
|
+
}),
|
|
10768
10794
|
launch: (() => {
|
|
10769
10795
|
const u = asString(asRecord(r["launch"])["url"]);
|
|
10770
10796
|
return u && /^https:\/\//.test(u) ? { url: u } : null;
|
|
@@ -11018,14 +11044,14 @@ var NAV = [
|
|
|
11018
11044
|
label: "Admin settings",
|
|
11019
11045
|
path: "/portal/admin",
|
|
11020
11046
|
icon: "settings",
|
|
11021
|
-
needs: "
|
|
11047
|
+
needs: "everything",
|
|
11022
11048
|
hidden: true,
|
|
11023
11049
|
children: [{
|
|
11024
11050
|
id: "admin.config",
|
|
11025
11051
|
label: "Global config",
|
|
11026
11052
|
path: "/portal/admin/config",
|
|
11027
11053
|
icon: "server",
|
|
11028
|
-
needs: "
|
|
11054
|
+
needs: "everything"
|
|
11029
11055
|
}]
|
|
11030
11056
|
},
|
|
11031
11057
|
{
|
|
@@ -11036,7 +11062,8 @@ var NAV = [
|
|
|
11036
11062
|
hidden: true
|
|
11037
11063
|
}
|
|
11038
11064
|
];
|
|
11039
|
-
var
|
|
11065
|
+
var holds = (who, gate) => gate === "everything" ? who.allAccounts === true : who.permissions[gate];
|
|
11066
|
+
var visible = (e, who) => !e.needs || holds(who, e.needs);
|
|
11040
11067
|
function navFor(who, entries = NAV) {
|
|
11041
11068
|
return entries.filter((e) => visible(e, who) && !e.hidden).map((e) => e.children ? {
|
|
11042
11069
|
...e,
|
|
@@ -11148,6 +11175,7 @@ var PATHS = {
|
|
|
11148
11175
|
bookmark: "M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2Z",
|
|
11149
11176
|
sliders: "M4 21v-7M4 10V3M12 21v-9M12 8V3M20 21v-5M20 12V3M1 14h6M9 8h6M17 16h6",
|
|
11150
11177
|
server: "M20 2H4a2 2 0 0 0-2 2v4a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2ZM20 14H4a2 2 0 0 0-2 2v4a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-4a2 2 0 0 0-2-2ZM6 6h.01M6 18h.01",
|
|
11178
|
+
laptop: "M20 16V7a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v9m16 0H4m16 0 1.28 2.55a1 1 0 0 1-.9 1.45H3.62a1 1 0 0 1-.9-1.45L4 16",
|
|
11151
11179
|
menu: "M3 12h18M3 6h18M3 18h18",
|
|
11152
11180
|
x: "M18 6 6 18M6 6l12 12",
|
|
11153
11181
|
chevron: "m9 18 6-6-6-6",
|
|
@@ -11155,6 +11183,7 @@ var PATHS = {
|
|
|
11155
11183
|
"chevron-right": "m9 18 6-6-6-6",
|
|
11156
11184
|
"grip-vertical": "M9 5h.01M15 5h.01M9 12h.01M15 12h.01M9 19h.01M15 19h.01",
|
|
11157
11185
|
"arrow-right": "M5 12h14M13 6l6 6-6 6",
|
|
11186
|
+
"arrow-left": "M19 12H5M11 18l-6-6 6-6",
|
|
11158
11187
|
trash: "M3 6h18M8 6V4h8v2M19 6l-1 14H6L5 6M10 11v6M14 11v6",
|
|
11159
11188
|
search: "M11 19a8 8 0 1 0 0-16 8 8 0 0 0 0 16ZM21 21l-4.3-4.3",
|
|
11160
11189
|
eye: "M2 12s4-7 10-7 10 7 10 7-4 7-10 7-10-7-10-7ZM12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z",
|
|
@@ -11486,6 +11515,157 @@ function accessSentence(input) {
|
|
|
11486
11515
|
return limits.length ? `${first} They ${limits.join(", and ")}.` : first;
|
|
11487
11516
|
}
|
|
11488
11517
|
//#endregion
|
|
11518
|
+
//#region src/shell/permissions.ts
|
|
11519
|
+
function canManage(who) {
|
|
11520
|
+
return who.permissions.manage;
|
|
11521
|
+
}
|
|
11522
|
+
function canRun(who) {
|
|
11523
|
+
return who.permissions.run;
|
|
11524
|
+
}
|
|
11525
|
+
function seesEverything(who) {
|
|
11526
|
+
return who.allAccounts === true;
|
|
11527
|
+
}
|
|
11528
|
+
//#endregion
|
|
11529
|
+
//#region src/shell/CompanyPicker.tsx
|
|
11530
|
+
function CompanyCard({ row, onPick }) {
|
|
11531
|
+
return (0, import_jsx_runtime.jsxs)("button", {
|
|
11532
|
+
type: "button",
|
|
11533
|
+
className: row.generic ? "entry-card pick-generic" : "entry-card",
|
|
11534
|
+
onClick: onPick,
|
|
11535
|
+
style: {
|
|
11536
|
+
flexDirection: "row",
|
|
11537
|
+
alignItems: "center",
|
|
11538
|
+
gap: 16,
|
|
11539
|
+
padding: "15px 17px"
|
|
11540
|
+
},
|
|
11541
|
+
children: [(0, import_jsx_runtime.jsxs)("span", {
|
|
11542
|
+
style: {
|
|
11543
|
+
minWidth: 0,
|
|
11544
|
+
flex: 1,
|
|
11545
|
+
textAlign: "left"
|
|
11546
|
+
},
|
|
11547
|
+
children: [(0, import_jsx_runtime.jsxs)("span", {
|
|
11548
|
+
className: "entry-title",
|
|
11549
|
+
style: {
|
|
11550
|
+
display: "block",
|
|
11551
|
+
marginBottom: 2
|
|
11552
|
+
},
|
|
11553
|
+
children: [row.name, row.generic ? (0, import_jsx_runtime.jsx)("span", {
|
|
11554
|
+
className: "pill",
|
|
11555
|
+
style: {
|
|
11556
|
+
marginLeft: 8,
|
|
11557
|
+
verticalAlign: "middle",
|
|
11558
|
+
background: "transparent",
|
|
11559
|
+
borderColor: "var(--accent-ink)",
|
|
11560
|
+
color: "var(--text-accent)"
|
|
11561
|
+
},
|
|
11562
|
+
children: "Default"
|
|
11563
|
+
}) : null]
|
|
11564
|
+
}), (0, import_jsx_runtime.jsx)("span", {
|
|
11565
|
+
className: "entry-body",
|
|
11566
|
+
style: {
|
|
11567
|
+
display: "block",
|
|
11568
|
+
overflow: "hidden",
|
|
11569
|
+
textOverflow: "ellipsis",
|
|
11570
|
+
whiteSpace: "nowrap"
|
|
11571
|
+
},
|
|
11572
|
+
children: row.line
|
|
11573
|
+
})]
|
|
11574
|
+
}), (0, import_jsx_runtime.jsx)("span", {
|
|
11575
|
+
"aria-hidden": "true",
|
|
11576
|
+
style: {
|
|
11577
|
+
flex: "none",
|
|
11578
|
+
color: "var(--text-faint)",
|
|
11579
|
+
display: "inline-flex"
|
|
11580
|
+
},
|
|
11581
|
+
children: (0, import_jsx_runtime.jsx)(Icon, {
|
|
11582
|
+
name: "arrow-right",
|
|
11583
|
+
size: 17
|
|
11584
|
+
})
|
|
11585
|
+
})]
|
|
11586
|
+
});
|
|
11587
|
+
}
|
|
11588
|
+
function CompanyPicker({ eyebrow, heading, line, keys, orgOf, organisations, companyName, factsFor, onPick, onAdd }) {
|
|
11589
|
+
const { headings, groups } = pickerGroups(keys, orgOf, organisations, companyName, factsFor);
|
|
11590
|
+
return (0, import_jsx_runtime.jsxs)("div", {
|
|
11591
|
+
className: "screen",
|
|
11592
|
+
children: [(0, import_jsx_runtime.jsx)("div", {
|
|
11593
|
+
className: "eyebrow",
|
|
11594
|
+
children: eyebrow
|
|
11595
|
+
}), (0, import_jsx_runtime.jsxs)("div", {
|
|
11596
|
+
className: "measure",
|
|
11597
|
+
children: [(0, import_jsx_runtime.jsxs)("div", {
|
|
11598
|
+
style: {
|
|
11599
|
+
display: "flex",
|
|
11600
|
+
alignItems: "flex-end",
|
|
11601
|
+
gap: 20,
|
|
11602
|
+
margin: "4px 0 18px"
|
|
11603
|
+
},
|
|
11604
|
+
children: [(0, import_jsx_runtime.jsxs)("div", {
|
|
11605
|
+
style: { flex: 1 },
|
|
11606
|
+
children: [(0, import_jsx_runtime.jsx)("h1", {
|
|
11607
|
+
style: {
|
|
11608
|
+
fontSize: 27,
|
|
11609
|
+
margin: "0 0 4px",
|
|
11610
|
+
color: "var(--text-strong)"
|
|
11611
|
+
},
|
|
11612
|
+
children: heading
|
|
11613
|
+
}), (0, import_jsx_runtime.jsx)("p", {
|
|
11614
|
+
style: {
|
|
11615
|
+
margin: 0,
|
|
11616
|
+
color: "var(--text-muted)",
|
|
11617
|
+
fontSize: 14.5
|
|
11618
|
+
},
|
|
11619
|
+
children: line
|
|
11620
|
+
})]
|
|
11621
|
+
}), onAdd ? (0, import_jsx_runtime.jsx)("button", {
|
|
11622
|
+
type: "button",
|
|
11623
|
+
className: "start-pill",
|
|
11624
|
+
onClick: onAdd,
|
|
11625
|
+
style: {
|
|
11626
|
+
flex: "none",
|
|
11627
|
+
borderColor: "var(--accent-ink)",
|
|
11628
|
+
color: "var(--text-accent)",
|
|
11629
|
+
fontWeight: 700
|
|
11630
|
+
},
|
|
11631
|
+
children: "+ New company"
|
|
11632
|
+
}) : null]
|
|
11633
|
+
}), groups.map((g, i) => (0, import_jsx_runtime.jsxs)("div", { children: [headings && g.org ? (0, import_jsx_runtime.jsx)("div", {
|
|
11634
|
+
className: "eyebrow",
|
|
11635
|
+
style: { margin: i === 0 ? "0 0 8px" : "16px 0 8px" },
|
|
11636
|
+
"data-anon": "mark",
|
|
11637
|
+
children: g.org.name
|
|
11638
|
+
}) : null, (0, import_jsx_runtime.jsx)("div", {
|
|
11639
|
+
style: {
|
|
11640
|
+
display: "flex",
|
|
11641
|
+
flexDirection: "column",
|
|
11642
|
+
gap: 10,
|
|
11643
|
+
marginTop: !headings && i > 0 ? 10 : 0
|
|
11644
|
+
},
|
|
11645
|
+
children: g.rows.map((r) => (0, import_jsx_runtime.jsx)(CompanyCard, {
|
|
11646
|
+
row: r,
|
|
11647
|
+
onPick: () => onPick(r.key)
|
|
11648
|
+
}, r.key))
|
|
11649
|
+
})] }, g.org?.key ?? ""))]
|
|
11650
|
+
})]
|
|
11651
|
+
});
|
|
11652
|
+
}
|
|
11653
|
+
function CompanyGate({ ctx, eyebrow, heading, line }) {
|
|
11654
|
+
return (0, import_jsx_runtime.jsx)(CompanyPicker, {
|
|
11655
|
+
eyebrow,
|
|
11656
|
+
heading,
|
|
11657
|
+
line,
|
|
11658
|
+
keys: ctx.ownerKeys,
|
|
11659
|
+
orgOf: ctx.orgOf,
|
|
11660
|
+
organisations: ctx.organisations,
|
|
11661
|
+
companyName: ctx.ownerName,
|
|
11662
|
+
factsFor: ctx.factsFor,
|
|
11663
|
+
onPick: (key) => ctx.setOwner(key),
|
|
11664
|
+
onAdd: canManage(ctx.me) ? () => ctx.go(NEW_COMPANY_PATH) : void 0
|
|
11665
|
+
});
|
|
11666
|
+
}
|
|
11667
|
+
var NEW_COMPANY_PATH = "/portal/brand/new";
|
|
11668
|
+
//#endregion
|
|
11489
11669
|
//#region src/shell/AppShell.tsx
|
|
11490
11670
|
var MOBILE = "(max-width: 899px)";
|
|
11491
11671
|
function useIsMobile() {
|
|
@@ -11740,7 +11920,8 @@ function AppShell({ render }) {
|
|
|
11740
11920
|
}), (0, import_jsx_runtime.jsx)(BrandOwnerSwitcher, {
|
|
11741
11921
|
grouped,
|
|
11742
11922
|
value: ownerInView,
|
|
11743
|
-
onChange: setOwnerGuarded
|
|
11923
|
+
onChange: setOwnerGuarded,
|
|
11924
|
+
onAdd: canManage(me) ? () => go(NEW_COMPANY_PATH) : void 0
|
|
11744
11925
|
})]
|
|
11745
11926
|
}), (0, import_jsx_runtime.jsx)(NavList, {
|
|
11746
11927
|
entries: groups.owner,
|
|
@@ -11908,14 +12089,15 @@ function AppShell({ render }) {
|
|
|
11908
12089
|
]
|
|
11909
12090
|
});
|
|
11910
12091
|
}
|
|
11911
|
-
|
|
12092
|
+
var NEW_COMPANY_OPTION = ":new-company";
|
|
12093
|
+
function BrandOwnerSwitcher({ grouped, value, onChange, onAdd }) {
|
|
11912
12094
|
const option = (r) => (0, import_jsx_runtime.jsx)("option", {
|
|
11913
12095
|
value: r.key,
|
|
11914
12096
|
children: switcherLabel(r)
|
|
11915
12097
|
}, r.key);
|
|
11916
12098
|
return (0, import_jsx_runtime.jsxs)("select", {
|
|
11917
12099
|
value: value ?? "",
|
|
11918
|
-
onChange: (e) => onChange(e.target.value || null),
|
|
12100
|
+
onChange: (e) => e.target.value === NEW_COMPANY_OPTION ? onAdd?.() : onChange(e.target.value || null),
|
|
11919
12101
|
"aria-label": "Company",
|
|
11920
12102
|
style: {
|
|
11921
12103
|
width: "100%",
|
|
@@ -11928,13 +12110,21 @@ function BrandOwnerSwitcher({ grouped, value, onChange }) {
|
|
|
11928
12110
|
fontWeight: 700,
|
|
11929
12111
|
color: "var(--text-strong)"
|
|
11930
12112
|
},
|
|
11931
|
-
children: [
|
|
11932
|
-
|
|
11933
|
-
|
|
11934
|
-
|
|
11935
|
-
|
|
11936
|
-
|
|
11937
|
-
|
|
12113
|
+
children: [
|
|
12114
|
+
(0, import_jsx_runtime.jsx)("option", {
|
|
12115
|
+
value: "",
|
|
12116
|
+
children: ALL_OWNERS
|
|
12117
|
+
}),
|
|
12118
|
+
grouped.groups.map((g) => grouped.headings && g.org ? (0, import_jsx_runtime.jsx)("optgroup", {
|
|
12119
|
+
label: g.org.name,
|
|
12120
|
+
children: g.rows.map(option)
|
|
12121
|
+
}, g.org.key) : g.rows.map(option)),
|
|
12122
|
+
onAdd ? (0, import_jsx_runtime.jsx)("option", {
|
|
12123
|
+
value: NEW_COMPANY_OPTION,
|
|
12124
|
+
"data-action": "new-company",
|
|
12125
|
+
children: "+ New company"
|
|
12126
|
+
}) : null
|
|
12127
|
+
]
|
|
11938
12128
|
});
|
|
11939
12129
|
}
|
|
11940
12130
|
var initials = (email) => {
|
|
@@ -12251,14 +12441,6 @@ function moveBefore(order, id, over) {
|
|
|
12251
12441
|
return next;
|
|
12252
12442
|
}
|
|
12253
12443
|
//#endregion
|
|
12254
|
-
//#region src/shell/permissions.ts
|
|
12255
|
-
function canManage(who) {
|
|
12256
|
-
return who.permissions.manage;
|
|
12257
|
-
}
|
|
12258
|
-
function canRun(who) {
|
|
12259
|
-
return who.permissions.run;
|
|
12260
|
-
}
|
|
12261
|
-
//#endregion
|
|
12262
12444
|
//#region src/screens/Home.tsx
|
|
12263
12445
|
var TERMINAL$1 = new Set([
|
|
12264
12446
|
"delivered",
|
|
@@ -13016,11 +13198,15 @@ function Clearances({ ctx }) {
|
|
|
13016
13198
|
const wanted = new URLSearchParams(window.location.search).get("owner");
|
|
13017
13199
|
if (wanted && wanted !== ctx.owner) ctx.setOwner(wanted);
|
|
13018
13200
|
}, [ctx]);
|
|
13019
|
-
const
|
|
13020
|
-
const
|
|
13201
|
+
const seesAll = ctx.me.allAccounts;
|
|
13202
|
+
const account = ownerFilter ?? (seesAll ? "*" : ctx.me.accounts.length === 1 ? ctx.me.accounts[0] : null);
|
|
13203
|
+
const { result: famResult, reload: reloadFamilies } = useLoad(() => seesAll ? api.families(account) : Promise.resolve({
|
|
13204
|
+
kind: "ok",
|
|
13205
|
+
value: NO_FAMILIES
|
|
13206
|
+
}), [account, seesAll]);
|
|
13021
13207
|
const families = famResult?.kind === "ok" ? famResult.value : NO_FAMILIES;
|
|
13022
13208
|
const [picked, setPicked] = (0, import_react.useState)(new Set());
|
|
13023
|
-
const canGroup = canManage(ctx.me);
|
|
13209
|
+
const canGroup = canManage(ctx.me) && seesAll;
|
|
13024
13210
|
const [showRetired, setShowRetired] = (0, import_react.useState)(false);
|
|
13025
13211
|
const { result: retiredResult, reload: reloadRetired } = useLoad(() => canGroup ? api.retiredRuns(account) : Promise.resolve({ kind: "notFound" }), [account, canGroup]);
|
|
13026
13212
|
const retired = retiredResult?.kind === "ok" ? retiredResult.value : [];
|
|
@@ -15936,146 +16122,6 @@ function unsavedChanges({ current, empty, saved, submitted }) {
|
|
|
15936
16122
|
return current !== saved;
|
|
15937
16123
|
}
|
|
15938
16124
|
//#endregion
|
|
15939
|
-
//#region src/shell/CompanyPicker.tsx
|
|
15940
|
-
function CompanyCard({ row, onPick }) {
|
|
15941
|
-
return (0, import_jsx_runtime.jsxs)("button", {
|
|
15942
|
-
type: "button",
|
|
15943
|
-
className: row.generic ? "entry-card pick-generic" : "entry-card",
|
|
15944
|
-
onClick: onPick,
|
|
15945
|
-
style: {
|
|
15946
|
-
flexDirection: "row",
|
|
15947
|
-
alignItems: "center",
|
|
15948
|
-
gap: 16,
|
|
15949
|
-
padding: "15px 17px"
|
|
15950
|
-
},
|
|
15951
|
-
children: [(0, import_jsx_runtime.jsxs)("span", {
|
|
15952
|
-
style: {
|
|
15953
|
-
minWidth: 0,
|
|
15954
|
-
flex: 1,
|
|
15955
|
-
textAlign: "left"
|
|
15956
|
-
},
|
|
15957
|
-
children: [(0, import_jsx_runtime.jsxs)("span", {
|
|
15958
|
-
className: "entry-title",
|
|
15959
|
-
style: {
|
|
15960
|
-
display: "block",
|
|
15961
|
-
marginBottom: 2
|
|
15962
|
-
},
|
|
15963
|
-
children: [row.name, row.generic ? (0, import_jsx_runtime.jsx)("span", {
|
|
15964
|
-
className: "pill",
|
|
15965
|
-
style: {
|
|
15966
|
-
marginLeft: 8,
|
|
15967
|
-
verticalAlign: "middle",
|
|
15968
|
-
background: "transparent",
|
|
15969
|
-
borderColor: "var(--accent-ink)",
|
|
15970
|
-
color: "var(--text-accent)"
|
|
15971
|
-
},
|
|
15972
|
-
children: "Default"
|
|
15973
|
-
}) : null]
|
|
15974
|
-
}), (0, import_jsx_runtime.jsx)("span", {
|
|
15975
|
-
className: "entry-body",
|
|
15976
|
-
style: {
|
|
15977
|
-
display: "block",
|
|
15978
|
-
overflow: "hidden",
|
|
15979
|
-
textOverflow: "ellipsis",
|
|
15980
|
-
whiteSpace: "nowrap"
|
|
15981
|
-
},
|
|
15982
|
-
children: row.line
|
|
15983
|
-
})]
|
|
15984
|
-
}), (0, import_jsx_runtime.jsx)("span", {
|
|
15985
|
-
"aria-hidden": "true",
|
|
15986
|
-
style: {
|
|
15987
|
-
flex: "none",
|
|
15988
|
-
color: "var(--text-faint)",
|
|
15989
|
-
display: "inline-flex"
|
|
15990
|
-
},
|
|
15991
|
-
children: (0, import_jsx_runtime.jsx)(Icon, {
|
|
15992
|
-
name: "arrow-right",
|
|
15993
|
-
size: 17
|
|
15994
|
-
})
|
|
15995
|
-
})]
|
|
15996
|
-
});
|
|
15997
|
-
}
|
|
15998
|
-
function CompanyPicker({ eyebrow, heading, line, keys, orgOf, organisations, companyName, factsFor, onPick, onAdd }) {
|
|
15999
|
-
const { headings, groups } = pickerGroups(keys, orgOf, organisations, companyName, factsFor);
|
|
16000
|
-
return (0, import_jsx_runtime.jsxs)("div", {
|
|
16001
|
-
className: "screen",
|
|
16002
|
-
children: [(0, import_jsx_runtime.jsx)("div", {
|
|
16003
|
-
className: "eyebrow",
|
|
16004
|
-
children: eyebrow
|
|
16005
|
-
}), (0, import_jsx_runtime.jsxs)("div", {
|
|
16006
|
-
className: "measure",
|
|
16007
|
-
children: [(0, import_jsx_runtime.jsxs)("div", {
|
|
16008
|
-
style: {
|
|
16009
|
-
display: "flex",
|
|
16010
|
-
alignItems: "flex-end",
|
|
16011
|
-
gap: 20,
|
|
16012
|
-
margin: "4px 0 18px"
|
|
16013
|
-
},
|
|
16014
|
-
children: [(0, import_jsx_runtime.jsxs)("div", {
|
|
16015
|
-
style: { flex: 1 },
|
|
16016
|
-
children: [(0, import_jsx_runtime.jsx)("h1", {
|
|
16017
|
-
style: {
|
|
16018
|
-
fontSize: 27,
|
|
16019
|
-
margin: "0 0 4px",
|
|
16020
|
-
color: "var(--text-strong)"
|
|
16021
|
-
},
|
|
16022
|
-
children: heading
|
|
16023
|
-
}), (0, import_jsx_runtime.jsx)("p", {
|
|
16024
|
-
style: {
|
|
16025
|
-
margin: 0,
|
|
16026
|
-
color: "var(--text-muted)",
|
|
16027
|
-
fontSize: 14.5
|
|
16028
|
-
},
|
|
16029
|
-
children: line
|
|
16030
|
-
})]
|
|
16031
|
-
}), onAdd ? (0, import_jsx_runtime.jsx)("button", {
|
|
16032
|
-
type: "button",
|
|
16033
|
-
className: "start-pill",
|
|
16034
|
-
onClick: onAdd,
|
|
16035
|
-
style: {
|
|
16036
|
-
flex: "none",
|
|
16037
|
-
borderColor: "var(--accent-ink)",
|
|
16038
|
-
color: "var(--text-accent)",
|
|
16039
|
-
fontWeight: 700
|
|
16040
|
-
},
|
|
16041
|
-
children: "+ New company"
|
|
16042
|
-
}) : null]
|
|
16043
|
-
}), groups.map((g, i) => (0, import_jsx_runtime.jsxs)("div", { children: [headings && g.org ? (0, import_jsx_runtime.jsx)("div", {
|
|
16044
|
-
className: "eyebrow",
|
|
16045
|
-
style: { margin: i === 0 ? "0 0 8px" : "16px 0 8px" },
|
|
16046
|
-
"data-anon": "mark",
|
|
16047
|
-
children: g.org.name
|
|
16048
|
-
}) : null, (0, import_jsx_runtime.jsx)("div", {
|
|
16049
|
-
style: {
|
|
16050
|
-
display: "flex",
|
|
16051
|
-
flexDirection: "column",
|
|
16052
|
-
gap: 10,
|
|
16053
|
-
marginTop: !headings && i > 0 ? 10 : 0
|
|
16054
|
-
},
|
|
16055
|
-
children: g.rows.map((r) => (0, import_jsx_runtime.jsx)(CompanyCard, {
|
|
16056
|
-
row: r,
|
|
16057
|
-
onPick: () => onPick(r.key)
|
|
16058
|
-
}, r.key))
|
|
16059
|
-
})] }, g.org?.key ?? ""))]
|
|
16060
|
-
})]
|
|
16061
|
-
});
|
|
16062
|
-
}
|
|
16063
|
-
function CompanyGate({ ctx, eyebrow, heading, line }) {
|
|
16064
|
-
return (0, import_jsx_runtime.jsx)(CompanyPicker, {
|
|
16065
|
-
eyebrow,
|
|
16066
|
-
heading,
|
|
16067
|
-
line,
|
|
16068
|
-
keys: ctx.ownerKeys,
|
|
16069
|
-
orgOf: ctx.orgOf,
|
|
16070
|
-
organisations: ctx.organisations,
|
|
16071
|
-
companyName: ctx.ownerName,
|
|
16072
|
-
factsFor: ctx.factsFor,
|
|
16073
|
-
onPick: (key) => ctx.setOwner(key),
|
|
16074
|
-
onAdd: canManage(ctx.me) ? () => ctx.go(NEW_COMPANY_PATH) : void 0
|
|
16075
|
-
});
|
|
16076
|
-
}
|
|
16077
|
-
var NEW_COMPANY_PATH = "/portal/brand/new";
|
|
16078
|
-
//#endregion
|
|
16079
16125
|
//#region src/contract/companyCreated.ts
|
|
16080
16126
|
var pending = null;
|
|
16081
16127
|
function handOff(created) {
|
|
@@ -17392,7 +17438,7 @@ function NewClearance({ ctx }) {
|
|
|
17392
17438
|
demoMode: ctx.me.engineMode === "demo",
|
|
17393
17439
|
setupRoute: ctx.me.setupRoute,
|
|
17394
17440
|
programDisputed: ctx.me.engineProgramDisputed,
|
|
17395
|
-
onSettings:
|
|
17441
|
+
onSettings: seesEverything(ctx.me) ? () => ctx.go("/portal/admin/config") : null,
|
|
17396
17442
|
saveOpen,
|
|
17397
17443
|
saveName,
|
|
17398
17444
|
saveText,
|
|
@@ -20023,19 +20069,19 @@ var WHAT_YOU_CAN_DO = [
|
|
|
20023
20069
|
"Ask what-if: why a finding was rated as it was, what changes if the goods narrow"
|
|
20024
20070
|
];
|
|
20025
20071
|
var COPIED_MS = 2600;
|
|
20072
|
+
var PLACES = ["disk", "public-http"];
|
|
20026
20073
|
var WHERE = {
|
|
20027
|
-
disk:
|
|
20028
|
-
|
|
20029
|
-
|
|
20030
|
-
|
|
20031
|
-
|
|
20032
|
-
|
|
20033
|
-
|
|
20034
|
-
}
|
|
20035
|
-
var servesPlace = (o, place) => {
|
|
20036
|
-
const r = o.route ?? "public-http";
|
|
20037
|
-
return r === place || r === EITHER;
|
|
20074
|
+
disk: {
|
|
20075
|
+
label: "Clearotron is installed on this machine (laptop/desktop)",
|
|
20076
|
+
icon: "laptop"
|
|
20077
|
+
},
|
|
20078
|
+
"public-http": {
|
|
20079
|
+
label: "Clearotron is running elsewhere (e.g. Cloud/Server)",
|
|
20080
|
+
icon: "server"
|
|
20081
|
+
}
|
|
20038
20082
|
};
|
|
20083
|
+
var HELP_URL = "https://github.com/CordilleraSarl/clearotron/blob/main/mcp-server/CONNECT.md";
|
|
20084
|
+
var HELP_LINK_TEXT = "GitHub MCP Connector Documentation";
|
|
20039
20085
|
async function copy(text) {
|
|
20040
20086
|
try {
|
|
20041
20087
|
await navigator.clipboard.writeText(text);
|
|
@@ -20045,77 +20091,121 @@ async function copy(text) {
|
|
|
20045
20091
|
}
|
|
20046
20092
|
}
|
|
20047
20093
|
var mask = (key) => key.length > 3 ? `${key.slice(0, 3)}••••` : "••••";
|
|
20048
|
-
var
|
|
20049
|
-
function
|
|
20050
|
-
|
|
20051
|
-
|
|
20052
|
-
className: "ai-
|
|
20053
|
-
|
|
20054
|
-
|
|
20055
|
-
|
|
20056
|
-
|
|
20057
|
-
|
|
20058
|
-
|
|
20059
|
-
|
|
20060
|
-
|
|
20061
|
-
|
|
20062
|
-
|
|
20063
|
-
|
|
20064
|
-
}), (0, import_jsx_runtime.jsxs)("span", {
|
|
20065
|
-
className: "ai-dest-say",
|
|
20066
|
-
children: [(0, import_jsx_runtime.jsx)("span", {
|
|
20067
|
-
className: "ai-dest-idle",
|
|
20068
|
-
children: pasteLine(offer)
|
|
20069
|
-
}), (0, import_jsx_runtime.jsx)("span", {
|
|
20070
|
-
className: "ai-dest-done",
|
|
20071
|
-
children: "✓ Copied"
|
|
20072
|
-
})]
|
|
20073
|
-
})]
|
|
20074
|
-
});
|
|
20075
|
-
}
|
|
20076
|
-
function Panel({ offer, landed }) {
|
|
20094
|
+
var fill = (c, value) => c.template.split(c.slot).join(value);
|
|
20095
|
+
function Marked({ text }) {
|
|
20096
|
+
const parts = text.split(/(\*\*[^*]+\*\*|`[^`]+`)/g).filter((p) => p !== "");
|
|
20097
|
+
return (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: parts.map((p, n) => p.length > 4 && p.startsWith("**") && p.endsWith("**") ? (0, import_jsx_runtime.jsx)("b", { children: p.slice(2, -2) }, n) : p.length > 2 && p.startsWith("`") && p.endsWith("`") ? (0, import_jsx_runtime.jsx)("code", {
|
|
20098
|
+
className: "ai-code",
|
|
20099
|
+
children: p.slice(1, -1)
|
|
20100
|
+
}, n) : (0, import_jsx_runtime.jsx)("span", { children: p }, n)) });
|
|
20101
|
+
}
|
|
20102
|
+
var AT_REST = {
|
|
20103
|
+
copiedAt: null,
|
|
20104
|
+
landedAt: null,
|
|
20105
|
+
landed: null,
|
|
20106
|
+
revealedAt: null,
|
|
20107
|
+
revealed: null
|
|
20108
|
+
};
|
|
20109
|
+
function StepsPanel({ offer, measuring = false, state = AT_REST, onBlock, onSecret }) {
|
|
20077
20110
|
return (0, import_jsx_runtime.jsxs)("div", {
|
|
20078
|
-
className: "
|
|
20079
|
-
"data-for": offer.id,
|
|
20111
|
+
className: "steps-panel",
|
|
20112
|
+
"data-for": measuring ? void 0 : offer.id,
|
|
20080
20113
|
children: [
|
|
20114
|
+
(0, import_jsx_runtime.jsx)("div", {
|
|
20115
|
+
className: "eyebrow",
|
|
20116
|
+
children: "Steps for"
|
|
20117
|
+
}),
|
|
20081
20118
|
(0, import_jsx_runtime.jsx)("h3", {
|
|
20082
|
-
className: "
|
|
20083
|
-
children:
|
|
20119
|
+
className: "steps-name",
|
|
20120
|
+
children: offer.name
|
|
20084
20121
|
}),
|
|
20085
|
-
|
|
20086
|
-
className: "
|
|
20087
|
-
children:
|
|
20088
|
-
|
|
20089
|
-
|
|
20090
|
-
|
|
20091
|
-
|
|
20092
|
-
|
|
20093
|
-
|
|
20094
|
-
|
|
20095
|
-
|
|
20096
|
-
|
|
20097
|
-
|
|
20098
|
-
|
|
20099
|
-
|
|
20100
|
-
|
|
20101
|
-
|
|
20102
|
-
|
|
20103
|
-
|
|
20104
|
-
|
|
20105
|
-
|
|
20122
|
+
(0, import_jsx_runtime.jsx)("ol", {
|
|
20123
|
+
className: "steps",
|
|
20124
|
+
children: offer.steps.map((s, i) => {
|
|
20125
|
+
const c = s.copy;
|
|
20126
|
+
const flashed = !measuring && state.copiedAt === i;
|
|
20127
|
+
const landed = measuring && c?.kind === "secret" ? fill(c, mask("")) : state.landedAt === i ? state.landed : null;
|
|
20128
|
+
return (0, import_jsx_runtime.jsx)("li", { children: (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
20129
|
+
(0, import_jsx_runtime.jsx)("div", {
|
|
20130
|
+
className: "step-text",
|
|
20131
|
+
children: (0, import_jsx_runtime.jsx)(Marked, { text: s.text })
|
|
20132
|
+
}),
|
|
20133
|
+
c?.kind === "block" ? (0, import_jsx_runtime.jsxs)("div", {
|
|
20134
|
+
className: "codeblock",
|
|
20135
|
+
children: [(0, import_jsx_runtime.jsx)("pre", { children: c.text }), (0, import_jsx_runtime.jsx)("button", {
|
|
20136
|
+
type: "button",
|
|
20137
|
+
className: `btn-ghost${flashed ? " is-copied" : ""}`,
|
|
20138
|
+
"data-step": i,
|
|
20139
|
+
tabIndex: measuring ? -1 : void 0,
|
|
20140
|
+
onClick: () => onBlock?.(i, c.text),
|
|
20141
|
+
children: flashed ? "✓ Copied" : "Copy"
|
|
20142
|
+
})]
|
|
20143
|
+
}) : null,
|
|
20144
|
+
c?.kind === "secret" ? (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
20145
|
+
(0, import_jsx_runtime.jsx)("div", {
|
|
20146
|
+
className: "secret-btn",
|
|
20147
|
+
children: (0, import_jsx_runtime.jsx)("button", {
|
|
20148
|
+
type: "button",
|
|
20149
|
+
className: `btn-primary${flashed ? " is-copied" : ""}`,
|
|
20150
|
+
"data-step": i,
|
|
20151
|
+
tabIndex: measuring ? -1 : void 0,
|
|
20152
|
+
onClick: () => onSecret?.(i, c),
|
|
20153
|
+
children: flashed ? (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [(0, import_jsx_runtime.jsx)(Icon, {
|
|
20154
|
+
name: "check",
|
|
20155
|
+
size: 15
|
|
20156
|
+
}), "Copied"] }) : landed ? "Copy again" : c.label
|
|
20157
|
+
})
|
|
20158
|
+
}),
|
|
20159
|
+
landed ? (0, import_jsx_runtime.jsxs)("div", {
|
|
20160
|
+
className: "landed",
|
|
20161
|
+
children: [(0, import_jsx_runtime.jsx)("div", {
|
|
20162
|
+
className: "landed-label",
|
|
20163
|
+
children: "On your clipboard now"
|
|
20164
|
+
}), landed.split("\n").map((line, n) => (0, import_jsx_runtime.jsx)("div", {
|
|
20165
|
+
className: "mono",
|
|
20166
|
+
children: line
|
|
20167
|
+
}, n))]
|
|
20168
|
+
}) : null,
|
|
20169
|
+
!measuring && state.revealedAt === i && state.revealed ? (0, import_jsx_runtime.jsxs)("div", {
|
|
20170
|
+
className: "landed",
|
|
20171
|
+
children: [(0, import_jsx_runtime.jsx)("p", {
|
|
20172
|
+
className: "ai-said",
|
|
20173
|
+
children: "Your browser would not let us copy it. Copy this by hand — it is yours, and it will not be shown again."
|
|
20174
|
+
}), (0, import_jsx_runtime.jsx)("pre", {
|
|
20175
|
+
className: "ai-pre",
|
|
20176
|
+
children: state.revealed
|
|
20177
|
+
})]
|
|
20178
|
+
}) : null
|
|
20179
|
+
] }) : null,
|
|
20180
|
+
s.hint ? (0, import_jsx_runtime.jsx)("div", {
|
|
20181
|
+
className: "step-hint",
|
|
20182
|
+
children: (0, import_jsx_runtime.jsx)(Marked, { text: s.hint })
|
|
20183
|
+
}) : null
|
|
20184
|
+
] }) }, i);
|
|
20185
|
+
})
|
|
20106
20186
|
})
|
|
20107
20187
|
]
|
|
20108
20188
|
});
|
|
20109
20189
|
}
|
|
20190
|
+
function NotOnline() {
|
|
20191
|
+
return (0, import_jsx_runtime.jsxs)("div", {
|
|
20192
|
+
className: "notice ai-none",
|
|
20193
|
+
children: [(0, import_jsx_runtime.jsx)("strong", { children: "Not available on this installation yet" }), (0, import_jsx_runtime.jsx)("p", { children: "Your AI app reaches Clearotron over the internet, and this installation isn’t on the internet yet. Whoever installed it can put it online — it takes about a minute and needs no account." })]
|
|
20194
|
+
});
|
|
20195
|
+
}
|
|
20110
20196
|
function UseYourAI({ ctx }) {
|
|
20111
20197
|
const [access, setAccess] = (0, import_react.useState)(null);
|
|
20112
|
-
const [
|
|
20198
|
+
const [place, setPlace] = (0, import_react.useState)(null);
|
|
20113
20199
|
const [picked, setPicked] = (0, import_react.useState)(null);
|
|
20200
|
+
const [copiedAt, setCopiedAt] = (0, import_react.useState)(null);
|
|
20201
|
+
const [landedAt, setLandedAt] = (0, import_react.useState)(null);
|
|
20114
20202
|
const [landed, setLanded] = (0, import_react.useState)(null);
|
|
20115
|
-
const [copiedId, setCopiedId] = (0, import_react.useState)(null);
|
|
20116
20203
|
const [failed, setFailed] = (0, import_react.useState)(null);
|
|
20204
|
+
const [revealedAt, setRevealedAt] = (0, import_react.useState)(null);
|
|
20117
20205
|
const [revealed, setRevealed] = (0, import_react.useState)(null);
|
|
20206
|
+
const [slotHeight, setSlotHeight] = (0, import_react.useState)(0);
|
|
20118
20207
|
const timer = (0, import_react.useRef)(null);
|
|
20208
|
+
const probe = (0, import_react.useRef)(null);
|
|
20119
20209
|
(0, import_react.useEffect)(() => {
|
|
20120
20210
|
api.mcpAccess().then((r) => {
|
|
20121
20211
|
if (r.kind === "ok") setAccess(r.value);
|
|
@@ -20125,43 +20215,66 @@ function UseYourAI({ ctx }) {
|
|
|
20125
20215
|
if (timer.current) window.clearTimeout(timer.current);
|
|
20126
20216
|
}, []);
|
|
20127
20217
|
const served = (access?.offers ?? []).filter((o) => o.served);
|
|
20128
|
-
const routes =
|
|
20129
|
-
const
|
|
20130
|
-
const
|
|
20218
|
+
const routes = PLACES.filter((p) => served.some((o) => o.route === p));
|
|
20219
|
+
const asks = routes.includes("disk");
|
|
20220
|
+
const active = asks ? place : routes[0] ?? null;
|
|
20221
|
+
const here = served.filter((o) => active !== null && o.route === active);
|
|
20131
20222
|
const chosen = here.find((o) => o.id === picked) ?? null;
|
|
20132
|
-
|
|
20133
|
-
|
|
20223
|
+
(0, import_react.useLayoutEffect)(() => {
|
|
20224
|
+
const el = probe.current;
|
|
20225
|
+
if (!el) return;
|
|
20226
|
+
const measure = () => setSlotHeight(Math.max(0, ...[...el.children].map((c) => c.offsetHeight)));
|
|
20227
|
+
measure();
|
|
20228
|
+
const seen = new ResizeObserver(measure);
|
|
20229
|
+
seen.observe(el);
|
|
20230
|
+
return () => seen.disconnect();
|
|
20231
|
+
}, [active, here.length]);
|
|
20232
|
+
const settle = () => {
|
|
20233
|
+
setCopiedAt(null);
|
|
20234
|
+
setLandedAt(null);
|
|
20235
|
+
setLanded(null);
|
|
20236
|
+
setRevealedAt(null);
|
|
20237
|
+
setRevealed(null);
|
|
20238
|
+
setFailed(null);
|
|
20239
|
+
};
|
|
20240
|
+
const flash = (i) => {
|
|
20241
|
+
setCopiedAt(i);
|
|
20242
|
+
if (timer.current) window.clearTimeout(timer.current);
|
|
20243
|
+
timer.current = window.setTimeout(() => setCopiedAt(null), COPIED_MS);
|
|
20244
|
+
};
|
|
20245
|
+
const copyBlock = async (i, text) => {
|
|
20246
|
+
setFailed(null);
|
|
20247
|
+
if (!await copy(text)) {
|
|
20248
|
+
setFailed("Your browser would not let us copy it. Select the text above and copy it by hand.");
|
|
20249
|
+
return;
|
|
20250
|
+
}
|
|
20251
|
+
flash(i);
|
|
20252
|
+
};
|
|
20253
|
+
const press = async (i, c) => {
|
|
20134
20254
|
setFailed(null);
|
|
20255
|
+
setRevealedAt(null);
|
|
20135
20256
|
setRevealed(null);
|
|
20136
|
-
|
|
20137
|
-
if (
|
|
20138
|
-
|
|
20139
|
-
|
|
20140
|
-
return;
|
|
20141
|
-
}
|
|
20142
|
-
setLanded(offer.command);
|
|
20143
|
-
} else {
|
|
20144
|
-
const r = await api.connectKey();
|
|
20145
|
-
if (r.kind !== "ok") {
|
|
20146
|
-
setFailed("We could not set this up just now. Try again, or ask us.");
|
|
20147
|
-
return;
|
|
20148
|
-
}
|
|
20149
|
-
if (!await copy(`${r.value.address}\n${r.value.key}`)) {
|
|
20150
|
-
setRevealed({
|
|
20151
|
-
address: r.value.address,
|
|
20152
|
-
key: r.value.key
|
|
20153
|
-
});
|
|
20154
|
-
return;
|
|
20155
|
-
}
|
|
20156
|
-
setLanded(`${r.value.address} ${mask(r.value.key)}`);
|
|
20257
|
+
const r = await api.connectKey();
|
|
20258
|
+
if (r.kind !== "ok") {
|
|
20259
|
+
setFailed("We could not set this up just now. Try again, or ask us.");
|
|
20260
|
+
return;
|
|
20157
20261
|
}
|
|
20158
|
-
|
|
20159
|
-
|
|
20160
|
-
|
|
20262
|
+
if (!await copy(fill(c, r.value.key))) {
|
|
20263
|
+
setRevealedAt(i);
|
|
20264
|
+
setRevealed(fill(c, r.value.key));
|
|
20265
|
+
return;
|
|
20266
|
+
}
|
|
20267
|
+
setLandedAt(i);
|
|
20268
|
+
setLanded(fill(c, mask(r.value.key)));
|
|
20269
|
+
flash(i);
|
|
20161
20270
|
};
|
|
20162
20271
|
return (0, import_jsx_runtime.jsxs)("div", {
|
|
20163
20272
|
className: "screen ai-screen",
|
|
20164
20273
|
children: [
|
|
20274
|
+
(0, import_jsx_runtime.jsx)("div", {
|
|
20275
|
+
className: "eyebrow",
|
|
20276
|
+
children: "Use your own AI"
|
|
20277
|
+
}),
|
|
20165
20278
|
(0, import_jsx_runtime.jsx)("h1", {
|
|
20166
20279
|
className: "ai-title",
|
|
20167
20280
|
children: "Use your own AI"
|
|
@@ -20171,136 +20284,156 @@ function UseYourAI({ ctx }) {
|
|
|
20171
20284
|
children: "Run and interrogate clearances from the assistant you already use — by voice, by email, or just by asking."
|
|
20172
20285
|
}),
|
|
20173
20286
|
(0, import_jsx_runtime.jsxs)("section", {
|
|
20174
|
-
className: "ai-can",
|
|
20287
|
+
className: "ctx-card ai-can",
|
|
20175
20288
|
children: [
|
|
20176
20289
|
(0, import_jsx_runtime.jsx)("h2", { children: "What you can do" }),
|
|
20177
|
-
(0, import_jsx_runtime.jsx)("ul", {
|
|
20290
|
+
(0, import_jsx_runtime.jsx)("ul", {
|
|
20291
|
+
className: "ai-can-list",
|
|
20292
|
+
children: WHAT_YOU_CAN_DO.map((line) => (0, import_jsx_runtime.jsxs)("li", { children: [(0, import_jsx_runtime.jsx)(Icon, {
|
|
20293
|
+
name: "check",
|
|
20294
|
+
size: 15
|
|
20295
|
+
}), line] }, line))
|
|
20296
|
+
}),
|
|
20178
20297
|
(0, import_jsx_runtime.jsxs)("p", {
|
|
20179
20298
|
className: "ai-can-foot",
|
|
20180
20299
|
children: [
|
|
20181
|
-
"
|
|
20300
|
+
"Use the ",
|
|
20182
20301
|
(0, import_jsx_runtime.jsx)("strong", { children: "Ask AI" }),
|
|
20183
|
-
" button
|
|
20184
|
-
" ",
|
|
20185
|
-
(0, import_jsx_runtime.jsx)("strong", { children: "What you set up here reaches your own clearances and nothing else." })
|
|
20302
|
+
" button on a report."
|
|
20186
20303
|
]
|
|
20187
20304
|
})
|
|
20188
20305
|
]
|
|
20189
20306
|
}),
|
|
20190
|
-
(0, import_jsx_runtime.
|
|
20191
|
-
className: "ai-connect
|
|
20192
|
-
children: "
|
|
20193
|
-
|
|
20194
|
-
|
|
20195
|
-
|
|
20196
|
-
|
|
20197
|
-
|
|
20198
|
-
|
|
20199
|
-
|
|
20200
|
-
|
|
20201
|
-
|
|
20202
|
-
|
|
20203
|
-
|
|
20204
|
-
|
|
20205
|
-
|
|
20206
|
-
|
|
20207
|
-
|
|
20208
|
-
|
|
20209
|
-
|
|
20210
|
-
|
|
20211
|
-
|
|
20212
|
-
|
|
20213
|
-
|
|
20214
|
-
|
|
20215
|
-
|
|
20216
|
-
|
|
20217
|
-
|
|
20218
|
-
|
|
20219
|
-
|
|
20220
|
-
|
|
20221
|
-
|
|
20222
|
-
|
|
20223
|
-
|
|
20224
|
-
|
|
20225
|
-
|
|
20226
|
-
|
|
20227
|
-
|
|
20228
|
-
|
|
20229
|
-
|
|
20230
|
-
|
|
20231
|
-
|
|
20232
|
-
|
|
20233
|
-
|
|
20234
|
-
|
|
20235
|
-
|
|
20236
|
-
|
|
20237
|
-
|
|
20238
|
-
|
|
20239
|
-
|
|
20240
|
-
|
|
20241
|
-
}),
|
|
20242
|
-
(0, import_jsx_runtime.jsxs)("div", {
|
|
20243
|
-
className: "ai-slot",
|
|
20244
|
-
"aria-live": "polite",
|
|
20245
|
-
children: [failed ? (0, import_jsx_runtime.jsx)("p", {
|
|
20246
|
-
className: "ai-said",
|
|
20247
|
-
children: failed
|
|
20248
|
-
}) : null, revealed ? (0, import_jsx_runtime.jsxs)("div", {
|
|
20249
|
-
className: "ai-panel",
|
|
20250
|
-
children: [(0, import_jsx_runtime.jsxs)("p", {
|
|
20251
|
-
className: "ai-said",
|
|
20252
|
-
children: [
|
|
20253
|
-
"Your browser would not let us copy it. Paste these two lines into",
|
|
20254
|
-
" ",
|
|
20255
|
-
chosen?.name ?? "your assistant",
|
|
20256
|
-
" — they are yours, and they will not be shown again."
|
|
20257
|
-
]
|
|
20258
|
-
}), (0, import_jsx_runtime.jsxs)("pre", {
|
|
20259
|
-
className: "ai-pre",
|
|
20307
|
+
(0, import_jsx_runtime.jsxs)("section", {
|
|
20308
|
+
className: "ai-connect",
|
|
20309
|
+
children: [(0, import_jsx_runtime.jsx)("h2", {
|
|
20310
|
+
className: "ai-connect-head",
|
|
20311
|
+
children: "Connect it"
|
|
20312
|
+
}), !served.length ? (0, import_jsx_runtime.jsx)(NotOnline, {}) : (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [asks ? (0, import_jsx_runtime.jsx)("div", {
|
|
20313
|
+
className: "where-grid",
|
|
20314
|
+
role: "group",
|
|
20315
|
+
"aria-label": "Where Clearotron is running",
|
|
20316
|
+
children: PLACES.map((p) => (0, import_jsx_runtime.jsxs)("button", {
|
|
20317
|
+
type: "button",
|
|
20318
|
+
className: "where-card",
|
|
20319
|
+
"data-place": p,
|
|
20320
|
+
"aria-pressed": p === active,
|
|
20321
|
+
onClick: () => {
|
|
20322
|
+
if (p !== active) {
|
|
20323
|
+
setPlace(p);
|
|
20324
|
+
setPicked(null);
|
|
20325
|
+
settle();
|
|
20326
|
+
}
|
|
20327
|
+
},
|
|
20328
|
+
children: [
|
|
20329
|
+
(0, import_jsx_runtime.jsx)("span", {
|
|
20330
|
+
className: p === active ? "radio radio-on" : "radio",
|
|
20331
|
+
"aria-hidden": "true"
|
|
20332
|
+
}),
|
|
20333
|
+
(0, import_jsx_runtime.jsx)(Icon, {
|
|
20334
|
+
name: WHERE[p].icon,
|
|
20335
|
+
size: 19
|
|
20336
|
+
}),
|
|
20337
|
+
WHERE[p].label
|
|
20338
|
+
]
|
|
20339
|
+
}, p))
|
|
20340
|
+
}) : null, active === null ? null : !here.length ? (0, import_jsx_runtime.jsx)(NotOnline, {}) : (0, import_jsx_runtime.jsxs)("div", {
|
|
20341
|
+
className: "ai-connect-grid",
|
|
20342
|
+
children: [(0, import_jsx_runtime.jsxs)("div", { children: [(0, import_jsx_runtime.jsx)("h3", {
|
|
20343
|
+
className: "section-title",
|
|
20344
|
+
children: "Select AI app"
|
|
20345
|
+
}), (0, import_jsx_runtime.jsx)("div", {
|
|
20346
|
+
className: "ai-apps",
|
|
20347
|
+
children: here.map((o) => (0, import_jsx_runtime.jsxs)("button", {
|
|
20348
|
+
type: "button",
|
|
20349
|
+
className: `pick-row ai-app${o.id === picked ? " pick-row-on" : ""}`,
|
|
20350
|
+
"data-id": o.id,
|
|
20351
|
+
"aria-pressed": o.id === picked,
|
|
20352
|
+
onClick: () => {
|
|
20353
|
+
if (o.id !== picked) {
|
|
20354
|
+
setPicked(o.id);
|
|
20355
|
+
settle();
|
|
20356
|
+
}
|
|
20357
|
+
},
|
|
20260
20358
|
children: [
|
|
20261
|
-
|
|
20262
|
-
|
|
20263
|
-
|
|
20359
|
+
(0, import_jsx_runtime.jsx)("span", {
|
|
20360
|
+
className: o.id === picked ? "radio radio-on" : "radio",
|
|
20361
|
+
"aria-hidden": "true"
|
|
20362
|
+
}),
|
|
20363
|
+
(0, import_jsx_runtime.jsxs)("span", {
|
|
20364
|
+
className: "ai-app-label",
|
|
20365
|
+
children: [(0, import_jsx_runtime.jsx)("span", {
|
|
20366
|
+
className: "ai-app-name",
|
|
20367
|
+
children: o.name
|
|
20368
|
+
}), o.sub ? (0, import_jsx_runtime.jsx)("span", {
|
|
20369
|
+
className: "ai-app-sub",
|
|
20370
|
+
children: o.sub
|
|
20371
|
+
}) : null]
|
|
20372
|
+
}),
|
|
20373
|
+
(0, import_jsx_runtime.jsx)("span", {
|
|
20374
|
+
className: "ai-app-go",
|
|
20375
|
+
children: (0, import_jsx_runtime.jsx)(Icon, {
|
|
20376
|
+
name: "chevron",
|
|
20377
|
+
size: 16
|
|
20378
|
+
})
|
|
20379
|
+
})
|
|
20264
20380
|
]
|
|
20265
|
-
})
|
|
20266
|
-
})
|
|
20267
|
-
|
|
20268
|
-
|
|
20269
|
-
|
|
20270
|
-
|
|
20271
|
-
|
|
20381
|
+
}, o.id))
|
|
20382
|
+
})] }), (0, import_jsx_runtime.jsxs)("div", {
|
|
20383
|
+
className: "ai-slot",
|
|
20384
|
+
"aria-live": "polite",
|
|
20385
|
+
style: slotHeight ? { minHeight: slotHeight } : void 0,
|
|
20386
|
+
children: [
|
|
20387
|
+
chosen ? (0, import_jsx_runtime.jsx)(StepsPanel, {
|
|
20388
|
+
offer: chosen,
|
|
20389
|
+
state: {
|
|
20390
|
+
copiedAt,
|
|
20391
|
+
landedAt,
|
|
20392
|
+
landed,
|
|
20393
|
+
revealedAt,
|
|
20394
|
+
revealed
|
|
20395
|
+
},
|
|
20396
|
+
onBlock: (i, text) => void copyBlock(i, text),
|
|
20397
|
+
onSecret: (i, c) => void press(i, c)
|
|
20398
|
+
}) : (0, import_jsx_runtime.jsx)("div", {
|
|
20399
|
+
className: "steps-panel steps-panel-empty",
|
|
20400
|
+
children: (0, import_jsx_runtime.jsxs)("span", {
|
|
20401
|
+
className: "steps-empty",
|
|
20402
|
+
children: [(0, import_jsx_runtime.jsx)(Icon, {
|
|
20403
|
+
name: "arrow-left",
|
|
20404
|
+
size: 16
|
|
20405
|
+
}), "Select AI to see instructions"]
|
|
20406
|
+
})
|
|
20407
|
+
}),
|
|
20408
|
+
failed ? (0, import_jsx_runtime.jsx)("p", {
|
|
20409
|
+
className: "ai-said ai-failed",
|
|
20410
|
+
children: failed
|
|
20411
|
+
}) : null,
|
|
20412
|
+
(0, import_jsx_runtime.jsx)("div", {
|
|
20413
|
+
className: "ai-probe",
|
|
20414
|
+
ref: probe,
|
|
20415
|
+
"aria-hidden": "true",
|
|
20416
|
+
children: here.map((o) => (0, import_jsx_runtime.jsx)(StepsPanel, {
|
|
20417
|
+
offer: o,
|
|
20418
|
+
measuring: true
|
|
20419
|
+
}, o.id))
|
|
20420
|
+
})
|
|
20421
|
+
]
|
|
20272
20422
|
})]
|
|
20273
|
-
})
|
|
20274
|
-
|
|
20275
|
-
(0, import_jsx_runtime.jsxs)("
|
|
20276
|
-
className: "ai-help",
|
|
20277
|
-
children: [
|
|
20278
|
-
|
|
20279
|
-
children:
|
|
20280
|
-
|
|
20281
|
-
|
|
20282
|
-
|
|
20283
|
-
|
|
20284
|
-
|
|
20285
|
-
|
|
20286
|
-
|
|
20287
|
-
(0, import_jsx_runtime.jsx)("em", { children: " “start a knockout for our new drinks name across the US”" }),
|
|
20288
|
-
", or",
|
|
20289
|
-
(0, import_jsx_runtime.jsx)("em", { children: " “why did you rate that one high?”" }),
|
|
20290
|
-
" — and it will do the same work you would do on these screens."
|
|
20291
|
-
] }),
|
|
20292
|
-
(0, import_jsx_runtime.jsx)("p", { children: "If a press does not finish, the most common reason is that your assistant runs somewhere this service cannot be reached from. The team who set this up can tell you in a sentence." }),
|
|
20293
|
-
(0, import_jsx_runtime.jsxs)("p", {
|
|
20294
|
-
className: "ai-help-doc",
|
|
20295
|
-
children: [(0, import_jsx_runtime.jsx)("a", {
|
|
20296
|
-
href: "/portal/connect-help",
|
|
20297
|
-
target: "_blank",
|
|
20298
|
-
rel: "noreferrer",
|
|
20299
|
-
children: "The full technical instructions"
|
|
20300
|
-
}), " — written for an engineer, or for an assistant reading on your behalf."]
|
|
20301
|
-
})
|
|
20302
|
-
]
|
|
20303
|
-
})]
|
|
20423
|
+
})] })]
|
|
20424
|
+
}),
|
|
20425
|
+
(0, import_jsx_runtime.jsxs)("div", {
|
|
20426
|
+
className: "notice quiet ai-help",
|
|
20427
|
+
children: [
|
|
20428
|
+
(0, import_jsx_runtime.jsx)("strong", { children: "If it doesn’t connect" }),
|
|
20429
|
+
(0, import_jsx_runtime.jsx)("p", { children: "Point your AI at the full technical setup instructions to diagnose." }),
|
|
20430
|
+
(0, import_jsx_runtime.jsx)("p", { children: (0, import_jsx_runtime.jsxs)("a", {
|
|
20431
|
+
href: HELP_URL,
|
|
20432
|
+
target: "_blank",
|
|
20433
|
+
rel: "noreferrer",
|
|
20434
|
+
children: [HELP_LINK_TEXT, " ↗"]
|
|
20435
|
+
}) })
|
|
20436
|
+
]
|
|
20304
20437
|
})
|
|
20305
20438
|
]
|
|
20306
20439
|
});
|
|
@@ -22124,7 +22257,8 @@ function useSourceRepo() {
|
|
|
22124
22257
|
function PeopleAccess({ ctx }) {
|
|
22125
22258
|
const { result } = useLoad(() => api.adminAccess(), []);
|
|
22126
22259
|
const repo = useSourceRepo();
|
|
22127
|
-
const
|
|
22260
|
+
const seesAll = ctx.me.allAccounts;
|
|
22261
|
+
const { result: observed } = useLoad(() => seesAll ? api.adminObserved() : Promise.resolve({ kind: "notFound" }), [seesAll]);
|
|
22128
22262
|
if (result && result.kind !== "ok") return (0, import_jsx_runtime.jsx)("div", {
|
|
22129
22263
|
className: "screen",
|
|
22130
22264
|
children: (0, import_jsx_runtime.jsxs)("div", {
|