ankka-console 0.11.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/ankka-mark.png +0 -0
  2. package/dist/client/control-plane.d.ts +63 -1
  3. package/dist/client/control-plane.js +142 -1
  4. package/dist/client/schemas.d.ts +1460 -2
  5. package/dist/client/schemas.js +462 -2
  6. package/dist/context.d.ts +1 -1
  7. package/dist/context.js +1 -1
  8. package/dist/extensions/types.d.ts +1 -1
  9. package/dist/extensions/types.js +22 -0
  10. package/dist/routes/front.d.ts +76 -2
  11. package/dist/routes/front.js +37 -8
  12. package/dist/routes/logs.d.ts +67 -0
  13. package/dist/routes/machines.d.ts +78 -0
  14. package/dist/routes/machines.js +78 -0
  15. package/dist/routes/organization.d.ts +29 -1
  16. package/dist/routes/organization.js +27 -5
  17. package/dist/routes/project.d.ts +285 -1
  18. package/dist/routes/project.js +107 -6
  19. package/dist/routes/service-history.d.ts +2 -0
  20. package/dist/routes/service-history.js +3 -0
  21. package/dist/routes/service-topology.d.ts +67 -0
  22. package/dist/routes/service.d.ts +67 -0
  23. package/dist/routes/service.js +64 -4
  24. package/dist/routes.js +1 -0
  25. package/dist/runtime.d.ts +3 -1
  26. package/dist/runtime.js +1 -0
  27. package/dist/styles.css +1 -1
  28. package/dist/testing/fake-control-plane.d.ts +193 -1
  29. package/dist/testing/fake-control-plane.js +840 -7
  30. package/dist/ui/buckets.d.ts +14 -0
  31. package/dist/ui/buckets.js +9 -0
  32. package/dist/ui/grants.d.ts +3 -0
  33. package/dist/ui/grants.js +13 -0
  34. package/dist/ui/shell.d.ts +1 -1
  35. package/dist/ui/shell.js +14 -3
  36. package/dist/ui/topology/Table.d.ts +8 -0
  37. package/dist/ui/topology/Table.js +8 -1
  38. package/dist/ui/use-stream.d.ts +134 -0
  39. package/package.json +1 -1
@@ -0,0 +1,14 @@
1
+ import type { BucketReport } from "../client/schemas.ts";
2
+ /** One row of a service's named buckets, as the service page shows it (feature 055). */
3
+ export interface BucketRow {
4
+ name: string;
5
+ /** The exposure, `supplied` for a bucket the developer made, or `kept` for one no longer named. */
6
+ exposure: string;
7
+ /** Its name in the store, when reported. */
8
+ bucket: string | null;
9
+ /** Where it is on the internet, as a link, when it is. */
10
+ address: string | null;
11
+ /** Said of a bucket the descriptor no longer names, which is kept rather than deleted. */
12
+ note: string | null;
13
+ }
14
+ export declare function bucketRows(buckets: readonly BucketReport[] | null | undefined): BucketRow[];
@@ -0,0 +1,9 @@
1
+ export function bucketRows(buckets) {
2
+ return (buckets ?? []).map((b) => ({
3
+ name: b.name,
4
+ exposure: b.kept ? "kept" : b.phase === "Supplied" || b.exposure === "supplied" ? "supplied" : b.exposure,
5
+ bucket: b.bucket ?? null,
6
+ address: b.kept ? null : (b.publicAddress ?? null),
7
+ note: b.kept ? "kept, no longer named" : null,
8
+ }));
9
+ }
@@ -0,0 +1,3 @@
1
+ import type { GrantTarget } from "../client/schemas.ts";
2
+ /** A grant's target in one line, as the CLI shows it: `route wallet POST /v1/…`, `topic casino.players consume`. */
3
+ export declare function targetText(t: GrantTarget): string;
@@ -0,0 +1,13 @@
1
+ /** A grant's target in one line, as the CLI shows it: `route wallet POST /v1/…`, `topic casino.players consume`. */
2
+ export function targetText(t) {
3
+ switch (t.kind) {
4
+ case "route":
5
+ return `route ${t.service ?? ""} ${t.method ?? ""} ${t.path ?? ""}`;
6
+ case "method":
7
+ return `method ${t.service ?? ""} ${t.method ?? ""}`;
8
+ case "topic":
9
+ return `topic ${t.topic ?? ""} ${t.right ?? ""}${t.decrypt ? " decrypt" : ""}`;
10
+ default:
11
+ return t.kind;
12
+ }
13
+ }
@@ -35,7 +35,7 @@ export declare function Bar({ wordmark, children, end }: {
35
35
  end?: ReactNode;
36
36
  }): import("react").JSX.Element;
