@zackbart/connecta 0.28.1 → 0.30.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 (332) hide show
  1. package/CHANGELOG.md +855 -5
  2. package/README.md +125 -116
  3. package/bin/connecta.mjs +121 -139
  4. package/bin/meta-tool-names.d.mts +2 -0
  5. package/bin/meta-tool-names.mjs +9 -0
  6. package/bin/version.mjs +3 -0
  7. package/dist/access-tokens.js +53 -63
  8. package/dist/activity-request.js +8 -0
  9. package/dist/activity.d.ts +76 -42
  10. package/dist/activity.js +110 -42
  11. package/dist/argument-redaction.js +230 -0
  12. package/dist/auth/clerk-sdk/client.d.ts +65 -0
  13. package/dist/auth/clerk-sdk/client.js +5 -0
  14. package/dist/auth/clerk-sdk/generated.js +1845 -0
  15. package/dist/auth/clerk-transport.js +19 -0
  16. package/dist/auth/clerk.d.ts +17 -7
  17. package/dist/auth/clerk.js +189 -107
  18. package/dist/auth/cloudflare-access.js +25 -26
  19. package/dist/auth/downstream-client-metadata.d.ts +29 -0
  20. package/dist/auth/downstream-client-metadata.js +133 -0
  21. package/dist/auth/downstream-oauth.js +1584 -1580
  22. package/dist/auth/downstream-revocation.js +106 -0
  23. package/dist/auth/oauth-token-response.js +231 -0
  24. package/dist/auth/oauth-v2-migration.js +116 -0
  25. package/dist/auth/static-oauth.js +93 -71
  26. package/dist/auth-elicitation.js +288 -0
  27. package/dist/authorization-handoff.js +111 -0
  28. package/dist/branding.d.ts +8 -16
  29. package/dist/branding.js +26 -59
  30. package/dist/byte-read-response.js +39 -0
  31. package/dist/call-admission.js +12 -16
  32. package/dist/catalog-cache.js +739 -0
  33. package/dist/catalog-drift.d.ts +50 -15
  34. package/dist/catalog-drift.js +365 -128
  35. package/dist/catalog-fingerprint.js +2 -4
  36. package/dist/catalog-freshness.js +13 -0
  37. package/dist/catalog-limits.js +2 -2
  38. package/dist/catalog-service.js +409 -225
  39. package/dist/catalog.js +43 -84
  40. package/dist/concurrency.js +3 -4
  41. package/dist/config-defaults.d.ts +39 -0
  42. package/dist/config-defaults.js +46 -0
  43. package/dist/config-schema.d.ts +181 -0
  44. package/dist/config-schema.js +435 -0
  45. package/dist/config-value-sources.js +102 -0
  46. package/dist/config.d.ts +633 -0
  47. package/dist/config.js +508 -0
  48. package/dist/connector-access.d.ts +1 -0
  49. package/dist/connector-access.js +13 -15
  50. package/dist/connector-caller.d.ts +8 -0
  51. package/dist/connector-caller.js +15 -6
  52. package/dist/connector-scope.js +1 -1
  53. package/dist/connectors/api-connector.d.ts +59 -7
  54. package/dist/connectors/api-connector.js +106 -19
  55. package/dist/connectors/api.js +4 -1
  56. package/dist/connectors/guarded-fetch.d.ts +144 -0
  57. package/dist/connectors/guarded-fetch.js +87 -38
  58. package/dist/connectors/negotiation-cache.js +46 -0
  59. package/dist/connectors/option-shapes.js +27 -0
  60. package/dist/connectors/remote-mcp.d.ts +30 -4
  61. package/dist/connectors/remote-mcp.js +1774 -320
  62. package/dist/connectors/resource-uri.js +335 -0
  63. package/dist/credential-contract.d.ts +10 -0
  64. package/dist/credential-rules.js +1 -3
  65. package/dist/credential-url.js +108 -0
  66. package/dist/credentials.d.ts +6 -1
  67. package/dist/credentials.js +27 -18
  68. package/dist/d1.d.ts +130 -0
  69. package/dist/d1.js +290 -0
  70. package/dist/describe-config.d.ts +165 -0
  71. package/dist/describe-config.js +315 -0
  72. package/dist/described.js +106 -0
  73. package/dist/downstream-input-context.js +128 -0
  74. package/dist/downstream-input.js +325 -0
  75. package/dist/errors.d.ts +132 -31
  76. package/dist/errors.js +175 -87
  77. package/dist/execute.js +798 -318
  78. package/dist/executor-admission.d.ts +1 -0
  79. package/dist/executor-admission.js +11 -15
  80. package/dist/executor-contract.d.ts +20 -0
  81. package/dist/executor-contract.js +48 -0
  82. package/dist/executor-result.js +30 -13
  83. package/dist/executors/quickjs-child.js +15 -9
  84. package/dist/executors/quickjs-protocol.js +5 -6
  85. package/dist/executors/quickjs-runtime.js +152 -59
  86. package/dist/executors/quickjs.js +49 -39
  87. package/dist/favicon.js +1 -2
  88. package/dist/fix-prompt.js +1 -3
  89. package/dist/guest-runtime.js +238 -0
  90. package/dist/guest-types.d.ts +218 -0
  91. package/dist/guest-types.js +1 -0
  92. package/dist/html-security.js +24 -0
  93. package/dist/identity.js +1 -3
  94. package/dist/inbound-credential.js +52 -0
  95. package/dist/index.d.ts +24 -256
  96. package/dist/index.js +65 -478
  97. package/dist/invocation-auth.js +69 -0
  98. package/dist/invocation.js +262 -79
  99. package/dist/json-schema.d.ts +1 -1
  100. package/dist/mcp-client-context.js +35 -0
  101. package/dist/mcp-result.js +11 -7
  102. package/dist/meta-output.js +61 -0
  103. package/dist/meta-tool-names.d.ts +2 -0
  104. package/dist/meta-tool-names.js +3 -0
  105. package/dist/meta-tools.js +419 -272
  106. package/dist/module-contracts.d.ts +8 -23
  107. package/dist/node.d.ts +0 -2
  108. package/dist/node.js +2 -2
  109. package/dist/oauth-callback-outcome.js +1 -3
  110. package/dist/oauth-handoff.js +194 -0
  111. package/dist/oauth-sealing.js +20 -0
  112. package/dist/operator-record.d.ts +137 -0
  113. package/dist/operator-record.js +420 -0
  114. package/dist/operator-ui/assets.js +31 -0
  115. package/dist/operator-ui/contract.d.ts +72 -0
  116. package/dist/operator-ui/contract.js +1 -0
  117. package/dist/operator-ui/fix-prompts.d.ts +18 -0
  118. package/dist/operator-ui/generated.js +5 -4
  119. package/dist/operator-ui/model.d.ts +12 -87
  120. package/dist/operator-ui/model.js +2 -9
  121. package/dist/operator-ui/setup-commands.js +1 -3
  122. package/dist/operator-ui/view.d.ts +323 -0
  123. package/dist/operator-ui/view.js +62 -189
  124. package/dist/page-styles.js +2 -3
  125. package/dist/program-result.js +5 -0
  126. package/dist/program-source.js +14 -2
  127. package/dist/{exempt-writes.js → program-writes.js} +60 -19
  128. package/dist/provider.d.ts +142 -0
  129. package/dist/provider.js +187 -0
  130. package/dist/providers/_shared/google/result-size.js +57 -0
  131. package/dist/providers/_shared/google/service-account.d.ts +58 -0
  132. package/dist/providers/_shared/google/service-account.js +500 -0
  133. package/dist/providers/_shared/google/workspace.d.ts +276 -0
  134. package/dist/providers/_shared/google/workspace.js +518 -0
  135. package/dist/providers/_shared/request-token.js +83 -0
  136. package/dist/providers/{basecamp.d.ts → basecamp/index.d.ts} +6 -28
  137. package/dist/providers/basecamp/index.js +997 -0
  138. package/dist/providers/basecamp/skill.generated.js +9 -0
  139. package/dist/providers/{breeze.d.ts → breeze/index.d.ts} +2 -2
  140. package/dist/providers/{breeze.js → breeze/index.js} +184 -140
  141. package/dist/providers/breeze/skill.generated.js +9 -0
  142. package/dist/providers/{ccb.d.ts → ccb/index.d.ts} +2 -2
  143. package/dist/providers/{ccb.js → ccb/index.js} +271 -116
  144. package/dist/providers/ccb/skill.generated.js +9 -0
  145. package/dist/providers/{cloudflare.d.ts → cloudflare/index.d.ts} +8 -7
  146. package/dist/providers/{cloudflare.js → cloudflare/index.js} +171 -738
  147. package/dist/providers/cloudflare/skill.generated.js +10 -0
  148. package/dist/providers/docs/index.d.ts +54 -0
  149. package/dist/providers/docs/index.js +1237 -0
  150. package/dist/providers/docs/skill.generated.js +9 -0
  151. package/dist/providers/drive/index.d.ts +53 -0
  152. package/dist/providers/drive/index.js +1523 -0
  153. package/dist/providers/drive/skill.generated.js +9 -0
  154. package/dist/providers/forms/index.d.ts +54 -0
  155. package/dist/providers/forms/index.js +1217 -0
  156. package/dist/providers/forms/skill.generated.js +11 -0
  157. package/dist/providers/github/auth.d.ts +32 -0
  158. package/dist/providers/github/auth.js +361 -0
  159. package/dist/providers/github/hosted.js +218 -0
  160. package/dist/providers/github/index.d.ts +13 -0
  161. package/dist/providers/github/index.js +140 -0
  162. package/dist/providers/github/key.js +100 -0
  163. package/dist/providers/github/rest.js +321 -0
  164. package/dist/providers/github/scope.d.ts +29 -0
  165. package/dist/providers/github/scope.js +124 -0
  166. package/dist/providers/github/skill.generated.js +8 -0
  167. package/dist/providers/gmail/index.d.ts +51 -0
  168. package/dist/providers/gmail/index.js +1436 -0
  169. package/dist/providers/gmail/skill.generated.js +9 -0
  170. package/dist/providers/infisical/index.d.ts +7 -0
  171. package/dist/providers/infisical/index.js +713 -0
  172. package/dist/providers/infisical/skill.generated.js +8 -0
  173. package/dist/providers/{linear.d.ts → linear/index.d.ts} +11 -14
  174. package/dist/providers/linear/index.js +352 -0
  175. package/dist/providers/linear/skill.generated.js +8 -0
  176. package/dist/providers/{mixpanel.d.ts → mixpanel/index.d.ts} +5 -10
  177. package/dist/providers/mixpanel/index.js +416 -0
  178. package/dist/providers/mixpanel/skill.generated.js +9 -0
  179. package/dist/providers/{notion.d.ts → notion/index.d.ts} +8 -8
  180. package/dist/providers/{notion.js → notion/index.js} +226 -239
  181. package/dist/providers/notion/skill.generated.js +10 -0
  182. package/dist/providers/{overflow.d.ts → overflow/index.d.ts} +2 -2
  183. package/dist/providers/{overflow.js → overflow/index.js} +74 -111
  184. package/dist/providers/overflow/skill.generated.js +8 -0
  185. package/dist/providers/{planning-center.d.ts → planning-center/index.d.ts} +2 -2
  186. package/dist/providers/{planning-center.js → planning-center/index.js} +264 -104
  187. package/dist/providers/planning-center/skill.generated.js +10 -0
  188. package/dist/providers/{revenuecat.d.ts → revenuecat/index.d.ts} +5 -10
  189. package/dist/providers/revenuecat/index.js +557 -0
  190. package/dist/providers/revenuecat/skill.generated.js +11 -0
  191. package/dist/providers/sheets/index.d.ts +54 -0
  192. package/dist/providers/sheets/index.js +1237 -0
  193. package/dist/providers/sheets/skill.generated.js +10 -0
  194. package/dist/providers/slides/index.d.ts +53 -0
  195. package/dist/providers/slides/index.js +2645 -0
  196. package/dist/providers/slides/skill.generated.js +9 -0
  197. package/dist/providers/{stripe.d.ts → stripe/index.d.ts} +5 -12
  198. package/dist/providers/stripe/index.js +266 -0
  199. package/dist/providers/stripe/skill.generated.js +11 -0
  200. package/dist/providers/{tithely.d.ts → tithely/index.d.ts} +2 -2
  201. package/dist/providers/{tithely.js → tithely/index.js} +60 -91
  202. package/dist/providers/tithely/skill.generated.js +8 -0
  203. package/dist/providers/{vercel.d.ts → vercel/index.d.ts} +8 -8
  204. package/dist/providers/vercel/index.js +1038 -0
  205. package/dist/providers/vercel/mcp-ownership.js +212 -0
  206. package/dist/providers/vercel/skill.generated.js +11 -0
  207. package/dist/registry.d.ts +110 -171
  208. package/dist/registry.js +588 -927
  209. package/dist/request-state.js +21 -0
  210. package/dist/resource-read.js +103 -0
  211. package/dist/result-shapes.js +17 -49
  212. package/dist/retired-toolkits.js +1 -1
  213. package/dist/routes/access-tokens.js +3 -6
  214. package/dist/routes/activity-context.js +21 -0
  215. package/dist/routes/activity-disclosure.js +40 -0
  216. package/dist/routes/activity.js +59 -21
  217. package/dist/routes/actor-labels.js +3 -50
  218. package/dist/routes/connect.js +221 -0
  219. package/dist/routes/credentials.js +15 -27
  220. package/dist/routes/mcp.js +365 -130
  221. package/dist/routes/oauth-client-metadata.js +15 -0
  222. package/dist/routes/oauth-management.js +45 -107
  223. package/dist/routes/oauth.js +110 -57
  224. package/dist/routes/operator.js +3 -3
  225. package/dist/routes/shared.d.ts +25 -64
  226. package/dist/routes/shared.js +160 -80
  227. package/dist/routes/skills.js +30 -0
  228. package/dist/routes/ui-config.js +225 -0
  229. package/dist/routes/ui-data.js +40 -35
  230. package/dist/routes/ui.js +66 -56
  231. package/dist/runtime/admission.js +4 -2
  232. package/dist/runtime/call-admission.js +3 -1
  233. package/dist/runtime/connector-scope.js +1 -4
  234. package/dist/runtime/run.js +10 -39
  235. package/dist/runtime/services.js +12 -117
  236. package/dist/runtime/shared-read.js +1 -3
  237. package/dist/runtime/storage.js +8 -1
  238. package/dist/sent-secrets.d.ts +93 -0
  239. package/dist/sent-secrets.js +1013 -0
  240. package/dist/server.js +28 -71
  241. package/dist/skills.js +416 -174
  242. package/dist/sqlite.d.ts +48 -0
  243. package/dist/sqlite.js +181 -0
  244. package/dist/storage/keys.js +443 -0
  245. package/dist/storage/memory.js +16 -4
  246. package/dist/storage/sql.d.ts +66 -0
  247. package/dist/storage/sql.js +543 -0
  248. package/dist/timeout.js +4 -2
  249. package/dist/tool-name.js +17 -0
  250. package/dist/tool-safety.d.ts +9 -35
  251. package/dist/tool-safety.js +20 -40
  252. package/dist/types.d.ts +336 -56
  253. package/dist/types.js +0 -1
  254. package/dist/ui.d.ts +7 -19
  255. package/dist/ui.js +76 -90
  256. package/dist/url-safety.js +3 -6
  257. package/dist/usage-guide.js +146 -0
  258. package/dist/validate.d.ts +7 -0
  259. package/dist/validate.js +309 -47
  260. package/dist/version.d.ts +1 -7
  261. package/dist/version.js +3 -7
  262. package/dist/worker.d.ts +11 -0
  263. package/dist/worker.js +435 -0
  264. package/documentation/README.md +63 -0
  265. package/documentation/architecture.md +696 -231
  266. package/documentation/auth.md +1069 -546
  267. package/documentation/code-mode.md +662 -356
  268. package/documentation/deploying.md +146 -0
  269. package/documentation/integrating.md +159 -0
  270. package/documentation/meta-tools.md +570 -216
  271. package/documentation/operating.md +135 -0
  272. package/documentation/operator-tests.md +97 -0
  273. package/documentation/operator-ui.md +132 -0
  274. package/documentation/provider-migration-0.29.md +65 -0
  275. package/examples/worker/AGENTS.md +34 -12
  276. package/examples/worker/README.md +293 -255
  277. package/examples/worker/kv-to-d1.wrangler.jsonc +26 -0
  278. package/examples/worker/scripts/copy-kv-to-d1.mjs +162 -0
  279. package/examples/worker/src/connecta.config.ts +151 -0
  280. package/examples/worker/src/index.ts +14 -197
  281. package/examples/worker/wrangler.jsonc +15 -35
  282. package/package.json +126 -54
  283. package/templates/node/.dockerignore +1 -2
  284. package/templates/node/.env.example +20 -21
  285. package/templates/node/AGENTS.md +21 -17
  286. package/templates/node/Dockerfile +3 -5
  287. package/templates/node/README.md +140 -58
  288. package/templates/node/docker-compose.yml +11 -12
  289. package/templates/node/package.json +4 -2
  290. package/templates/node/src/connecta.config.ts +119 -0
  291. package/templates/node/src/index.ts +9 -154
  292. package/templates/node/src/provision-token.ts +17 -0
  293. package/AGENTS.md +0 -170
  294. package/dist/artifacts/connector.d.ts +0 -58
  295. package/dist/artifacts/connector.js +0 -730
  296. package/dist/artifacts/document.js +0 -86
  297. package/dist/artifacts/guide.js +0 -140
  298. package/dist/artifacts/html-scan.js +0 -329
  299. package/dist/artifacts/json.js +0 -78
  300. package/dist/artifacts/kv-store.d.ts +0 -20
  301. package/dist/artifacts/kv-store.js +0 -140
  302. package/dist/artifacts/markdown.js +0 -478
  303. package/dist/artifacts/module.d.ts +0 -37
  304. package/dist/artifacts/module.js +0 -66
  305. package/dist/artifacts/operations.d.ts +0 -197
  306. package/dist/artifacts/operations.js +0 -1002
  307. package/dist/artifacts/refresh.d.ts +0 -55
  308. package/dist/artifacts/refresh.js +0 -236
  309. package/dist/artifacts/routes.js +0 -206
  310. package/dist/artifacts/types.d.ts +0 -214
  311. package/dist/artifacts/types.js +0 -22
  312. package/dist/artifacts/validate.d.ts +0 -62
  313. package/dist/artifacts/validate.js +0 -651
  314. package/dist/artifacts.d.ts +0 -6
  315. package/dist/artifacts.js +0 -9
  316. package/dist/auth/bearer.d.ts +0 -11
  317. package/dist/auth/bearer.js +0 -50
  318. package/dist/providers/basecamp.js +0 -445
  319. package/dist/providers/linear.js +0 -217
  320. package/dist/providers/mixpanel.js +0 -247
  321. package/dist/providers/revenuecat.js +0 -317
  322. package/dist/providers/stripe.js +0 -253
  323. package/dist/providers/vercel.js +0 -1253
  324. package/dist/storage/file.d.ts +0 -15
  325. package/dist/storage/file.js +0 -455
  326. package/ethos.md +0 -93
  327. package/examples/worker/src/cloudflare-kv.ts +0 -43
  328. package/examples/worker/src/d1-activity-row.ts +0 -155
  329. package/examples/worker/src/d1-activity.ts +0 -147
  330. package/examples/worker/src/d1-storage.ts +0 -138
  331. package/examples/worker/src/r2-artifact-blobs.ts +0 -29
  332. package/templates/node/src/file-activity.ts +0 -182
