@zackbart/connecta 0.15.1 → 0.16.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.
Files changed (335) hide show
  1. package/AGENTS.md +40 -20
  2. package/CHANGELOG.md +653 -0
  3. package/README.md +25 -5
  4. package/bin/connecta.mjs +44 -3
  5. package/dist/access-tokens.d.ts +0 -1
  6. package/dist/access-tokens.js +0 -1
  7. package/dist/activity.d.ts +50 -2
  8. package/dist/activity.js +34 -1
  9. package/dist/apps-shell.d.ts +0 -1
  10. package/dist/apps-shell.js +0 -1
  11. package/dist/auth/bearer.d.ts +0 -1
  12. package/dist/auth/bearer.js +0 -1
  13. package/dist/auth/clerk.d.ts +0 -1
  14. package/dist/auth/clerk.js +45 -9
  15. package/dist/auth/downstream-oauth.d.ts +0 -1
  16. package/dist/auth/downstream-oauth.js +0 -1
  17. package/dist/call-admission.d.ts +0 -1
  18. package/dist/call-admission.js +0 -1
  19. package/dist/catalog-drift.d.ts +99 -0
  20. package/dist/catalog-drift.js +251 -0
  21. package/dist/catalog-fingerprint.d.ts +0 -1
  22. package/dist/catalog-fingerprint.js +0 -1
  23. package/dist/catalog-limits.d.ts +0 -1
  24. package/dist/catalog-limits.js +0 -1
  25. package/dist/catalog-service.d.ts +0 -1
  26. package/dist/catalog-service.js +41 -5
  27. package/dist/catalog.d.ts +11 -1
  28. package/dist/catalog.js +20 -1
  29. package/dist/concurrency.d.ts +0 -1
  30. package/dist/concurrency.js +0 -1
  31. package/dist/connector-scope.d.ts +0 -1
  32. package/dist/connector-scope.js +0 -1
  33. package/dist/connectors/api.d.ts +29 -21
  34. package/dist/connectors/api.js +45 -19
  35. package/dist/connectors/guarded-fetch.d.ts +106 -0
  36. package/dist/connectors/guarded-fetch.js +289 -0
  37. package/dist/connectors/remote-mcp.d.ts +0 -1
  38. package/dist/connectors/remote-mcp.js +0 -1
  39. package/dist/credentials.d.ts +0 -1
  40. package/dist/credentials.js +0 -1
  41. package/dist/errors.d.ts +30 -3
  42. package/dist/errors.js +1 -1
  43. package/dist/execute.d.ts +0 -1
  44. package/dist/execute.js +0 -1
  45. package/dist/executor-admission.d.ts +11 -1
  46. package/dist/executor-admission.js +28 -1
  47. package/dist/executor-result.d.ts +0 -1
  48. package/dist/executor-result.js +0 -1
  49. package/dist/executors/quickjs-child.d.ts +0 -1
  50. package/dist/executors/quickjs-child.js +0 -1
  51. package/dist/executors/quickjs-protocol.d.ts +0 -1
  52. package/dist/executors/quickjs-protocol.js +0 -1
  53. package/dist/executors/quickjs-runtime.d.ts +0 -1
  54. package/dist/executors/quickjs-runtime.js +0 -1
  55. package/dist/executors/quickjs.d.ts +0 -1
  56. package/dist/executors/quickjs.js +2 -1
  57. package/dist/favicon.d.ts +0 -1
  58. package/dist/favicon.js +0 -1
  59. package/dist/index.d.ts +2 -3
  60. package/dist/index.js +24 -7
  61. package/dist/invocation.d.ts +0 -1
  62. package/dist/invocation.js +0 -1
  63. package/dist/json-schema.d.ts +0 -1
  64. package/dist/json-schema.js +0 -1
  65. package/dist/mcp-result.d.ts +0 -1
  66. package/dist/mcp-result.js +0 -1
  67. package/dist/meta-tools.d.ts +0 -1
  68. package/dist/meta-tools.js +0 -1
  69. package/dist/node.d.ts +0 -1
  70. package/dist/node.js +0 -1
  71. package/dist/operator-ui/generated.d.ts +2 -3
  72. package/dist/operator-ui/generated.js +3 -4
  73. package/dist/operator-ui/model.d.ts +10 -1
  74. package/dist/operator-ui/model.js +0 -1
  75. package/dist/operator-ui/view.d.ts +167 -0
  76. package/dist/operator-ui/view.js +270 -0
  77. package/dist/providers/cloudflare.d.ts +0 -1
  78. package/dist/providers/cloudflare.js +261 -299
  79. package/dist/providers/linear.d.ts +26 -5
  80. package/dist/providers/linear.js +32 -61
  81. package/dist/providers/mixpanel.d.ts +35 -4
  82. package/dist/providers/mixpanel.js +53 -79
  83. package/dist/providers/notion.d.ts +0 -1
  84. package/dist/providers/notion.js +87 -42
  85. package/dist/providers/stripe.d.ts +13 -1
  86. package/dist/providers/stripe.js +31 -60
  87. package/dist/registry.d.ts +34 -2
  88. package/dist/registry.js +85 -5
  89. package/dist/retired-toolkits.d.ts +0 -1
  90. package/dist/retired-toolkits.js +0 -1
  91. package/dist/routes/access-tokens.d.ts +0 -1
  92. package/dist/routes/access-tokens.js +0 -1
  93. package/dist/routes/activity.d.ts +0 -1
  94. package/dist/routes/activity.js +0 -1
  95. package/dist/routes/credentials.d.ts +0 -1
  96. package/dist/routes/credentials.js +0 -1
  97. package/dist/routes/mcp.d.ts +0 -1
  98. package/dist/routes/mcp.js +0 -1
  99. package/dist/routes/oauth.d.ts +0 -1
  100. package/dist/routes/oauth.js +0 -1
  101. package/dist/routes/shared.d.ts +2 -1
  102. package/dist/routes/shared.js +0 -1
  103. package/dist/routes/ui.d.ts +0 -1
  104. package/dist/routes/ui.js +0 -1
  105. package/dist/server.d.ts +0 -1
  106. package/dist/server.js +11 -1
  107. package/dist/skills.d.ts +0 -1
  108. package/dist/skills.js +0 -1
  109. package/dist/storage/file.d.ts +0 -1
  110. package/dist/storage/file.js +0 -1
  111. package/dist/storage/memory.d.ts +0 -1
  112. package/dist/storage/memory.js +0 -1
  113. package/dist/timeout.d.ts +0 -1
  114. package/dist/timeout.js +0 -1
  115. package/dist/tool-safety.d.ts +0 -1
  116. package/dist/tool-safety.js +0 -1
  117. package/dist/types.d.ts +45 -1
  118. package/dist/types.js +0 -1
  119. package/dist/ui.d.ts +0 -1
  120. package/dist/ui.js +13 -137
  121. package/dist/validate.d.ts +13 -15
  122. package/dist/validate.js +24 -11
  123. package/dist/version.d.ts +1 -2
  124. package/dist/version.js +1 -2
  125. package/documentation/architecture.md +186 -5
  126. package/documentation/auth.md +11 -0
  127. package/documentation/call-admission.md +142 -6
  128. package/documentation/cloudflare.md +92 -10
  129. package/documentation/code-first-exploration.md +2 -2
  130. package/documentation/code-mode.md +14 -14
  131. package/documentation/connector-guides.md +172 -5
  132. package/documentation/connectors.md +89 -0
  133. package/documentation/linear.md +20 -2
  134. package/documentation/mcp-ui-design.md +2 -2
  135. package/documentation/meta-tools.md +7 -1
  136. package/documentation/mixpanel.md +42 -9
  137. package/documentation/notion.md +23 -2
  138. package/documentation/operations.md +325 -5
  139. package/documentation/operator-ui.md +120 -5
  140. package/documentation/provider-audit.md +160 -0
  141. package/documentation/provider-conventions.md +667 -0
  142. package/documentation/request-admission.md +167 -5
  143. package/documentation/rich-output-design.md +1 -2
  144. package/documentation/stripe.md +15 -0
  145. package/documentation/upgrading.md +454 -0
  146. package/ethos.md +14 -9
  147. package/examples/worker/README.md +102 -12
  148. package/examples/worker/src/index.ts +46 -1
  149. package/examples/worker/wrangler.jsonc +14 -1
  150. package/package.json +10 -6
  151. package/templates/node/.dockerignore +10 -0
  152. package/templates/node/.env.example +40 -3
  153. package/templates/node/AGENTS.md +16 -1
  154. package/templates/node/Dockerfile +49 -0
  155. package/templates/node/README.md +117 -2
  156. package/templates/node/docker-compose.yml +39 -0
  157. package/templates/node/package.json +1 -1
  158. package/templates/node/src/file-activity.ts +182 -0
  159. package/templates/node/src/index.ts +80 -4
  160. package/assets/connecta-clay-hero.png +0 -0
  161. package/dist/access-tokens.d.ts.map +0 -1
  162. package/dist/access-tokens.js.map +0 -1
  163. package/dist/activity.d.ts.map +0 -1
  164. package/dist/activity.js.map +0 -1
  165. package/dist/apps-shell.d.ts.map +0 -1
  166. package/dist/apps-shell.js.map +0 -1
  167. package/dist/auth/bearer.d.ts.map +0 -1
  168. package/dist/auth/bearer.js.map +0 -1
  169. package/dist/auth/clerk.d.ts.map +0 -1
  170. package/dist/auth/clerk.js.map +0 -1
  171. package/dist/auth/downstream-oauth.d.ts.map +0 -1
  172. package/dist/auth/downstream-oauth.js.map +0 -1
  173. package/dist/call-admission.d.ts.map +0 -1
  174. package/dist/call-admission.js.map +0 -1
  175. package/dist/catalog-fingerprint.d.ts.map +0 -1
  176. package/dist/catalog-fingerprint.js.map +0 -1
  177. package/dist/catalog-limits.d.ts.map +0 -1
  178. package/dist/catalog-limits.js.map +0 -1
  179. package/dist/catalog-service.d.ts.map +0 -1
  180. package/dist/catalog-service.js.map +0 -1
  181. package/dist/catalog.d.ts.map +0 -1
  182. package/dist/catalog.js.map +0 -1
  183. package/dist/concurrency.d.ts.map +0 -1
  184. package/dist/concurrency.js.map +0 -1
  185. package/dist/connector-scope.d.ts.map +0 -1
  186. package/dist/connector-scope.js.map +0 -1
  187. package/dist/connectors/api.d.ts.map +0 -1
  188. package/dist/connectors/api.js.map +0 -1
  189. package/dist/connectors/remote-mcp.d.ts.map +0 -1
  190. package/dist/connectors/remote-mcp.js.map +0 -1
  191. package/dist/credentials.d.ts.map +0 -1
  192. package/dist/credentials.js.map +0 -1
  193. package/dist/errors.d.ts.map +0 -1
  194. package/dist/errors.js.map +0 -1
  195. package/dist/execute.d.ts.map +0 -1
  196. package/dist/execute.js.map +0 -1
  197. package/dist/executor-admission.d.ts.map +0 -1
  198. package/dist/executor-admission.js.map +0 -1
  199. package/dist/executor-result.d.ts.map +0 -1
  200. package/dist/executor-result.js.map +0 -1
  201. package/dist/executors/quickjs-child.d.ts.map +0 -1
  202. package/dist/executors/quickjs-child.js.map +0 -1
  203. package/dist/executors/quickjs-protocol.d.ts.map +0 -1
  204. package/dist/executors/quickjs-protocol.js.map +0 -1
  205. package/dist/executors/quickjs-runtime.d.ts.map +0 -1
  206. package/dist/executors/quickjs-runtime.js.map +0 -1
  207. package/dist/executors/quickjs.d.ts.map +0 -1
  208. package/dist/executors/quickjs.js.map +0 -1
  209. package/dist/favicon.d.ts.map +0 -1
  210. package/dist/favicon.js.map +0 -1
  211. package/dist/index.d.ts.map +0 -1
  212. package/dist/index.js.map +0 -1
  213. package/dist/invocation.d.ts.map +0 -1
  214. package/dist/invocation.js.map +0 -1
  215. package/dist/json-schema.d.ts.map +0 -1
  216. package/dist/json-schema.js.map +0 -1
  217. package/dist/mcp-result.d.ts.map +0 -1
  218. package/dist/mcp-result.js.map +0 -1
  219. package/dist/meta-tools.d.ts.map +0 -1
  220. package/dist/meta-tools.js.map +0 -1
  221. package/dist/node.d.ts.map +0 -1
  222. package/dist/node.js.map +0 -1
  223. package/dist/operator-ui/generated.d.ts.map +0 -1
  224. package/dist/operator-ui/generated.js.map +0 -1
  225. package/dist/operator-ui/model.d.ts.map +0 -1
  226. package/dist/operator-ui/model.js.map +0 -1
  227. package/dist/providers/cloudflare.d.ts.map +0 -1
  228. package/dist/providers/cloudflare.js.map +0 -1
  229. package/dist/providers/linear.d.ts.map +0 -1
  230. package/dist/providers/linear.js.map +0 -1
  231. package/dist/providers/mixpanel.d.ts.map +0 -1
  232. package/dist/providers/mixpanel.js.map +0 -1
  233. package/dist/providers/notion.d.ts.map +0 -1
  234. package/dist/providers/notion.js.map +0 -1
  235. package/dist/providers/stripe.d.ts.map +0 -1
  236. package/dist/providers/stripe.js.map +0 -1
  237. package/dist/registry.d.ts.map +0 -1
  238. package/dist/registry.js.map +0 -1
  239. package/dist/retired-toolkits.d.ts.map +0 -1
  240. package/dist/retired-toolkits.js.map +0 -1
  241. package/dist/routes/access-tokens.d.ts.map +0 -1
  242. package/dist/routes/access-tokens.js.map +0 -1
  243. package/dist/routes/activity.d.ts.map +0 -1
  244. package/dist/routes/activity.js.map +0 -1
  245. package/dist/routes/credentials.d.ts.map +0 -1
  246. package/dist/routes/credentials.js.map +0 -1
  247. package/dist/routes/mcp.d.ts.map +0 -1
  248. package/dist/routes/mcp.js.map +0 -1
  249. package/dist/routes/oauth.d.ts.map +0 -1
  250. package/dist/routes/oauth.js.map +0 -1
  251. package/dist/routes/shared.d.ts.map +0 -1
  252. package/dist/routes/shared.js.map +0 -1
  253. package/dist/routes/ui.d.ts.map +0 -1
  254. package/dist/routes/ui.js.map +0 -1
  255. package/dist/server.d.ts.map +0 -1
  256. package/dist/server.js.map +0 -1
  257. package/dist/skills.d.ts.map +0 -1
  258. package/dist/skills.js.map +0 -1
  259. package/dist/storage/file.d.ts.map +0 -1
  260. package/dist/storage/file.js.map +0 -1
  261. package/dist/storage/memory.d.ts.map +0 -1
  262. package/dist/storage/memory.js.map +0 -1
  263. package/dist/timeout.d.ts.map +0 -1
  264. package/dist/timeout.js.map +0 -1
  265. package/dist/tool-safety.d.ts.map +0 -1
  266. package/dist/tool-safety.js.map +0 -1
  267. package/dist/types.d.ts.map +0 -1
  268. package/dist/types.js.map +0 -1
  269. package/dist/ui.d.ts.map +0 -1
  270. package/dist/ui.js.map +0 -1
  271. package/dist/validate.d.ts.map +0 -1
  272. package/dist/validate.js.map +0 -1
  273. package/dist/version.d.ts.map +0 -1
  274. package/dist/version.js.map +0 -1
  275. package/examples/node/README.md +0 -52
  276. package/examples/node/src/index.ts +0 -71
  277. package/src/access-tokens.ts +0 -289
  278. package/src/activity.ts +0 -234
  279. package/src/apps-shell.ts +0 -370
  280. package/src/auth/bearer.ts +0 -61
  281. package/src/auth/clerk.ts +0 -553
  282. package/src/auth/downstream-oauth.ts +0 -575
  283. package/src/call-admission.ts +0 -521
  284. package/src/catalog-fingerprint.ts +0 -52
  285. package/src/catalog-limits.ts +0 -11
  286. package/src/catalog-service.ts +0 -1153
  287. package/src/catalog.ts +0 -790
  288. package/src/concurrency.ts +0 -39
  289. package/src/connector-scope.ts +0 -66
  290. package/src/connectors/api.ts +0 -159
  291. package/src/connectors/remote-mcp.ts +0 -1090
  292. package/src/credentials.ts +0 -428
  293. package/src/errors.ts +0 -364
  294. package/src/execute.ts +0 -1406
  295. package/src/executor-admission.ts +0 -328
  296. package/src/executor-result.ts +0 -107
  297. package/src/executors/quickjs-child.ts +0 -172
  298. package/src/executors/quickjs-protocol.ts +0 -99
  299. package/src/executors/quickjs-runtime.ts +0 -470
  300. package/src/executors/quickjs.ts +0 -776
  301. package/src/favicon.ts +0 -53
  302. package/src/index.ts +0 -666
  303. package/src/invocation.ts +0 -655
  304. package/src/json-schema.ts +0 -11
  305. package/src/mcp-result.ts +0 -43
  306. package/src/meta-tools.ts +0 -1607
  307. package/src/node.ts +0 -206
  308. package/src/operator-ui/browser.css +0 -423
  309. package/src/operator-ui/browser.ts +0 -1281
  310. package/src/operator-ui/generated.ts +0 -4
  311. package/src/operator-ui/model.ts +0 -111
  312. package/src/providers/cloudflare.ts +0 -3999
  313. package/src/providers/linear.ts +0 -302
  314. package/src/providers/mixpanel.ts +0 -229
  315. package/src/providers/notion.ts +0 -1879
  316. package/src/providers/stripe.ts +0 -307
  317. package/src/registry.ts +0 -1085
  318. package/src/retired-toolkits.ts +0 -14
  319. package/src/routes/access-tokens.ts +0 -115
  320. package/src/routes/activity.ts +0 -215
  321. package/src/routes/credentials.ts +0 -254
  322. package/src/routes/mcp.ts +0 -429
  323. package/src/routes/oauth.ts +0 -322
  324. package/src/routes/shared.ts +0 -247
  325. package/src/routes/ui.ts +0 -152
  326. package/src/server.ts +0 -195
  327. package/src/skills.ts +0 -271
  328. package/src/storage/file.ts +0 -123
  329. package/src/storage/memory.ts +0 -44
  330. package/src/timeout.ts +0 -84
  331. package/src/tool-safety.ts +0 -15
  332. package/src/types.ts +0 -523
  333. package/src/ui.ts +0 -744
  334. package/src/validate.ts +0 -387
  335. package/src/version.ts +0 -7