37
37
  /**
38
- * The rail: the console's areas, the one the page belongs to marked. Members and deploy tokens open
38
+ * The rail: the console's areas, the one the page belongs to marked. Members, deploy tokens and machines open
39
39
  * those of the organization the page belongs to; with no organization in view they are shown and
40
40
  * unavailable. Signing out is at its foot.
41
41
  */
package/dist/ui/shell.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { clsx } from "clsx";
3
- import { Box, Building2, Folder, KeyRound, LogOut, Plus, Users } from "lucide-react";
3
+ import { Bot, Box, Building2, Folder, KeyRound, LogOut, Plus, Users } from "lucide-react";
4
4
  import { Breadcrumbs, ConsoleForm, ConsoleLink, useConsole } from "./console.js";
5
5
  import { Lifecycle } from "./status.js";
6
6
  import { button } from "./primitives/button.js";
@@ -15,8 +15,12 @@ export function Shell({ children, className, theme = "dark" }) {
15
15
  export function Backdrop() {
16
16
  return _jsx("div", { className: "ac-backdrop", "aria-hidden": "true" });
17
17
  }
18
+ /**
19
+ * The mark: the duck, as a mask over the current colour, so it follows `--ac-color-ink` and a host's
20
+ * override of it in either theme with one asset. The build copies the image beside the stylesheet.
21
+ */
18
22
  function Mark() {
19
- return (_jsxs("svg", { viewBox: "0 0 36 36", width: "32", height: "32", fill: "none", "aria-hidden": "true", children: [_jsx("path", { d: "M8 24c0-7 5-12 10-12s10 5 10 12", stroke: "currentColor", strokeWidth: "2.2", strokeLinecap: "round" }), _jsx("path", { d: "M14 24h8", stroke: "currentColor", strokeWidth: "2.2", strokeLinecap: "round" }), _jsx("circle", { cx: "18", cy: "9", r: "2.2", fill: "var(--ac-color-amber)" })] }));
23
+ return _jsx("span", { className: "ac-mark-image", "aria-hidden": "true" });
20
24
  }
21
25
  const initials = (name) => name
22
26
  .split(/[\s@.]+/)
@@ -37,7 +41,7 @@ export function Bar({ wordmark, children, end }) {
37
41
  (name ? (_jsxs("span", { className: "ac-person", title: name, children: [_jsx("span", { "aria-hidden": "true", children: initials(name) }), _jsxs("span", { className: "ac-visually-hidden", children: ["You are ", name] })] })) : null)] })] }));
38
42
  }
39
43
  /**
40
- * The rail: the console's areas, the one the page belongs to marked. Members and deploy tokens open
44
+ * The rail: the console's areas, the one the page belongs to marked. Members, deploy tokens and machines open
41
45
  * those of the organization the page belongs to; with no organization in view they are shown and
42
46
  * unavailable. Signing out is at its foot.
43
47
  */
@@ -64,6 +68,13 @@ export function Rail() {
64
68
  to: orgPath && org?.manages ? `${orgPath}/tokens` : undefined,
65
69
  unavailable: org ? "Deploy tokens: only an owner manages them" : "Deploy tokens: open an organization first",
66
70
  },
71
+ {
72
+ area: "machines",
73
+ label: org ? `Machines of ${org.name}` : "Machines",
74
+ icon: Bot,
75
+ to: orgPath && `${orgPath}/machines`,
76
+ unavailable: "Machines: open an organization first",
77
+ },
67
78
  ];