@@ -0,0 +1,8 @@
1
+ // Generated by scripts/generate-providers.mjs; do not edit.
2
+ export const skill = {
3
+ "content": "Start with `list_projects` for project IDs and environment slugs, then `list_folders` for absolute paths.\n\nKeep value reads narrow. `list_secrets` returns identifiers only by default, even if the server sends values or comments; use `get_secret` or opt into `includeValues` only when needed. These explicit reads return secrets, including values and comments. Comments are available only from these value-read tools. Do not echo values unless the user asks. Imports follow the same value policy.\n\nValues can reference secrets as `${env.KEY}`. Value reads expand references by default. Use `expandReferences: false` to read the literal reference before editing; updating a value changes only that secret, not the secrets it references. Updates send only named changes. Writes omit values and report `pendingApproval` when an environment's change policy requires approval.\n\nEvery value-free result returns only checked identifiers: UUID or legacy 24-hex IDs, secret keys, positive integer versions, known type/approval enums, environment and tag slugs, absolute paths, and ISO timestamps. Projects expose IDs and environment identifiers; folders expose IDs and paths. Project slugs are withheld because Infisical can derive them from free-text project names. Comments, descriptions, free-form names, reminder notes, and arbitrary nested objects are withheld. `metadataOmitted: true` reports dropped or unavailable metadata; success or pending-approval context remains available. Identifier fields outside the conservative grammar are dropped.\n\nKnown, accepted residual risk: environment slugs are returned as required routing identifiers. Infisical's UI derives them from environment names by default, so secrets entered in those names can appear in returned slugs. Operators must not put secrets in environment names or slugs. Secrets placed in identifiers or key names are out of scope.\n\nThe provider assumes an honest Infisical server and protects against careless human entry of secrets in free text. It does not match submitted values or defend against a malicious server encoding values into valid identifiers. Submitted secret data never joins credential redaction, so later calls in the same program keep their authorized arguments. Client credentials and tokens retain request-scoped credential protection.\n\nThis finite surface has no guarded raw-REST tool. These endpoints return complete collections without a page cursor; narrow the path and avoid recursive/value listings to stay below Connecta's 8 MiB response ceiling. Temporary result paging does not reduce the upstream response size.\n\nUniversal Auth tokens remain in memory only and refresh before expiry. Reads may retry once after a rejected token. Writes refresh a rejected token for a later explicit call and return the auth failure without resending; reconcile the target before another call. Recovery echoes marked `argsRedacted` omit secret values, secret comments, and folder descriptions, so any new call requires the original arguments. The operator's machine identity must belong to each project with the right role; a 403 needs an operator to fix membership or role. US cloud is the default; set `baseUrl: \"https://eu.infisical.com/api\"` for EU cloud or your self-hosted HTTPS API base including `/api`. Preserve the connector id and the `clientId`/`clientSecret` fields when migrating existing credentials.\n\nNo default call budget is assumed. Operators can supply `callAdmission` for their instance's limits. The credential test performs a Universal Auth login only, without reading projects or secrets.\n",
4
+ "instructionsHeading": "Organization instructions",
5
+ "fragments": {
6
+ "guide": "Start with `list_projects` for project IDs and environment slugs, then `list_folders` for absolute paths.\n\nKeep value reads narrow. `list_secrets` returns identifiers only by default, even if the server sends values or comments; use `get_secret` or opt into `includeValues` only when needed. These explicit reads return secrets, including values and comments. Comments are available only from these value-read tools. Do not echo values unless the user asks. Imports follow the same value policy.\n\nValues can reference secrets as `${env.KEY}`. Value reads expand references by default. Use `expandReferences: false` to read the literal reference before editing; updating a value changes only that secret, not the secrets it references. Updates send only named changes. Writes omit values and report `pendingApproval` when an environment's change policy requires approval.\n\nEvery value-free result returns only checked identifiers: UUID or legacy 24-hex IDs, secret keys, positive integer versions, known type/approval enums, environment and tag slugs, absolute paths, and ISO timestamps. Projects expose IDs and environment identifiers; folders expose IDs and paths. Project slugs are withheld because Infisical can derive them from free-text project names. Comments, descriptions, free-form names, reminder notes, and arbitrary nested objects are withheld. `metadataOmitted: true` reports dropped or unavailable metadata; success or pending-approval context remains available. Identifier fields outside the conservative grammar are dropped.\n\nKnown, accepted residual risk: environment slugs are returned as required routing identifiers. Infisical's UI derives them from environment names by default, so secrets entered in those names can appear in returned slugs. Operators must not put secrets in environment names or slugs. Secrets placed in identifiers or key names are out of scope.\n\nThe provider assumes an honest Infisical server and protects against careless human entry of secrets in free text. It does not match submitted values or defend against a malicious server encoding values into valid identifiers. Submitted secret data never joins credential redaction, so later calls in the same program keep their authorized arguments. Client credentials and tokens retain request-scoped credential protection.\n\nThis finite surface has no guarded raw-REST tool. These endpoints return complete collections without a page cursor; narrow the path and avoid recursive/value listings to stay below Connecta's 8 MiB response ceiling. Temporary result paging does not reduce the upstream response size.\n\nUniversal Auth tokens remain in memory only and refresh before expiry. Reads may retry once after a rejected token. Writes refresh a rejected token for a later explicit call and return the auth failure without resending; reconcile the target before another call. Recovery echoes marked `argsRedacted` omit secret values, secret comments, and folder descriptions, so any new call requires the original arguments. The operator's machine identity must belong to each project with the right role; a 403 needs an operator to fix membership or role. US cloud is the default; set `baseUrl: \"https://eu.infisical.com/api\"` for EU cloud or your self-hosted HTTPS API base including `/api`. Preserve the connector id and the `clientId`/`clientSecret` fields when migrating existing credentials.\n\nNo default call budget is assumed. Operators can supply `callAdmission` for their instance's limits. The credential test performs a Universal Auth login only, without reading projects or secrets.\n"
7
+ }
8
+ };
@@ -1,5 +1,6 @@
1
- import { type RemoteMcpAuth } from "../connectors/remote-mcp.js";
2
- import type { Connector, ConnectorCallAdmissionPolicy } from "../types.js";
1
+ import { type RemoteMcpAuth } from "../../connectors/remote-mcp.js";
2
+ import { type ProviderOptions } from "../../provider.js";
3
+ import type { ConnectorCallAdmissionPolicy } from "../../types.js";
3
4
  /** Which of Linear's two hosted MCP endpoints this connection is bound to. */