@@ -0,0 +1,270 @@
1
+ export const OPERATOR_PAGES = [
2
+ "connections",
3
+ "credentials",
4
+ "tokens",
5
+ "activity",
6
+ ];
7
+ export const PAGE_META = {
8
+ connections: { path: "/", label: "Connections" },
9
+ credentials: { path: "/credentials", label: "Credentials" },
10
+ tokens: { path: "/tokens", label: "Access tokens" },
11
+ activity: { path: "/activity", label: "Activity" },
12
+ };
13
+ export function pageForPath(path) {
14
+ const match = OPERATOR_PAGES.find((page) => PAGE_META[page].path === path);
15
+ return match ?? "connections";
16
+ }
17
+ export function info(message) {
18
+ return { message, tone: "info" };
19
+ }
20
+ export function failure(message) {
21
+ return { message, tone: "error" };
22
+ }
23
+ export function initialState(page) {
24
+ return {
25
+ page,
26
+ generation: 0,
27
+ session: "loading",
28
+ gate: null,
29
+ refreshing: false,
30
+ pendingFocus: null,
31
+ ...identityScopedState(),
32
+ };
33
+ }
34
+ /**
35
+ * Every field that belongs to one operator identity. Split out because the only
36
+ * safe way to change identity is to replace all of them at once: a field left
37
+ * behind here is one identity's data on another identity's screen.
38
+ */
39
+ function identityScopedState() {
40
+ return {
41
+ data: null,
42
+ connectorFilter: "",
43
+ oauthNotice: null,
44
+ oauthBusy: null,
45
+ credentialNotice: null,
46
+ credentialEditing: null,
47
+ credentialBusy: null,
48
+ tokenPhase: "idle",
49
+ tokenNotice: null,
50
+ tokens: [],
51
+ createdToken: null,
52
+ tokenRenaming: null,
53
+ tokenBusy: false,
54
+ activityPhase: "idle",
55
+ activityNotice: null,
56
+ activityEvents: [],
57
+ activityCursor: null,
58
+ activitySearch: "",
59
+ };
60
+ }
61
+ /**
62
+ * Drop to the gate and forget the previous operator. Bumping the generation is
63
+ * what makes the drop stick: work already in flight for the old identity
64
+ * resolves into a state that no longer accepts it.
65
+ */
66
+ export function resetIdentity(state, gate = null) {
67
+ return {
68
+ ...state,
69
+ generation: state.generation + 1,
70
+ session: "gated",
71
+ gate,
72
+ refreshing: false,
73
+ pendingFocus: null,
74
+ ...identityScopedState(),
75
+ };
76
+ }
77
+ /**
78
+ * Leaving a page closes what should not survive it: a one-time secret, a half
79
+ * typed credential, and the notices that answered the page just left.
80
+ */
81
+ export function withPage(state, page) {
82
+ return {
83
+ ...state,
84
+ page,
85
+ createdToken: null,
86
+ tokenRenaming: null,
87
+ tokenNotice: null,
88
+ credentialEditing: null,
89
+ credentialNotice: null,
90
+ };
91
+ }
92
+ export function credentialUnavailableCopy(capability) {
93
+ if (capability === "no_slots") {
94
+ return "No connectors declare operator-managed credential slots. Connector credentials remain configuration-as-code until a slot is declared.";
95
+ }
96
+ if (capability === "vault_not_configured") {
97
+ return "Credential storage is not configured. Set credentials.encryptionKey before managing connector credentials here.";
98
+ }
99
+ return "Credential management requires an eligible Clerk operator. Bearer-authenticated sessions can inspect connections but cannot manage stored credentials.";
100
+ }
101
+ export function accessTokenUnavailableCopy(capability) {
102
+ if (capability === "not_configured") {
103
+ return "Access tokens are not configured for this deployment. Add accessTokens to the deployment configuration to enable them.";
104
+ }
105
+ return "Access token management requires an eligible Clerk operator. A Bearer token can connect to MCP, but it cannot create or revoke other tokens.";
106
+ }
107
+ export function connectorStatusLabel(status) {
108
+ if (status === "ok")
109
+ return "Connected";
110
+ if (status === "auth_required")
111
+ return "Authorization needed";
112
+ return "Unavailable";
113
+ }
114
+ export function toolCountLabel(count) {
115
+ return `${count} ${count === 1 ? "tool" : "tools"}`;
116
+ }
117
+ /**
118
+ * The four categories, in the order an operator should read them: what the
119
+ * deployment refuses to call, what it can no longer call, what contradicts a
120
+ * vetted verdict, and what changed shape underneath a reviewed schema. Counts
121
+ * only — a name or a schema on this path would be the payload leak the whole
122
+ * drift model exists to avoid.
123
+ */
124
+ const DRIFT_CATEGORIES = [
125
+ { key: "unclassifiedTools", label: "Unclassified" },
126
+ { key: "unservedTools", label: "Unserved" },
127
+ { key: "annotationConflicts", label: "Annotation conflicts" },
128
+ { key: "schemaChanges", label: "Schema changes" },
129
+ ];
130
+ export function driftTotal(drift) {
131
+ if (!drift)
132
+ return 0;
133
+ return DRIFT_CATEGORIES.reduce((sum, { key }) => sum + (drift[key] || 0), 0);
134
+ }
135
+ export function driftState(drift) {
136
+ if (!drift)
137
+ return "unavailable";
138
+ return driftTotal(drift) > 0 ? "warning" : "clean";
139
+ }
140
+ /** Every category with its count, so a clean report still shows its zeros. */
141
+ export function driftCounts(drift) {
142
+ if (!drift)
143
+ return [];
144
+ return DRIFT_CATEGORIES.map(({ key, label }) => ({
145
+ key,
146
+ label,
147
+ count: drift[key] || 0,
148
+ }));
149
+ }
150
+ /** One line naming the state and when it was observed. Never what drifted. */
151
+ export function driftSummary(drift) {
152
+ const state = driftState(drift);
153
+ if (state === "unavailable") {
154
+ return "No catalog refresh observed yet in this runtime.";
155
+ }
156
+ const observed = formatDate(drift?.observedAt);
157
+ const when = observed ? ` · observed ${observed}` : "";
158
+ if (state === "clean")
159
+ return `Matches the reviewed manifest${when}`;
160
+ const total = driftTotal(drift);
161
+ return `${total} difference${total === 1 ? "" : "s"} from the reviewed manifest${when}`;
162
+ }
163
+ /**
164
+ * Only http/https may become a clickable href — the browser half of the gate
165
+ * `src/ui.ts` applies before an authorizationUrl is ever serialized. A hostile
166
+ * downstream that gets a `javascript:` URL past one of them still meets the
167
+ * other, and the caller renders inert text instead of a link.
168
+ */
169
+ export function safeHttpHref(url) {
170
+ if (!url)
171
+ return null;
172
+ try {
173
+ const protocol = new URL(url).protocol;
174
+ return protocol === "http:" || protocol === "https:" ? url : null;
175
+ }
176
+ catch {
177
+ return null;
178
+ }
179
+ }
180
+ /** Locale timestamp, or "" for anything that is not a readable date. */
181
+ export function formatDate(value) {
182
+ if (!value)
183
+ return "";
184
+ const date = new Date(value);
185
+ return Number.isNaN(date.valueOf()) ? "" : date.toLocaleString();
186
+ }
187
+ export function actorLabel(actor) {
188
+ if (!actor?.kind)
189
+ return "unknown";
190
+ if (actor.label)
191
+ return `${actor.kind} · ${actor.label}`;
192
+ return actor.id ? `${actor.kind} · ${actor.id}` : actor.kind;
193
+ }
194
+ /**
195
+ * The stable id behind a friendly label, shown only when a label or namespace
196
+ * could otherwise make two different people look like one.
197
+ */
198
+ export function actorStableId(actor) {
199
+ if (!actor?.id)
200
+ return null;
201
+ if (!actor.label && !actor.namespace)
202
+ return null;
203
+ return actor.namespace ? `${actor.namespace} · ${actor.id}` : actor.id;
204
+ }
205
+ function activityMatches(event, query) {
206
+ const q = query.trim().toLowerCase();
207
+ if (!q)
208
+ return true;
209
+ return [
210
+ event.address,
211
+ event.connectorId,
212
+ event.toolName,
213
+ event.source,
214
+ event.outcome,
215
+ event.errorCode,
216
+ event.friction,
217
+ event.actor?.kind,
218
+ event.actor?.id,
219
+ event.actor?.namespace,
220
+ event.actor?.label,
221
+ ].some((value) => String(value ?? "").toLowerCase().includes(q));
222
+ }
223
+ export function filterActivity(events, query) {
224
+ return events.filter((event) => activityMatches(event, query));
225
+ }
226
+ /** Counts only. What the deployment ran, never what it sent or received. */
227
+ export function activitySummary(events) {
228
+ if (events.length === 0)
229
+ return "Arguments and results are never stored.";
230
+ const tools = new Set(events.map((event) => event.address)).size;
231
+ return `${events.length} loaded call${events.length === 1 ? "" : "s"} · ${tools} tool${tools === 1 ? "" : "s"} · no arguments or results stored`;
232
+ }
233
+ const ACTIVITY_OUTCOMES = ["success", "error", "timeout", "cancelled"];
234
+ export function activityOutcomeClass(outcome) {
235
+ return ACTIVITY_OUTCOMES.includes(outcome) ? outcome : "error";
236
+ }
237
+ /** The one-line detail under an address: source, retries, and friction. */
238
+ export function activityDetail(event) {
239
+ const parts = [event.source];
240
+ if (event.attempts > 1)
241
+ parts.push(`${event.attempts} attempts`);
242
+ if (event.friction)
243
+ parts.push(event.friction);
244
+ // The friction class and the code coincide for auth_required and
245
+ // result_too_large. Printing "· auth_required · auth_required" says nothing
246
+ // twice, so the coarse class stands in for both when they agree.
247
+ if (event.errorCode && event.errorCode !== event.friction) {
248
+ parts.push(event.errorCode);
249
+ }
250
+ return parts.join(" · ");
251
+ }
252
+ export function credentialStateLabel(credential) {
253
+ if (!credential.configured)
254
+ return "not configured";
255
+ const masked = credential.fields?.length
256
+ ? "configured"
257
+ : `configured · ••••${credential.lastFour ?? ""}`;
258
+ return credential.updatedAt
259
+ ? `${masked} · updated ${formatDate(credential.updatedAt)}`
260
+ : masked;
261
+ }
262
+ /** Gate copy for the two inbound-auth shapes, so the sign-in state is never a blank page. */
263
+ export function gateCopy(kind, signedIn) {
264
+ if (kind !== "clerk") {
265
+ return "Paste an operator bearer token to open this page. Nothing is requested until you do.";
266
+ }
267
+ return signedIn
268
+ ? "Signed in with Clerk, but this account cannot open deployment-wide operator pages."
269
+ : "Sign in with Clerk to open this operator page.";
270
+ }
@@ -55,4 +55,3 @@ export interface CloudflareOptions {
55
55
  }
56
56
  /** A maintained Cloudflare REST API connection. */
57
57
  export declare function cloudflare(id: string, options: CloudflareOptions): Connector;
58
- //# sourceMappingURL=cloudflare.d.ts.map