68
79
  return (_jsxs("nav", { className: "ac-rail", "aria-label": "Console", children: [_jsx(ConsoleLink, { to: "", className: "ac-mark", "aria-label": "ankka console", title: "ankka console", children: _jsx(Mark, {}) }), _jsx("ul", { className: "ac-rail-areas", children: entries.map((e) => {
69
80
  const Icon = e.icon;
@@ -3,6 +3,14 @@
3
3
  * read. Handled and unanswered are separate columns, because they are separate facts.
4
4
  */
5
5
  import type { Pair, View } from "./layout.ts";
6
+ /**
7
+ * A handler as the table names it: a tool, an agent's or an MCP endpoint's, is marked with a tool
8
+ * glyph and the word, so an MCP endpoint's tools read apart from its routes, to a screen reader too.
9
+ */
10
+ export declare function handlerInWords(h: {
11
+ name: string;
12
+ type: string;
13
+ }): string;
6
14
  export declare function duration(pair: Pair): string;
7
15
  export declare function Table({ shown, differs }: {
8
16
  shown: View;
@@ -5,10 +5,17 @@ function nameOf(shown, id) {
5
5
  function kindInWords(kind) {
6
6
  return kind.replace(/([a-z])([A-Z])/g, "$1 $2").toLowerCase();
7
7
  }
8
+ /**
9
+ * A handler as the table names it: a tool, an agent's or an MCP endpoint's, is marked with a tool
10
+ * glyph and the word, so an MCP endpoint's tools read apart from its routes, to a screen reader too.
11
+ */
12
+ export function handlerInWords(h) {
13
+ return h.type === "tool" ? `🔧 ${h.name} (tool)` : h.name;
14
+ }
8
15
  export function duration(pair) {
9
16
  const d = pair.durationMillis;
10
17
  return d ? `~${d.p50} / ~${d.p99} / ~${d.max} ms` : "";
11
18
  }
12
19
  export function Table({ shown, differs }) {
13
- return (_jsxs(_Fragment, { children: [_jsx("div", { className: "ac-table-wrap", children: _jsxs("table", { className: "ac-table", "aria-label": "Components", children: [_jsx("caption", { className: "ac-visually-hidden", children: "Components" }), _jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { scope: "col", children: "Name" }), _jsx("th", { scope: "col", children: "Kind" }), _jsx("th", { scope: "col", children: "Handlers" })] }) }), _jsx("tbody", { children: shown.nodes.map((n) => (_jsxs("tr", { "data-node": n.id, children: [_jsx("td", { children: n.label }), _jsxs("td", { children: [kindInWords(n.kind), n.platform ? ", platform" : "", differs.has(n.id) ? `, only on ${differs.get(n.id).join(", ")}` : ""] }), _jsx("td", { children: n.handlers.map((h) => h.name).join(", ") })] }, n.id))) })] }) }), shown.declared.length > 0 ? (_jsx("div", { className: "ac-table-wrap", children: _jsxs("table", { className: "ac-table", "aria-label": "Declared connections", children: [_jsx("caption", { className: "ac-visually-hidden", children: "Declared connections" }), _jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { scope: "col", children: "From" }), _jsx("th", { scope: "col", children: "To" }), _jsx("th", { scope: "col", children: "As" })] }) }), _jsx("tbody", { children: shown.declared.map((e) => (_jsxs("tr", { children: [_jsx("td", { children: nameOf(shown, e.from) }), _jsx("td", { children: nameOf(shown, e.to) }), _jsx("td", { children: e.kind })] }, `${e.from}>${e.to}:${e.kind}`))) })] }) })) : null, shown.calls.length > 0 ? (_jsx("div", { className: "ac-table-wrap", children: _jsxs("table", { className: "ac-table", "aria-label": "Observed calls", children: [_jsx("caption", { className: "ac-visually-hidden", children: "Observed calls" }), _jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { scope: "col", children: "From" }), _jsx("th", { scope: "col", children: "To" }), _jsx("th", { scope: "col", children: "Handler to handler" }), _jsx("th", { scope: "col", className: "ac-num", children: "Ok" }), _jsx("th", { scope: "col", className: "ac-num", children: "Refused" }), _jsx("th", { scope: "col", className: "ac-num", children: "Failed" }), _jsx("th", { scope: "col", className: "ac-num", children: "Timed out" }), _jsx("th", { scope: "col", className: "ac-num", children: "Undelivered" }), _jsx("th", { scope: "col", children: "p50 / p99 / max" })] }) }), _jsx("tbody", { children: shown.calls.flatMap((c) => c.pairs.map((p) => (_jsxs("tr", { "data-pair": `${p.caller} -> ${p.callee}`, children: [_jsx("td", { children: nameOf(shown, c.from) }), _jsx("td", { children: nameOf(shown, c.to) }), _jsxs("td", { children: [p.caller, " \u2192 ", p.callee, p.streaming ? " (stream)" : ""] }), _jsx("td", { className: "ac-num", children: p.handled?.ok ?? 0 }), _jsx("td", { className: "ac-num", children: p.handled?.refused ?? 0 }), _jsx("td", { className: "ac-num", children: p.handled?.failed ?? 0 }), _jsx("td", { className: "ac-num", children: p.unanswered?.timedOut ?? 0 }), _jsx("td", { className: "ac-num", children: p.unanswered?.undelivered ?? 0 }), _jsx("td", { children: duration(p) })] }, `${c.from}>${c.to}:${p.caller}>${p.callee}`)))) })] }) })) : null] }));
20
+ return (_jsxs(_Fragment, { children: [_jsx("div", { className: "ac-table-wrap", children: _jsxs("table", { className: "ac-table", "aria-label": "Components", children: [_jsx("caption", { className: "ac-visually-hidden", children: "Components" }), _jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { scope: "col", children: "Name" }), _jsx("th", { scope: "col", children: "Kind" }), _jsx("th", { scope: "col", children: "Handlers" })] }) }), _jsx("tbody", { children: shown.nodes.map((n) => (_jsxs("tr", { "data-node": n.id, children: [_jsx("td", { children: n.label }), _jsxs("td", { children: [kindInWords(n.kind), n.platform ? ", platform" : "", differs.has(n.id) ? `, only on ${differs.get(n.id).join(", ")}` : ""] }), _jsx("td", { children: n.handlers.map(handlerInWords).join(", ") })] }, n.id))) })] }) }), shown.declared.length > 0 ? (_jsx("div", { className: "ac-table-wrap", children: _jsxs("table", { className: "ac-table", "aria-label": "Declared connections", children: [_jsx("caption", { className: "ac-visually-hidden", children: "Declared connections" }), _jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { scope: "col", children: "From" }), _jsx("th", { scope: "col", children: "To" }), _jsx("th", { scope: "col", children: "As" })] }) }), _jsx("tbody", { children: shown.declared.map((e) => (_jsxs("tr", { children: [_jsx("td", { children: nameOf(shown, e.from) }), _jsx("td", { children: nameOf(shown, e.to) }), _jsx("td", { children: e.kind })] }, `${e.from}>${e.to}:${e.kind}`))) })] }) })) : null, shown.calls.length > 0 ? (_jsx("div", { className: "ac-table-wrap", children: _jsxs("table", { className: "ac-table", "aria-label": "Observed calls", children: [_jsx("caption", { className: "ac-visually-hidden", children: "Observed calls" }), _jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { scope: "col", children: "From" }), _jsx("th", { scope: "col", children: "To" }), _jsx("th", { scope: "col", children: "Handler to handler" }), _jsx("th", { scope: "col", className: "ac-num", children: "Ok" }), _jsx("th", { scope: "col", className: "ac-num", children: "Refused" }), _jsx("th", { scope: "col", className: "ac-num", children: "Failed" }), _jsx("th", { scope: "col", className: "ac-num", children: "Timed out" }), _jsx("th", { scope: "col", className: "ac-num", children: "Undelivered" }), _jsx("th", { scope: "col", children: "p50 / p99 / max" })] }) }), _jsx("tbody", { children: shown.calls.flatMap((c) => c.pairs.map((p) => (_jsxs("tr", { "data-pair": `${p.caller} -> ${p.callee}`, children: [_jsx("td", { children: nameOf(shown, c.from) }), _jsx("td", { children: nameOf(shown, c.to) }), _jsxs("td", { children: [p.caller, " \u2192 ", p.callee, p.streaming ? " (stream)" : ""] }), _jsx("td", { className: "ac-num", children: p.handled?.ok ?? 0 }), _jsx("td", { className: "ac-num", children: p.handled?.refused ?? 0 }), _jsx("td", { className: "ac-num", children: p.handled?.failed ?? 0 }), _jsx("td", { className: "ac-num", children: p.unanswered?.timedOut ?? 0 }), _jsx("td", { className: "ac-num", children: p.unanswered?.undelivered ?? 0 }), _jsx("td", { children: duration(p) })] }, `${c.from}>${c.to}:${p.caller}>${p.callee}`)))) })] }) })) : null] }));
14
21
  }