4
5
  export type LinearAccess = "read-write" | "read-only";
5
6
  /**
@@ -9,14 +10,12 @@ export type LinearAccess = "read-write" | "read-only";
9
10
  * deliberately absent — it now answers 404.
10
11
  */
11
12
  export declare const LINEAR_MCP_ENDPOINTS: Readonly<Record<LinearAccess, string>>;
12
- export interface LinearOptions {
13
+ export interface LinearOptions extends ProviderOptions {
13
14
  /**
14
15
  * Human-readable display name; defaults to "Linear", or
15
16
  * "Linear (read-only)" when `access` is `"read-only"`.
16
17
  */
17
18
  title?: string;
18
- /** Downstream auth ownership. Defaults to one shared deployment grant. */
19
- authScope?: "shared" | "personal";
20
19
  /** Which workspace this is and what decisions it answers. */
21
20
  purpose: string;
22
21
  /**
@@ -37,8 +36,6 @@ export interface LinearOptions {
37
36
  auth?: RemoteMcpAuth;
38
37
  /** Workspace-specific conventions appended to the maintained provider guide. */
39
38
  instructions?: string;
40
- /** Connector-specific inline result limit; omit to inherit the deployment. */
41
- maxResultBytes?: number;
42
39
  /**
43
40
  * Optional per-runtime policy. There is no default: Linear documents no
44
41
  * MCP-specific limit, the GraphQL limits it rides are metered per user per
@@ -47,12 +44,12 @@ export interface LinearOptions {
47
44
  */
48
45
  callAdmission?: ConnectorCallAdmissionPolicy;
49
46
  }
47
+ /** A maintained Linear hosted-MCP connection. */
48
+ export declare const linear: import("../../provider.js").ProviderFactory<LinearOptions>;
50
49
  /**
51
- * One release-reviewed manifest, used both to classify a live tool and as the
52
- * baseline the drift check compares against, so the annotation a caller gets
53
- * and the verdict a check reads can never disagree. Drift must surface as an
54
- * unclassified tool on the approval path (P5), never a quiet re-guess.
50
+ * The reviewed classification in the legacy manifest form.
51
+ *
52
+ * @deprecated Read `linear.definition.classify` instead. This alias is derived
53
+ * from it and retained for existing public imports.
55
54
  */
56
- export declare const LINEAR_VETTED_CATALOG: import("../catalog-drift.js").VettedCatalog;
57
- /** A maintained Linear hosted-MCP connection. */
58
- export declare function linear(id: string, options: LinearOptions): Connector;
55
+ export declare const LINEAR_VETTED_CATALOG: import("../../catalog-drift.js").VettedCatalog;
@@ -0,0 +1,352 @@
1
+ import { skill } from "./skill.generated.js";
2
+ import { remoteMcp, withCredentialDefaults } from "../../connectors/remote-mcp.js";
3
+ import { keys, optionsOf } from "../../config-schema.js";
4
+ import { REMOTE_MCP_AUTH } from "../../connectors/option-shapes.js";
5
+ import { reviewedCatalog } from "../../catalog-drift.js";
6
+ import { defineProvider, PROVIDER_COMMON } from "../../provider.js";
7
+ /**
8
+ * Linear publishes two hosted endpoints. `read-only` is not a client-side
9
+ * filter: it advertises the `read` scope alone, so the token minted for it
10
+ * cannot reach Linear's write APIs at all. The deprecated `/sse` transport is
11
+ * deliberately absent — it now answers 404.
12
+ */
13
+ export const LINEAR_MCP_ENDPOINTS = {
14
+ "read-write": "https://mcp.linear.app/mcp",
15
+ "read-only": "https://mcp.linear.app/mcp/readonly",
16
+ };
17
+ /**
18
+ * Every `save_*` is destructive because Linear's `save_*` tools are upserts:
19
+ * omitting a record id creates, supplying one overwrites in place, and the
20
+ * schema cannot tell them apart.
21
+ */
22
+ const UPSERT = "An upsert: supplying a record id overwrites that record in place, and the schema cannot tell a create from an update.";
23
+ /**
24
+ * The release-reviewed classification (P5), used both to classify a live tool
25
+ * and as the record the drift check compares against, so the annotation a
26
+ * caller gets and the verdict a check reads can never disagree. It is a
27
+ * superset: Linear's hosted `tools/list` varies by plan and enabled features,
28
+ * so a name this workspace never returns costs nothing, while an unlisted new
29
+ * one fails closed. The genuine creates — the `create_*_label` and attachment
30
+ * tools — are plain writes rather than destructive.
31
+ */
32
+ const LINEAR_CLASSIFICATION = {
33
+ tools: {
34
+ // Issues
35
+ list_issues: {
36
+ "verdict": "read",
37
+ "reason": "Reads existing Linear list issues data without changing workspace state.",
38
+ },
39
+ get_issue: {
40
+ "verdict": "read",
41
+ "reason": "Reads existing Linear get issue data without changing workspace state.",
42
+ },
43
+ list_issue_statuses: {
44
+ "verdict": "read",
45
+ "reason": "Reads existing Linear list issue statuses data without changing workspace state.",
46
+ },
47
+ get_issue_status: {
48
+ "verdict": "read",
49
+ "reason": "Reads existing Linear get issue status data without changing workspace state.",
50
+ },
51
+ list_issue_labels: {
52
+ "verdict": "read",
53
+ "reason": "Reads existing Linear list issue labels data without changing workspace state.",
54
+ },
55
+ save_issue: { verdict: "destructive", reason: UPSERT },
56
+ create_issue_label: {
57
+ "verdict": "write",
58
+ "reason": "Creates Linear state through create_issue_label; the reviewed operation only appends.",
59
+ },
60
+ // Projects
61
+ list_projects: {
62
+ "verdict": "read",
63
+ "reason": "Reads existing Linear list projects data without changing workspace state.",
64
+ },
65
+ get_project: {
66
+ "verdict": "read",
67
+ "reason": "Reads existing Linear get project data without changing workspace state.",
68
+ },
69
+ list_project_labels: {
70
+ "verdict": "read",
71
+ "reason": "Reads existing Linear list project labels data without changing workspace state.",
72
+ },
73
+ save_project: { verdict: "destructive", reason: UPSERT },
74
+ // Milestones
75
+ list_milestones: {
76
+ "verdict": "read",
77
+ "reason": "Reads existing Linear list milestones data without changing workspace state.",
78
+ },
79
+ get_milestone: {
80
+ "verdict": "read",
81
+ "reason": "Reads existing Linear get milestone data without changing workspace state.",
82
+ },
83
+ save_milestone: { verdict: "destructive", reason: UPSERT },
84
+ // Initiatives
85
+ list_initiatives: {
86
+ "verdict": "read",
87
+ "reason": "Reads existing Linear list initiatives data without changing workspace state.",
88
+ },
89
+ get_initiative: {
90
+ "verdict": "read",
91
+ "reason": "Reads existing Linear get initiative data without changing workspace state.",
92
+ },
93
+ list_initiative_labels: {
94
+ "verdict": "read",
95
+ "reason": "Reads existing Linear list initiative labels data without changing workspace state.",
96
+ },
97
+ save_initiative: { verdict: "destructive", reason: UPSERT },
98
+ create_initiative_label: {
99
+ "verdict": "write",
100
+ "reason": "Creates Linear state through create_initiative_label; the reviewed operation only appends.",
101
+ },
102
+ // Cycles
103
+ list_cycles: {
104
+ "verdict": "read",
105
+ "reason": "Reads existing Linear list cycles data without changing workspace state.",
106
+ },
107
+ // Comments
108
+ list_comments: {
109
+ "verdict": "read",
110
+ "reason": "Reads existing Linear list comments data without changing workspace state.",
111
+ },
112
+ save_comment: { verdict: "destructive", reason: UPSERT },
113
+ delete_comment: {
114
+ "verdict": "destructive",
115
+ "reason": "Changes or removes existing Linear state through delete_comment.",
116
+ },
117
+ // Documents
118
+ list_documents: {
119
+ "verdict": "read",
120
+ "reason": "Reads existing Linear list documents data without changing workspace state.",
121
+ },
122
+ get_document: {
123
+ "verdict": "read",
124
+ "reason": "Reads existing Linear get document data without changing workspace state.",
125
+ },
126
+ save_document: { verdict: "destructive", reason: UPSERT },
127
+ // Teams and users
128
+ list_teams: {
129
+ "verdict": "read",
130
+ "reason": "Reads existing Linear list teams data without changing workspace state.",
131
+ },
132
+ get_team: { "verdict": "read", "reason": "Reads existing Linear get team data without changing workspace state." },
133
+ list_users: {
134
+ "verdict": "read",
135
+ "reason": "Reads existing Linear list users data without changing workspace state.",
136
+ },
137
+ get_user: { "verdict": "read", "reason": "Reads existing Linear get user data without changing workspace state." },
138
+ get_workspace: {
139
+ "verdict": "read",
140
+ "reason": "Reads existing Linear get workspace data without changing workspace state.",
141
+ },
142
+ // Templates
143
+ list_templates: {
144
+ "verdict": "read",
145
+ "reason": "Reads existing Linear list templates data without changing workspace state.",
146
+ },
147
+ get_template: {
148
+ "verdict": "read",
149
+ "reason": "Reads existing Linear get template data without changing workspace state.",
150
+ },
151
+ // Status updates
152
+ get_status_updates: {
153
+ "verdict": "read",
154
+ "reason": "Reads existing Linear get status updates data without changing workspace state.",
155
+ },
156
+ save_status_update: { verdict: "destructive", reason: UPSERT },
157
+ delete_status_update: {
158
+ "verdict": "destructive",
159
+ "reason": "Changes or removes existing Linear state through delete_status_update.",
160
+ },
161
+ // Releases
162
+ list_release_pipelines: {
163
+ "verdict": "read",
164
+ "reason": "Reads existing Linear list release pipelines data without changing workspace state.",
165
+ },
166
+ list_releases: {
167
+ "verdict": "read",
168
+ "reason": "Reads existing Linear list releases data without changing workspace state.",
169
+ },
170
+ get_release: {
171
+ "verdict": "read",
172
+ "reason": "Reads existing Linear get release data without changing workspace state.",
173
+ },
174
+ list_release_notes: {
175
+ "verdict": "read",
176
+ "reason": "Reads existing Linear list release notes data without changing workspace state.",
177
+ },
178
+ get_release_note: {
179
+ "verdict": "read",
180
+ "reason": "Reads existing Linear get release note data without changing workspace state.",
181
+ },
182
+ save_release: { verdict: "destructive", reason: UPSERT },
183
+ save_release_note: { verdict: "destructive", reason: UPSERT },
184
+ // Code review
185
+ list_diffs: {
186
+ "verdict": "read",
187
+ "reason": "Reads existing Linear list diffs data without changing workspace state.",
188
+ },
189
+ get_diff: { "verdict": "read", "reason": "Reads existing Linear get diff data without changing workspace state." },
190
+ get_diff_threads: {
191
+ "verdict": "read",
192
+ "reason": "Reads existing Linear get diff threads data without changing workspace state.",
193
+ },
194
+ save_diff_comment: { verdict: "destructive", reason: UPSERT },
195
+ resolve_diff_thread: {
196
+ "verdict": "destructive",
197
+ "reason": "Changes or removes existing Linear state through resolve_diff_thread.",
198
+ },
199
+ delete_diff_comment: {
200
+ "verdict": "destructive",
201
+ "reason": "Changes or removes existing Linear state through delete_diff_comment.",
202
+ },
203
+ submit_diff_review: {
204
+ "verdict": "destructive",
205
+ "reason": "Changes or removes existing Linear state through submit_diff_review.",
206
+ },
207
+ merge_diff: { "verdict": "destructive", "reason": "Changes or removes existing Linear state through merge_diff." },
208
+ // Attachments
209
+ get_attachment: {
210
+ "verdict": "read",
211
+ "reason": "Reads existing Linear get attachment data without changing workspace state.",
212
+ },
213
+ prepare_attachment_upload: {
214
+ verdict: "write",
215
+ reason: "Mints an upload URL: a side effect, but it changes no existing record.",
216
+ },
217
+ create_attachment_from_upload: {
218
+ "verdict": "write",
219
+ "reason": "Creates Linear state through create_attachment_from_upload; the reviewed operation only appends.",
220
+ },
221
+ create_attachment: {
222
+ "verdict": "write",
223
+ "reason": "Creates Linear state through create_attachment; the reviewed operation only appends.",
224
+ },
225
+ delete_attachment: {
226
+ "verdict": "destructive",
227
+ "reason": "Changes or removes existing Linear state through delete_attachment.",
228
+ },
229
+ // Explicit issue access.
230
+ share_issue: {
231
+ verdict: "destructive",
232
+ reason: "Changes who can see an existing issue.",
233
+ },
234
+ unshare_issue: {
235
+ verdict: "destructive",
236
+ reason: "Changes who can see an existing issue.",
237
+ },
238
+ // Agent skills
239
+ list_agent_skills: {
240
+ "verdict": "read",
241
+ "reason": "Reads existing Linear list agent skills data without changing workspace state.",
242
+ },
243
+ get_agent_skill: {
244
+ "verdict": "read",
245
+ "reason": "Reads existing Linear get agent skill data without changing workspace state.",
246
+ },
247
+ // Documentation search
248
+ search_documentation: {
249
+ "verdict": "read",
250
+ "reason": "Reads existing Linear search documentation data without changing workspace state.",
251
+ },
252
+ // Customer requests (plan-gated)
253
+ list_customers: {
254
+ "verdict": "read",
255
+ "reason": "Reads existing Linear list customers data without changing workspace state.",
256
+ },
257
+ save_customer: { verdict: "destructive", reason: UPSERT },
258
+ delete_customer: {
259
+ "verdict": "destructive",
260
+ "reason": "Changes or removes existing Linear state through delete_customer.",
261
+ },
262
+ save_customer_need: { verdict: "destructive", reason: UPSERT },
263
+ delete_customer_need: {
264
+ "verdict": "destructive",
265
+ "reason": "Changes or removes existing Linear state through delete_customer_need.",
266
+ },
267
+ // Markdown helper.
268
+ extract_images: {
269
+ verdict: "read",
270
+ reason: "Reads images out of content it is handed and touches no workspace state; the hosted server ships it annotated readOnlyHint: true and idempotentHint: true.",
271
+ },
272
+ },
273
+ };
274
+ /**
275
+ * Connection-independent conventions. The access note and purpose lead the
276
+ * rendered guide; deployment instructions follow it.
277
+ */
278
+ /** The closed options linear() accepts, checked against LinearOptions. */
279
+ const LINEAR_OPTIONS = optionsOf()({
280
+ ...PROVIDER_COMMON,
281
+ ...keys("access"),
282
+ auth: REMOTE_MCP_AUTH,
283
+ });
284
+ /** A maintained Linear hosted-MCP connection. */
285
+ export const linear = defineProvider({
286
+ name: "linear",
287
+ title: "Linear",
288
+ kind: "mcp",
289
+ readme: "Linear",
290
+ bundle: { "baselineGzip": 127244, "maxGzip": 187244 },
291
+ skill,
292
+ options: LINEAR_OPTIONS,
293
+ classify: LINEAR_CLASSIFICATION,
294
+ create(id, options, provider) {
295
+ const access = options.access;
296
+ if (access !== "read-write" && access !== "read-only") {
297
+ throw new Error(`linear("${id}") requires access "read-write" or "read-only".`);
298
+ }
299
+ // Leads the guide because discovery summarizes a connector by its first
300
+ // content line: whether this connection can write at all is the one thing
301
+ // an agent must know before it opens the guide, and `search_tools` shows
302
+ // the summary without the description.
303
+ const accessNote = access === "read-only"
304
+ ? "Read-only connection: bound to Linear's read-only endpoint, whose token is scope-limited downstream, so every write fails at Linear regardless of arguments. Route writes to a connector configured for read-write access."
305
+ : "Read-write connection: treat every `save_`, `create_`, `delete_`, `resolve_`, `submit_`, and `merge_` operation as a write. Connecta classifies the maintained writes explicitly and enforces the configured pool trust policy. Unknown tools without an explicit, uncontradicted read annotation fail closed.";
306
+ return remoteMcp(id, {
307
+ url: LINEAR_MCP_ENDPOINTS[access],
308
+ ...provider.connectorOptions,
309
+ // The title is what browse-time discovery renders; a read-only
310
+ // connection says so there rather than only in a description the caller
311
+ // may not see.
312
+ title: options.title ?? (access === "read-only" ? "Linear (read-only)" : "Linear"),
313
+ description: access === "read-only"
314
+ ? `Linear issue tracking and project planning (read-only) — ${options.purpose}`
315
+ : `Linear issue tracking and project planning — ${options.purpose}`,
316
+ // Linear's MCP endpoint takes an API key the same way it takes an OAuth
317
+ // token — `Authorization: Bearer <yourtoken>` — so only the slot copy is
318
+ // provider-specific and the bearer framing default stands. The
319
+ // bare-header convention belongs to Linear's GraphQL API, not to this
320
+ // endpoint.
321
+ auth: withCredentialDefaults(options.auth ?? { type: "oauth" }, {
322
+ credential: {
323
+ label: "Personal API key",
324
+ description: "A Linear personal API key. It carries the issuing user's full workspace access and is stored encrypted; the read-only endpoint still limits what it can reach.",
325
+ placeholder: "lin_api_…",
326
+ },
327
+ }),
328
+ requireHttps: true,
329
+ classify: provider.classify,
330
+ usageGuide: provider.usageGuide({
331
+ context: [accessNote, `Workspace purpose: ${options.purpose}`],
332
+ // Explicit rather than derived. The derived summary would truncate the
333
+ // access note mid-sentence at 120 characters, and the one thing a
334
+ // browsing agent must not get wrong is whether this connection can
335
+ // write at all ([#342](https://github.com/zackbart/connecta/issues/342)).
336
+ // Not `required`: Linear's own schemas describe each call correctly;
337
+ // the guide adds cross-tool sequence advice worth reading before a
338
+ // write, not before every read.
339
+ summary: access === "read-only"
340
+ ? "Read-only: every write fails at Linear. Id resolution, upsert semantics, and cursor paging."
341
+ : "Read-write. Id resolution, `save_*` upsert semantics, plan-gated areas, and cursor paging.",
342
+ }),
343
+ });
344
+ },
345
+ });
346
+ /**
347
+ * The reviewed classification in the legacy manifest form.
348
+ *
349
+ * @deprecated Read `linear.definition.classify` instead. This alias is derived
350
+ * from it and retained for existing public imports.
351
+ */
352
+ export const LINEAR_VETTED_CATALOG = reviewedCatalog(linear.definition.classify, 'defineProvider("linear")');
@@ -0,0 +1,8 @@
1
+ // Generated by scripts/generate-providers.mjs; do not edit.
2
+ export const skill = {
3
+ "content": "- Issue arguments use `state`, not `status`. Resolve team-specific states through `list_issue_statuses` and use the value format required by the live input schema.\n- Resolve identity before acting. `list_teams`, `list_users`, `list_projects`, `list_issue_statuses`, and `list_issue_labels` return the ids that create and update arguments expect; do not guess a team, status, label, or assignee id.\n- Issues carry a human identifier like `ENG-123` — team key, dash, number — alongside a UUID. Use the identifier the request gave you and resolve it with `get_issue` or `list_issues` when a tool wants an id; never fabricate an identifier or renumber one.\n- `save_*` tools are upserts: omit the record id to create, supply it to update in place. Read the record first when you mean to update, and send only the fields you intend to change — an upsert overwrites what you restate.\n- Labels are the exception to that naming: `create_issue_label` and `create_initiative_label` only ever create.\n- Projects, milestones, and initiatives nest: initiatives contain projects, projects contain milestones and issues, and cycles are per-team time boxes. Scope a search by team or project rather than listing the workspace and filtering afterwards.\n- List tools paginate with a cursor. Thread the returned cursor for the next page instead of raising the page size, and reduce pages inside `execute_code` before returning them.\n- This workspace's catalog is not the whole product. Customer requests, releases, and code review are plan- and feature-gated, so search the catalog for what this connector actually exposes rather than assuming a tool exists.\n- Linear meters the underlying API per user per hour, shared with everything else that credential does. Reuse discovery results within a run and avoid speculative fan-out.\n- An `auth_required` failure means this connector's Linear authorization is missing or expired: run `authorize_connector` for this connector id, then retry the same call unchanged.",
4
+ "instructionsHeading": "Workspace instructions",
5
+ "fragments": {
6
+ "content": "- Issue arguments use `state`, not `status`. Resolve team-specific states through `list_issue_statuses` and use the value format required by the live input schema.\n- Resolve identity before acting. `list_teams`, `list_users`, `list_projects`, `list_issue_statuses`, and `list_issue_labels` return the ids that create and update arguments expect; do not guess a team, status, label, or assignee id.\n- Issues carry a human identifier like `ENG-123` — team key, dash, number — alongside a UUID. Use the identifier the request gave you and resolve it with `get_issue` or `list_issues` when a tool wants an id; never fabricate an identifier or renumber one.\n- `save_*` tools are upserts: omit the record id to create, supply it to update in place. Read the record first when you mean to update, and send only the fields you intend to change — an upsert overwrites what you restate.\n- Labels are the exception to that naming: `create_issue_label` and `create_initiative_label` only ever create.\n- Projects, milestones, and initiatives nest: initiatives contain projects, projects contain milestones and issues, and cycles are per-team time boxes. Scope a search by team or project rather than listing the workspace and filtering afterwards.\n- List tools paginate with a cursor. Thread the returned cursor for the next page instead of raising the page size, and reduce pages inside `execute_code` before returning them.\n- This workspace's catalog is not the whole product. Customer requests, releases, and code review are plan- and feature-gated, so search the catalog for what this connector actually exposes rather than assuming a tool exists.\n- Linear meters the underlying API per user per hour, shared with everything else that credential does. Reuse discovery results within a run and avoid speculative fan-out.\n- An `auth_required` failure means this connector's Linear authorization is missing or expired: run `authorize_connector` for this connector id, then retry the same call unchanged."
7
+ }
8
+ };
@@ -1,5 +1,5 @@
1
- import { type RemoteMcpAuth } from "../connectors/remote-mcp.js";
2
- import type { Connector, ConnectorCallAdmissionPolicy } from "../types.js";
1
+ import { type RemoteMcpAuth } from "../../connectors/remote-mcp.js";
2
+ import type { ConnectorCallAdmissionPolicy } from "../../types.js";
3
3
  export type MixpanelRegion = "us" | "eu" | "in";
4
4
  export declare const MIXPANEL_MCP_ENDPOINTS: Readonly<Record<MixpanelRegion, string>>;
5
5
  export interface MixpanelOptions {
@@ -36,12 +36,7 @@ export interface MixpanelOptions {
36
36
  */
37
37
  callAdmission?: ConnectorCallAdmissionPolicy;
38
38
  }
39
- /**
40
- * One release-reviewed manifest, used both to classify a live tool and as the
41
- * baseline the drift check compares against, so the annotation a caller gets
42
- * and the verdict a check reads can never disagree. Drift must surface as an
43
- * unclassified tool on the approval path (P5), never a quiet re-guess.
44
- */
45
- export declare const MIXPANEL_VETTED_CATALOG: import("../catalog-drift.js").VettedCatalog;
46
39
  /** A maintained Mixpanel hosted-MCP connection. */
47
- export declare function mixpanel(id: string, options: MixpanelOptions): Connector;
40
+ export declare const mixpanel: import("../../provider.js").ProviderFactory<MixpanelOptions>;
41
+ /** @deprecated Read `mixpanel.definition.classify` instead. Kept for existing imports. */
42
+ export declare const MIXPANEL_VETTED_CATALOG: import("../../catalog-drift.js").VettedCatalog;