@zackbart/connecta 0.33.0 → 0.34.1
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 +65 -0
- package/README.md +100 -128
- package/SECURITY.md +1 -1
- package/bin/version.mjs +1 -1
- package/dist/activity.d.ts +3 -0
- package/dist/branding.d.ts +7 -0
- package/dist/branding.js +76 -9
- package/dist/catalog-drift.d.ts +30 -26
- package/dist/catalog-drift.js +169 -84
- package/dist/catalog-service.js +16 -2
- package/dist/config-value-sources.js +6 -1
- package/dist/config.d.ts +13 -2
- package/dist/config.js +36 -2
- package/dist/connector-caller.js +2 -1
- package/dist/connectors/api-connector.d.ts +3 -0
- package/dist/connectors/api-connector.js +5 -1
- package/dist/connectors/option-shapes.js +1 -1
- package/dist/connectors/remote-mcp.d.ts +2 -0
- package/dist/connectors/remote-mcp.js +5 -1
- package/dist/describe-config.d.ts +5 -1
- package/dist/describe-config.js +2 -0
- package/dist/execute.js +1 -11
- package/dist/fix-prompt.js +2 -2
- package/dist/index.js +1 -0
- package/dist/invocation.js +3 -2
- package/dist/membership.d.ts +2 -0
- package/dist/meta-tools.js +3 -2
- package/dist/oauth-callback-outcome.js +2 -2
- package/dist/operator-ui/agents.d.ts +1 -1
- package/dist/operator-ui/agents.js +16 -16
- package/dist/operator-ui/config-summary.js +565 -0
- package/dist/operator-ui/connection-map.js +376 -0
- package/dist/operator-ui/endpoints.js +45 -16
- package/dist/operator-ui/fix-prompts.js +1 -1
- package/dist/operator-ui/generated.js +4 -4
- package/dist/operator-ui/health.js +52 -0
- package/dist/operator-ui/member-page.js +13 -28
- package/dist/operator-ui/overview.js +123 -0
- package/dist/operator-ui/view.d.ts +26 -22
- package/dist/operator-ui/view.js +130 -96
- package/dist/page-styles.js +5 -3
- package/dist/provider.d.ts +6 -1
- package/dist/provider.js +18 -1
- package/dist/providers/_shared/google/workspace.d.ts +9 -4
- package/dist/providers/_shared/google/workspace.js +7 -3
- package/dist/providers/basecamp/index.d.ts +2 -0
- package/dist/providers/breeze/index.d.ts +2 -0
- package/dist/providers/ccb/index.d.ts +2 -0
- package/dist/providers/ccb/index.js +2 -2
- package/dist/providers/cloudflare/index.d.ts +2 -0
- package/dist/providers/cloudflare/index.js +5 -1
- package/dist/providers/cloudflare/openapi.generated.js +3296 -3206
- package/dist/providers/cloudflare/rest.js +19 -0
- package/dist/providers/cloudflare/skill.generated.js +2 -2
- package/dist/providers/cloudflare/value-safety.js +51 -18
- package/dist/providers/docs/index.js +1 -1
- package/dist/providers/docs/skill.generated.js +2 -2
- package/dist/providers/drive/index.js +1 -1
- package/dist/providers/drive/skill.generated.js +2 -2
- package/dist/providers/forms/index.js +1 -1
- package/dist/providers/forms/skill.generated.js +2 -2
- package/dist/providers/gmail/index.js +1 -1
- package/dist/providers/gmail/skill.generated.js +2 -2
- package/dist/providers/intercom/index.d.ts +24 -0
- package/dist/providers/intercom/index.js +121 -0
- package/dist/providers/intercom/skill.generated.js +8 -0
- package/dist/providers/linear/index.js +204 -19
- package/dist/providers/linear/skill.generated.js +2 -2
- package/dist/providers/mixpanel/index.d.ts +2 -0
- package/dist/providers/mixpanel/index.js +21 -17
- package/dist/providers/mixpanel/skill.generated.js +3 -3
- package/dist/providers/notion/index.d.ts +2 -0
- package/dist/providers/notion/index.js +1 -1
- package/dist/providers/notion/skill.generated.js +1 -1
- package/dist/providers/overflow/index.d.ts +2 -0
- package/dist/providers/overflow/index.js +1 -1
- package/dist/providers/overflow/skill.generated.js +2 -2
- package/dist/providers/planning-center/index.d.ts +2 -0
- package/dist/providers/planning-center/index.js +1 -1
- package/dist/providers/planning-center/skill.generated.js +4 -4
- package/dist/providers/revenuecat/index.d.ts +5 -3
- package/dist/providers/revenuecat/index.js +147 -7
- package/dist/providers/revenuecat/skill.generated.js +3 -3
- package/dist/providers/sheets/index.js +1 -1
- package/dist/providers/sheets/skill.generated.js +2 -2
- package/dist/providers/slides/index.js +1 -1
- package/dist/providers/slides/skill.generated.js +2 -2
- package/dist/providers/stripe/index.d.ts +2 -0
- package/dist/providers/stripe/index.js +50 -30
- package/dist/providers/stripe/skill.generated.js +2 -1
- package/dist/providers/tithely/index.d.ts +2 -0
- package/dist/providers/tithely/index.js +1 -1
- package/dist/providers/vercel/index.d.ts +2 -0
- package/dist/providers/vercel/index.js +2 -2
- package/dist/providers/vercel/openapi.generated.js +391 -374
- package/dist/providers/vercel/skill.generated.js +2 -2
- package/dist/providers/vercel/value-safety.js +14 -4
- package/dist/registry.d.ts +10 -14
- package/dist/registry.js +77 -62
- package/dist/routes/mcp.js +20 -13
- package/dist/routes/oauth.js +2 -2
- package/dist/routes/ui-data.js +8 -2
- package/dist/skills.js +18 -2
- package/dist/storage/sql.js +5 -1
- package/dist/types.d.ts +36 -11
- package/dist/ui.js +9 -4
- package/dist/usage-guide.js +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/documentation/README.md +2 -2
- package/documentation/architecture.md +66 -18
- package/documentation/auth.md +183 -67
- package/documentation/code-mode.md +30 -10
- package/documentation/deploying.md +5 -1
- package/documentation/integrating.md +64 -7
- package/documentation/meta-tools.md +38 -24
- package/documentation/migration-0.33.md +21 -13
- package/documentation/migration-0.34.md +67 -0
- package/documentation/operating.md +1 -1
- package/documentation/operator-tests.md +52 -20
- package/documentation/operator-ui.md +341 -104
- package/documentation/provider-auth-migration.md +22 -0
- package/examples/worker/AGENTS.md +15 -9
- package/examples/worker/README.md +41 -14
- package/examples/worker/src/connecta.config.ts +5 -4
- package/examples/worker/wrangler.jsonc +1 -1
- package/package.json +23 -19
- package/templates/node/AGENTS.md +13 -7
- package/templates/node/README.md +14 -11
- package/templates/node/package.json +1 -1
- package/templates/node/src/connecta.config.ts +2 -2
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The next steady evidence. A settled connector takes its current row; one
|
|
3
|
+
* being read again keeps its previous evidence when this identity has any.
|
|
4
|
+
* Returns `previous` itself when nothing changed, so it can live in React
|
|
5
|
+
* state. A new identity starts empty.
|
|
6
|
+
*/
|
|
7
|
+
export function steadyHealth(state, previous) {
|
|
8
|
+
const same = previous?.generation === state.generation ? previous : null;
|
|
9
|
+
const contract = state.contract?.role === "maintainer" && state.data ? state.contract : null;
|
|
10
|
+
// No contract on screen: keep what was shown until the next one arrives.
|
|
11
|
+
if (!contract || !state.data)
|
|
12
|
+
return same ?? { generation: state.generation, rows: Object.create(null) };
|
|
13
|
+
const reading = new Set(state.data.connectors.filter((c) => c.status === "loading").map((c) => c.id));
|
|
14
|
+
const held = same?.rows ?? Object.create(null);
|
|
15
|
+
const rows = Object.create(null);
|
|
16
|
+
let changed = !same || Object.keys(held).length !== contract.live.connectors.length;
|
|
17
|
+
for (const live of contract.live.connectors) {
|
|
18
|
+
const before = Object.hasOwn(held, live.id) ? held[live.id] : undefined;
|
|
19
|
+
if (before && reading.has(live.id)) {
|
|
20
|
+
rows[live.id] = before;
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
const failed = Object.hasOwn(state.connectorFailures, live.id) && Boolean(state.connectorFailures[live.id]);
|
|
24
|
+
if (before?.live === live && before.failed === failed)
|
|
25
|
+
rows[live.id] = before;
|
|
26
|
+
else {
|
|
27
|
+
rows[live.id] = { live, failed };
|
|
28
|
+
changed = true;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return changed ? { generation: state.generation, rows } : same;
|
|
32
|
+
}
|
|
33
|
+
/** The contract each view renders health from, with every live row replaced by its steady evidence. */
|
|
34
|
+
export function shownHealth(contract, health) {
|
|
35
|
+
const signals = Object.create(null);
|
|
36
|
+
if (!contract)
|
|
37
|
+
return { contract, signals };
|
|
38
|
+
let replaced = false;
|
|
39
|
+
const connectors = contract.live.connectors.map((live) => {
|
|
40
|
+
const row = Object.hasOwn(health.rows, live.id) ? health.rows[live.id] : undefined;
|
|
41
|
+
if (row?.failed)
|
|
42
|
+
signals[live.id] = { failed: true };
|
|
43
|
+
if (!row || row.live === live)
|
|
44
|
+
return live;
|
|
45
|
+
replaced = true;
|
|
46
|
+
return row.live;
|
|
47
|
+
});
|
|
48
|
+
return {
|
|
49
|
+
contract: replaced ? { ...contract, live: { ...contract.live, connectors } } : contract,
|
|
50
|
+
signals,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
@@ -35,23 +35,17 @@ function controlsFor(manage, connection) {
|
|
|
35
35
|
}
|
|
36
36
|
return [];
|
|
37
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* A few words under the account's name, only where the badge alone would
|
|
40
|
+
* leave something out: a saved credential that no longer fits, or one saved
|
|
41
|
+
* but not working.
|
|
42
|
+
*/
|
|
38
43
|
function summaryFor(manage, connection) {
|
|
39
|
-
if (manage.kind
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
return "Your saved credential no longer fits. Replace it.";
|
|
45
|
-
return connection.state === "ok" ? "Your credential is saved." : "Your credential is saved, but it isn't working.";
|
|
46
|
-
}
|
|
47
|
-
if (connection.state === "ok")
|
|
48
|
-
return "Connected with your account.";
|
|
49
|
-
if (connection.state === "auth_required") {
|
|
50
|
-
return manage.kind === "oauth" && manage.actions.includes("connect")
|
|
51
|
-
? "Not connected. Its tools won't work for you until you connect."
|
|
52
|
-
: "Not connected.";
|
|
53
|
-
}
|
|
54
|
-
return "Unavailable right now.";
|
|
44
|
+
if (manage.kind !== "credential" || !credentialStored(manage))
|
|
45
|
+
return null;
|
|
46
|
+
if (connection.problem === "credential_mismatch")
|
|
47
|
+
return "Saved credential no longer fits";
|
|
48
|
+
return connection.state === "ok" ? null : "Saved, but not working";
|
|
55
49
|
}
|
|
56
50
|
const toolCount = (connector) => connector.tools.length;
|
|
57
51
|
export function memberPage(contract) {
|
|
@@ -94,19 +88,10 @@ export function toolCountLabel(count) {
|
|
|
94
88
|
/** The in-page question before a member's action that takes something away. */
|
|
95
89
|
export function memberConfirmCopy(action, name) {
|
|
96
90
|
if (action === "oauth_restart") {
|
|
97
|
-
return {
|
|
98
|
-
question: `Reconnect ${name}? Your current connection stops working until you finish authorizing in the new tab.`,
|
|
99
|
-
confirm: "Reconnect",
|
|
100
|
-
};
|
|
91
|
+
return { question: `Reconnect ${name}? It stops working until you finish in the new tab.`, confirm: "Reconnect" };
|
|
101
92
|
}
|
|
102
93
|
if (action === "oauth_disconnect") {
|
|
103
|
-
return {
|
|
104
|
-
question: `Disconnect your ${name} account? Its tools stop working for you until you connect again.`,
|
|
105
|
-
confirm: "Disconnect",
|
|
106
|
-
};
|
|
94
|
+
return { question: `Disconnect your ${name} account? Its tools stop working for you.`, confirm: "Disconnect" };
|
|
107
95
|
}
|
|
108
|
-
return {
|
|
109
|
-
question: `Clear your ${name} credential? Its tools stop working for you until you add one again.`,
|
|
110
|
-
confirm: "Clear",
|
|
111
|
-
};
|
|
96
|
+
return { question: `Clear your ${name} credential? Its tools stop working for you.`, confirm: "Clear" };
|
|
112
97
|
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { endpointRows } from "./endpoints.js";
|
|
2
|
+
import { joinList } from "./connection-map.js";
|
|
3
|
+
import { connectorVerdict } from "./view.js";
|
|
4
|
+
const PROBLEM_TITLE = {
|
|
5
|
+
connector_unavailable: "is unavailable",
|
|
6
|
+
oauth_required: "needs authorization",
|
|
7
|
+
credential_required: "needs a credential",
|
|
8
|
+
auth_required: "needs a secret in the deployment",
|
|
9
|
+
credential_mismatch: "can't use its saved credential",
|
|
10
|
+
catalog_failed: "couldn't load its tools",
|
|
11
|
+
};
|
|
12
|
+
function affects(paths) {
|
|
13
|
+
return paths.length ? `Affects ${joinList(paths)}` : "No endpoint serves it";
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* One row per connector that is not healthy, in config order, then one per
|
|
17
|
+
* agent that sits in an endpoint without a working token. Each row carries
|
|
18
|
+
* the fix the rest of the UI already offers for it.
|
|
19
|
+
*/
|
|
20
|
+
export function attentionItems(contract, options = {}) {
|
|
21
|
+
if (contract.role !== "maintainer")
|
|
22
|
+
return [];
|
|
23
|
+
const rows = endpointRows(contract);
|
|
24
|
+
const connectors = [];
|
|
25
|
+
for (const config of contract.config?.connectors ?? []) {
|
|
26
|
+
const live = contract.live.connectors.find((c) => c.id === config.id);
|
|
27
|
+
if (!live)
|
|
28
|
+
continue;
|
|
29
|
+
const signals = options.signals && Object.hasOwn(options.signals, config.id) ? options.signals[config.id] : {};
|
|
30
|
+
const verdict = connectorVerdict(live, signals);
|
|
31
|
+
if ((verdict.tone !== "warn" && verdict.tone !== "danger") || !verdict.action)
|
|
32
|
+
continue;
|
|
33
|
+
const title = config.title ?? config.id;
|
|
34
|
+
const id = encodeURIComponent(config.id);
|
|
35
|
+
const paths = rows.filter((row) => row.groups.some((group) => group.config.id === config.id)).map((r) => r.path);
|
|
36
|
+
const connection = `/connectors/${id}#connection`;
|
|
37
|
+
const base = {
|
|
38
|
+
key: `connector:${config.id}`,
|
|
39
|
+
kind: "connector",
|
|
40
|
+
tone: verdict.tone,
|
|
41
|
+
subject: title,
|
|
42
|
+
action: { label: verdict.action, href: connection, ariaLabel: `${verdict.action} ${title}` },
|
|
43
|
+
href: connection,
|
|
44
|
+
};
|
|
45
|
+
// The server's problem code outranks a failed read on this page: the row
|
|
46
|
+
// keeps its fix prompt and says the details didn't load. "Unavailable"
|
|
47
|
+
// beside a failed read is the page's own (see connectorVerdict).
|
|
48
|
+
const reported = live.problem ?? (live.status === "error" ? "connector_unavailable" : undefined);
|
|
49
|
+
const problem = signals.failed && reported === "connector_unavailable" ? undefined : reported;
|
|
50
|
+
if (problem) {
|
|
51
|
+
connectors.push({
|
|
52
|
+
...base,
|
|
53
|
+
problem: PROBLEM_TITLE[problem],
|
|
54
|
+
body: signals.failed ? `Details didn't load · ${affects(paths)}` : affects(paths),
|
|
55
|
+
fix: { kind: problem, connectorId: config.id },
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
else if (signals.failed) {
|
|
59
|
+
connectors.push({
|
|
60
|
+
...base,
|
|
61
|
+
problem: "didn't load on this page",
|
|
62
|
+
body: affects(paths),
|
|
63
|
+
fix: null,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
else if (live.status !== "ok") {
|
|
67
|
+
connectors.push({
|
|
68
|
+
...base,
|
|
69
|
+
problem: verdict.label === "Authorization needed" ? "needs authorization" : "isn't connected",
|
|
70
|
+
body: affects(paths),
|
|
71
|
+
fix: null,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
const agents = contract.agents
|
|
76
|
+
.filter((agent) => agent.pools.length && agent.token.state !== "issued")
|
|
77
|
+
.map((agent) => {
|
|
78
|
+
// An agent connects only at a pool's agent URL.
|
|
79
|
+
const paths = agent.pools.map((name) => contract.pools.find((pool) => pool.name === name)?.agentPath ?? `/agent/${name}`);
|
|
80
|
+
const revoked = agent.token.state === "revoked";
|
|
81
|
+
return {
|
|
82
|
+
key: `agent:${agent.name}`,
|
|
83
|
+
kind: "agent",
|
|
84
|
+
tone: "warn",
|
|
85
|
+
subject: agent.name,
|
|
86
|
+
problem: revoked ? "has a revoked token" : "has no token",
|
|
87
|
+
body: `Can't connect at ${joinList(paths)}`,
|
|
88
|
+
action: options.tokensPage
|
|
89
|
+
? { label: "Issue token", href: "/tokens", ariaLabel: `Issue a token for ${agent.name}` }
|
|
90
|
+
: null,
|
|
91
|
+
href: options.tokensPage ? "/tokens" : null,
|
|
92
|
+
fix: null,
|
|
93
|
+
};
|
|
94
|
+
});
|
|
95
|
+
// Severity changes as individual details settle. Config order keeps surviving
|
|
96
|
+
// rows in place without waiting for the slowest connector's read.
|
|
97
|
+
return [...connectors, ...agents];
|
|
98
|
+
}
|
|
99
|
+
/** The numbers above the list, counted from the same map the page draws. */
|
|
100
|
+
export function overviewHeadline(contract, map, items, signals = {}) {
|
|
101
|
+
const bar = (contract.config?.connectors ?? []).flatMap((config) => {
|
|
102
|
+
const live = contract.live.connectors.find((c) => c.id === config.id);
|
|
103
|
+
if (!live)
|
|
104
|
+
return [];
|
|
105
|
+
const health = connectorVerdict(live, Object.hasOwn(signals, config.id) ? signals[config.id] : undefined);
|
|
106
|
+
return [{ id: config.id, title: config.title ?? config.id, tone: health.tone, label: health.label }];
|
|
107
|
+
});
|
|
108
|
+
const healthy = bar.filter((entry) => entry.tone === "ok").length;
|
|
109
|
+
const warn = bar.filter((entry) => entry.tone === "warn").length;
|
|
110
|
+
const danger = bar.filter((entry) => entry.tone === "danger").length;
|
|
111
|
+
const count = (kind) => map.nodes.filter((node) => node.kind === kind).length;
|
|
112
|
+
return {
|
|
113
|
+
connectors: bar.length,
|
|
114
|
+
healthy,
|
|
115
|
+
warn,
|
|
116
|
+
danger,
|
|
117
|
+
bar,
|
|
118
|
+
endpoints: count("endpoint"),
|
|
119
|
+
readOnlyEndpoints: map.nodes.filter((node) => node.kind === "endpoint" && node.readOnly).length,
|
|
120
|
+
people: count("person"),
|
|
121
|
+
agents: contract.agents.length,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
@@ -4,16 +4,7 @@ import type { CredentialManagementCapability, UiConnector, UiData, UiProblem } f
|
|
|
4
4
|
import type { FixPromptKind } from "./fix-prompts.js";
|
|
5
5
|
import type { AgentSlot } from "./agents.js";
|
|
6
6
|
export declare function registrationPathLabel(path: NonNullable<UiConnector["registrationPath"]>): string;
|
|
7
|
-
|
|
8
|
-
* A connector's source column: the maintained provider with the
|
|
9
|
-
* implementation it uses, since a dual provider's `auth` selects either the
|
|
10
|
-
* vendor's hosted MCP server or Connecta's REST connector.
|
|
11
|
-
*/
|
|
12
|
-
export declare function connectorSourceLabel(source: {
|
|
13
|
-
kind: string;
|
|
14
|
-
provider?: string;
|
|
15
|
-
}): string;
|
|
16
|
-
export type OperatorPage = "endpoints" | "settings" | "connector" | "tokens" | "connections" | "activity";
|
|
7
|
+
export type OperatorPage = "overview" | "endpoints" | "settings" | "connector" | "tokens" | "connections" | "activity";
|
|
17
8
|
/** Pages the nav lists, in dashboard order. */
|
|
18
9
|
export declare const OPERATOR_PAGES: readonly OperatorPage[];
|
|
19
10
|
export declare const PAGE_META: Readonly<Record<OperatorPage, {
|
|
@@ -134,7 +125,7 @@ export declare function credentialTestNotice(connectorId: string, answer: {
|
|
|
134
125
|
*/
|
|
135
126
|
export declare function refusedNotice(action: DownstreamAction, connectorId: string, problem?: unknown): Notice;
|
|
136
127
|
/** An action whose permission or target changed before it was sent. */
|
|
137
|
-
export declare const STALE_COPY = "This changed before
|
|
128
|
+
export declare const STALE_COPY = "This changed before sending, so nothing was sent. Try again.";
|
|
138
129
|
/**
|
|
139
130
|
* Every row action's failure, in one voice. The page's own failures — a
|
|
140
131
|
* lapsed session, a denied identity, a dropped connection — read the same for
|
|
@@ -327,12 +318,30 @@ export declare function problemCopy(problem: UiProblem | undefined): string | nu
|
|
|
327
318
|
* error. The two used to share the red box, so the row contradicted itself.
|
|
328
319
|
*/
|
|
329
320
|
export declare function problemTone(problem: UiProblem): "warn" | "danger";
|
|
321
|
+
/** What the page knows about a connector beyond its live status: a failed detail read. */
|
|
322
|
+
export interface ConnectorSignals {
|
|
323
|
+
failed?: boolean;
|
|
324
|
+
}
|
|
325
|
+
/** One connector's health everywhere it is shown: badge tone, status word, and the one action beside it. */
|
|
326
|
+
export interface ConnectorVerdict {
|
|
327
|
+
tone: "ok" | "warn" | "danger" | "neutral";
|
|
328
|
+
label: string;
|
|
329
|
+
/** The link to the Connection tab, or null when the connector is fine. */
|
|
330
|
+
action: "Connect" | "Replace key" | "Inspect" | null;
|
|
331
|
+
}
|
|
330
332
|
/**
|
|
331
|
-
*
|
|
332
|
-
*
|
|
333
|
-
*
|
|
333
|
+
* The verdict the Connectors list, the Overview, Endpoints and a connector's
|
|
334
|
+
* page all show. The server's problem code comes first, then a failed detail
|
|
335
|
+
* read on this page, then a non-ok status. Catalog drift is informational. A problem
|
|
336
|
+
* outranks the status, so a connector whose catalog failed is never
|
|
337
|
+
* "Connected". A failed read marks its connector `connector_unavailable` in
|
|
338
|
+
* the store, so that one code beside a failed read is the page's own and
|
|
339
|
+
* reads "Couldn't load" instead of blaming the downstream.
|
|
334
340
|
*/
|
|
335
|
-
export declare function
|
|
341
|
+
export declare function connectorVerdict(live: {
|
|
342
|
+
status: string;
|
|
343
|
+
problem?: UiProblem;
|
|
344
|
+
}, signals?: ConnectorSignals): ConnectorVerdict;
|
|
336
345
|
/**
|
|
337
346
|
* Hosted-provider catalog drift, as an operator reads it
|
|
338
347
|
* ([#343](https://github.com/zackbart/connecta/issues/343)).
|
|
@@ -378,6 +387,8 @@ export declare function activityOutcomeBadge(outcome: string): {
|
|
|
378
387
|
label: string;
|
|
379
388
|
tone: Tone;
|
|
380
389
|
};
|
|
390
|
+
/** Why a call stalled or failed, in words; "" when nothing was recorded. */
|
|
391
|
+
export declare function activityReason(event: UiActivityEvent): string;
|
|
381
392
|
/** The one-line detail under an address: where it ran, retries, and why it stalled. */
|
|
382
393
|
export declare function activityDetail(event: UiActivityEvent): string;
|
|
383
394
|
/**
|
|
@@ -385,13 +396,6 @@ export declare function activityDetail(event: UiActivityEvent): string;
|
|
|
385
396
|
* beside it is not shown: it can carry a vault's own words.
|
|
386
397
|
*/
|
|
387
398
|
export declare function credentialProblemCopy(problem: string | undefined): string;
|
|
388
|
-
export declare function credentialStateLabel(credential: {
|
|
389
|
-
configured: boolean | null;
|
|
390
|
-
problem?: string;
|
|
391
|
-
fields?: unknown[];
|
|
392
|
-
lastFour?: string;
|
|
393
|
-
updatedAt?: string;
|
|
394
|
-
}): string;
|
|
395
399
|
/** Gate copy for each browser-auth shape, so the sign-in state is never a blank page. */
|
|
396
400
|
export declare function gateCopy(kind: string, signedIn: boolean): string;
|
|
397
401
|
export {};
|