@@ -27,6 +27,19 @@ export declare function useProjectStream(projectId: string, initial: ServiceStat
27
27
  processPort: number | undefined;
28
28
  broker: string | undefined;
29
29
  undeclaredTopics: string[] | undefined;
30
+ secretStore: {
31
+ backend: string;
32
+ keyRead: boolean;
33
+ move: {
34
+ phase: string;
35
+ outcome: string;
36
+ names: {
37
+ name: string;
38
+ state: string;
39
+ }[];
40
+ detail: string | undefined;
41
+ } | undefined;
42
+ } | undefined;
30
43
  topicChecks: {
31
44
  topic: string | undefined;
32
45
  service: string;
@@ -48,10 +61,64 @@ export declare function useProjectStream(projectId: string, initial: ServiceStat
48
61
  contract: string | undefined;
49
62
  lag: number | undefined;
50
63
  failing: string | undefined;
64
+ gap: {
65
+ partitions: {
66
+ partition: number;
67
+ beginning: number;
68
+ earliestRetained: string | undefined;
69
+ }[];
70
+ compacted: boolean;
71
+ gone: boolean;
72
+ readAt: string | undefined;
73
+ } | undefined;
74
+ }[] | undefined;
75
+ warnings: {
76
+ kind: string;
77
+ component: string;
78
+ topic: string;
79
+ message: string;
51
80
  }[] | undefined;
52
81
  objectStorage: string | undefined;
53
82
  bucket: string | undefined;
54
83
  bucketAddress: string | undefined;
84
+ objectStore: string | undefined;
85
+ bucketLocation: string | undefined;
86
+ softDeleteDays: number | undefined;
87
+ storageMove: string | undefined;
88
+ buckets: {
89
+ name: string;
90
+ phase: string;
91
+ store: string | undefined;
92
+ bucket: string | undefined;
93
+ exposure: string;
94
+ publicAddress: string | undefined;
95
+ kept: boolean;
96
+ detail: string | undefined;
97
+ }[] | undefined;
98
+ databaseCluster: string | undefined;
99
+ grants: string | undefined;
100
+ crossProjectTopics: {
101
+ project: string;
102
+ topic: string;
103
+ right: string;
104
+ status: string;
105
+ }[] | undefined;
106
+ customHostnames: {
107
+ hostname: string;
108
+ state: string;
109
+ reason: string | undefined;
110
+ record: {
111
+ name: string;
112
+ kind: string;
113
+ value: string;
114
+ } | undefined;
115
+ note: string | undefined;
116
+ }[];
117
+ proofRecord: {
118
+ name: string;
119
+ kind: string;
120
+ value: string;
121
+ } | undefined;
55
122
  }[];
56
123
  state: StreamState;
57
124
  };
@@ -93,6 +160,19 @@ export declare function useServiceStream(projectId: string, name: string, initia
93
160
  processPort: number | undefined;
94
161
  broker: string | undefined;
95
162
  undeclaredTopics: string[] | undefined;
163
+ secretStore: {
164
+ backend: string;
165
+ keyRead: boolean;
166
+ move: {
167
+ phase: string;
168
+ outcome: string;
169
+ names: {
170
+ name: string;
171
+ state: string;
172
+ }[];
173
+ detail: string | undefined;
174
+ } | undefined;
175
+ } | undefined;
96
176
  topicChecks: {
97
177
  topic: string | undefined;
98
178
  service: string;
@@ -114,10 +194,64 @@ export declare function useServiceStream(projectId: string, name: string, initia
114
194
  contract: string | undefined;
115
195
  lag: number | undefined;
116
196
  failing: string | undefined;
197
+ gap: {
198
+ partitions: {
199
+ partition: number;
200
+ beginning: number;
201
+ earliestRetained: string | undefined;
202
+ }[];
203
+ compacted: boolean;
204
+ gone: boolean;
205
+ readAt: string | undefined;
206
+ } | undefined;
207
+ }[] | undefined;
208
+ warnings: {
209
+ kind: string;
210
+ component: string;
211
+ topic: string;
212
+ message: string;
117
213
  }[] | undefined;
118
214
  objectStorage: string | undefined;
119
215
  bucket: string | undefined;
120
216
  bucketAddress: string | undefined;
217
+ objectStore: string | undefined;
218
+ bucketLocation: string | undefined;
219
+ softDeleteDays: number | undefined;
220
+ storageMove: string | undefined;
221
+ buckets: {
222
+ name: string;
223
+ phase: string;
224
+ store: string | undefined;
225
+ bucket: string | undefined;
226
+ exposure: string;
227
+ publicAddress: string | undefined;
228
+ kept: boolean;
229
+ detail: string | undefined;
230
+ }[] | undefined;
231
+ databaseCluster: string | undefined;
232
+ grants: string | undefined;
233
+ crossProjectTopics: {
234
+ project: string;
235
+ topic: string;
236
+ right: string;
237
+ status: string;
238
+ }[] | undefined;
239
+ customHostnames: {
240
+ hostname: string;
241
+ state: string;
242
+ reason: string | undefined;
243
+ record: {
244
+ name: string;
245
+ kind: string;
246
+ value: string;
247
+ } | undefined;
248
+ note: string | undefined;
249
+ }[];
250
+ proofRecord: {
251
+ name: string;
252
+ kind: string;
253
+ value: string;
254
+ } | undefined;
121
255
  };
122
256
  byInstance: Record<string, {
123
257
  lines: string[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ankka-console",
3
- "version": "0.11.0",
3
+ "version": "0.13.0",
4
4
  "description": "The ankka console as a package: the control plane client, sign-in and sessions, and the pages as routes a React Router host mounts.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",