@zackbart/connecta 0.24.3 → 0.25.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 (145) hide show
  1. package/AGENTS.md +58 -30
  2. package/CHANGELOG.md +317 -1
  3. package/README.md +5 -6
  4. package/dist/advertised-schema.js +53 -0
  5. package/dist/auth/downstream-oauth.js +490 -106
  6. package/dist/branding.d.ts +31 -2
  7. package/dist/branding.js +116 -8
  8. package/dist/call-admission.js +139 -113
  9. package/dist/catalog-service.js +141 -105
  10. package/dist/catalog.js +258 -33
  11. package/dist/concurrency.js +24 -23
  12. package/dist/connector-scope.js +6 -37
  13. package/dist/connectors/api.d.ts +3 -3
  14. package/dist/connectors/api.js +10 -2
  15. package/dist/connectors/guarded-fetch.js +34 -4
  16. package/dist/connectors/remote-mcp.d.ts +6 -5
  17. package/dist/connectors/remote-mcp.js +325 -245
  18. package/dist/credential-contract.d.ts +9 -0
  19. package/dist/credential-rules.js +2 -2
  20. package/dist/credentials.d.ts +6 -1
  21. package/dist/credentials.js +45 -3
  22. package/dist/errors.d.ts +11 -3
  23. package/dist/errors.js +2 -1
  24. package/dist/execute.js +363 -257
  25. package/dist/executor-admission.js +67 -50
  26. package/dist/executors/quickjs-runtime.js +4 -2
  27. package/dist/executors/quickjs.js +251 -210
  28. package/dist/fix-prompt.js +37 -0
  29. package/dist/index.d.ts +11 -2
  30. package/dist/index.js +63 -21
  31. package/dist/invocation.js +324 -285
  32. package/dist/meta-tools.js +304 -114
  33. package/dist/oauth-callback-outcome.js +94 -0
  34. package/dist/oauth-sealing.js +29 -0
  35. package/dist/operator-ui/fix-prompts.js +87 -0
  36. package/dist/operator-ui/generated.js +2 -2
  37. package/dist/operator-ui/model.d.ts +46 -1
  38. package/dist/operator-ui/setup-commands.js +53 -0
  39. package/dist/operator-ui/view.js +109 -2
  40. package/dist/program-source.js +205 -0
  41. package/dist/providers/cloudflare.d.ts +14 -2
  42. package/dist/providers/cloudflare.js +107 -16
  43. package/dist/providers/linear.d.ts +26 -4
  44. package/dist/providers/linear.js +19 -4
  45. package/dist/providers/mixpanel.d.ts +16 -3
  46. package/dist/providers/mixpanel.js +13 -2
  47. package/dist/providers/notion.d.ts +8 -1
  48. package/dist/providers/notion.js +85 -12
  49. package/dist/providers/revenuecat.d.ts +30 -4
  50. package/dist/providers/revenuecat.js +70 -5
  51. package/dist/providers/stripe.d.ts +10 -3
  52. package/dist/providers/stripe.js +30 -4
  53. package/dist/providers/vercel.js +12 -2
  54. package/dist/registry.d.ts +13 -5
  55. package/dist/registry.js +317 -258
  56. package/dist/routes/activity.js +120 -137
  57. package/dist/routes/credentials.js +174 -163
  58. package/dist/routes/mcp.js +129 -70
  59. package/dist/routes/oauth-management.js +60 -71
  60. package/dist/routes/oauth.js +44 -16
  61. package/dist/routes/operator.js +82 -0
  62. package/dist/routes/shared.d.ts +2 -0
  63. package/dist/routes/ui-data.js +210 -0
  64. package/dist/routes/ui.js +64 -32
  65. package/dist/runtime/admission.js +43 -0
  66. package/dist/runtime/call-admission.js +67 -0
  67. package/dist/runtime/connector-scope.js +72 -0
  68. package/dist/runtime/run.js +174 -0
  69. package/dist/runtime/services.js +130 -0
  70. package/dist/runtime/storage.js +66 -0
  71. package/dist/server.js +111 -89
  72. package/dist/skills.js +1 -1
  73. package/dist/storage/file.js +39 -2
  74. package/dist/storage/memory.js +28 -16
  75. package/dist/timeout.js +17 -47
  76. package/dist/types.d.ts +64 -7
  77. package/dist/ui.d.ts +16 -2
  78. package/dist/ui.js +68 -176
  79. package/dist/url-safety.js +157 -0
  80. package/dist/version.d.ts +1 -1
  81. package/dist/version.js +1 -1
  82. package/documentation/architecture.md +368 -182
  83. package/documentation/auth.md +277 -176
  84. package/documentation/code-mode.md +479 -329
  85. package/documentation/meta-tools.md +494 -417
  86. package/ethos.md +44 -47
  87. package/examples/worker/AGENTS.md +2 -1
  88. package/examples/worker/README.md +62 -14
  89. package/examples/worker/src/d1-storage.ts +116 -0
  90. package/examples/worker/src/index.ts +18 -21
  91. package/examples/worker/wrangler.jsonc +16 -4
  92. package/package.json +11 -4
  93. package/templates/node/.env.example +3 -3
  94. package/templates/node/AGENTS.md +5 -4
  95. package/templates/node/README.md +2 -1
  96. package/templates/node/package.json +1 -1
  97. package/templates/node/src/index.ts +23 -22
  98. package/dist/auth/downstream-oauth.d.ts +0 -200
  99. package/dist/catalog-fingerprint.d.ts +0 -19
  100. package/dist/catalog-limits.d.ts +0 -9
  101. package/dist/catalog-service.d.ts +0 -263
  102. package/dist/catalog.d.ts +0 -87
  103. package/dist/concurrency.d.ts +0 -3
  104. package/dist/connectors/guarded-fetch.d.ts +0 -92
  105. package/dist/credential-rules.d.ts +0 -85
  106. package/dist/execute.d.ts +0 -154
  107. package/dist/executor-result.d.ts +0 -10
  108. package/dist/executors/quickjs-child.d.ts +0 -1
  109. package/dist/executors/quickjs-protocol.d.ts +0 -67
  110. package/dist/favicon.d.ts +0 -1
  111. package/dist/identity.d.ts +0 -4
  112. package/dist/invocation.d.ts +0 -74
  113. package/dist/mcp-result.d.ts +0 -8
  114. package/dist/meta-tools.d.ts +0 -129
  115. package/dist/operator-ui/generated.d.ts +0 -2
  116. package/dist/operator-ui/view.d.ts +0 -151
  117. package/dist/result-shapes.d.ts +0 -13
  118. package/dist/retired-toolkits.d.ts +0 -2
  119. package/dist/routes/activity.d.ts +0 -2
  120. package/dist/routes/credentials.d.ts +0 -2
  121. package/dist/routes/mcp.d.ts +0 -10
  122. package/dist/routes/oauth-management.d.ts +0 -2
  123. package/dist/routes/oauth.d.ts +0 -2
  124. package/dist/routes/ui.d.ts +0 -2
  125. package/dist/server.d.ts +0 -9
  126. package/dist/skills.d.ts +0 -44
  127. package/dist/timeout.d.ts +0 -21
  128. package/dist/tool-safety.d.ts +0 -9
  129. package/documentation/call-admission.md +0 -158
  130. package/documentation/cloudflare.md +0 -471
  131. package/documentation/connector-guides.md +0 -176
  132. package/documentation/connectors.md +0 -431
  133. package/documentation/linear.md +0 -193
  134. package/documentation/mixpanel.md +0 -160
  135. package/documentation/notion.md +0 -308
  136. package/documentation/operations.md +0 -359
  137. package/documentation/operator-ui.md +0 -135
  138. package/documentation/optional-modules-upgrade.md +0 -243
  139. package/documentation/provider-conventions.md +0 -729
  140. package/documentation/request-admission.md +0 -204
  141. package/documentation/revenuecat.md +0 -305
  142. package/documentation/storage-and-credentials.md +0 -254
  143. package/documentation/stripe.md +0 -262
  144. package/documentation/upgrading.md +0 -768
  145. package/documentation/vercel.md +0 -241
@@ -1,3 +1,6 @@
1
+ import { Deferred, Duration, Effect } from "effect";
2
+ import { admit, provideAdmissionProgram } from "./runtime/admission.js";
3
+ import { fromSignal, runEdge } from "./runtime/run.js";
1
4
  /**
2
5
  * A stable, machine-readable admission failure. Overload is retryable; caller
3
6
  * cancellation and shutdown are terminal for this invocation.
@@ -98,57 +101,15 @@ export class AdmissionController {
98
101
  };
99
102
  }
100
103
  acquire(options = {}) {
101
- if (this.closed) {
102
- this.closedTotal++;
103
- return Promise.reject(new ExecutorAdmissionError("executor_closed", "Executor is shutting down."));
104
- }
105
- if (options.signal?.aborted) {
106
- this.cancelledTotal++;
107
- return Promise.reject(new ExecutorAdmissionError("executor_cancelled", "Execution was cancelled before admission."));
108
- }
109
- if (this.active < this.concurrency) {
110
- this.active++;
111
- this.admittedTotal++;
112
- return Promise.resolve(this.makeLease(0));
113
- }
114
- if (this.waiters.length >= this.maxQueueSize) {
115
- this.rejectedTotal++;
116
- return Promise.reject(this.overloaded("Executor queue is full."));
117
- }
118
- return new Promise((resolve, reject) => {
119
- const waiter = {
120
- queuedAt: Date.now(),
121
- resolve,
122
- reject,
123
- ...(options.signal ? { signal: options.signal } : {}),
124
- };
125
- waiter.onAbort = () => {
126
- if (!this.remove(waiter))
127
- return;
128
- this.cleanup(waiter);
129
- this.cancelledTotal++;
130
- reject(new ExecutorAdmissionError("executor_cancelled", "Execution was cancelled while queued."));
131
- };
132
- options.signal?.addEventListener("abort", waiter.onAbort, { once: true });
133
- waiter.timer = setTimeout(() => {
134
- if (!this.remove(waiter))
135
- return;
136
- this.cleanup(waiter);
137
- this.rejectedTotal++;
138
- reject(this.overloaded(`Executor admission timed out after ${this.queueTimeoutMs}ms.`));
139
- }, this.queueTimeoutMs);
140
- this.waiters.push(waiter);
141
- this.queuedTotal++;
142
- });
104
+ return runEdge(admit(this, options));
143
105
  }
144
106
  close() {
145
107
  if (this.closed)
146
108
  return;
147
109
  this.closed = true;
148
110
  for (const waiter of this.waiters.splice(0)) {
149
- this.cleanup(waiter);
150
111
  this.closedTotal++;
151
- waiter.reject(new ExecutorAdmissionError("executor_closed", "Executor is shutting down."));
112
+ Deferred.doneUnsafe(waiter.outcome, Effect.fail(new ExecutorAdmissionError("executor_closed", "Executor is shutting down.")));
152
113
  }
153
114
  }
154
115
  overloaded(message) {
@@ -176,14 +137,13 @@ export class AdmissionController {
176
137
  const waiter = this.waiters.shift();
177
138
  if (!waiter)
178
139
  return;
179
- this.cleanup(waiter);
180
140
  const waitMs = Math.max(0, Date.now() - waiter.queuedAt);
181
141
  this.admittedTotal++;
182
142
  this.queueWaitCount++;
183
143
  this.queueWaitTotalMs += waitMs;
184
144
  this.queueWaitMaxMs = Math.max(this.queueWaitMaxMs, waitMs);
185
145
  this.active++;
186
- waiter.resolve(this.makeLease(waitMs));
146
+ Deferred.doneUnsafe(waiter.outcome, Effect.succeed(this.makeLease(waitMs)));
187
147
  }
188
148
  remove(waiter) {
189
149
  const index = this.waiters.indexOf(waiter);
@@ -192,12 +152,69 @@ export class AdmissionController {
192
152
  this.waiters.splice(index, 1);
193
153
  return true;
194
154
  }
155
+ // The waiting fiber was interrupted — an Effect caller's scope closed, not a
156
+ // signal. Withdraw the waiter if it is still queued; if release() handed it
157
+ // a slot in the same breath, give the slot back, because nobody is left to
158
+ // receive the lease. (A line comment, not JSDoc: TypeScript copies a private
159
+ // member's JSDoc into the published declaration.)
195
160
  cleanup(waiter) {
196
- if (waiter.timer !== undefined)
197
- clearTimeout(waiter.timer);
198
- if (waiter.onAbort) {
199
- waiter.signal?.removeEventListener("abort", waiter.onAbort);
161
+ if (this.remove(waiter)) {
162
+ this.cancelledTotal++;
163
+ return Effect.void;
200
164
  }
165
+ if (!Deferred.isDoneUnsafe(waiter.outcome))
166
+ return Effect.void;
167
+ return Deferred.await(waiter.outcome).pipe(Effect.tap((lease) => Effect.sync(() => lease.release())), Effect.ignore);
168
+ }
169
+ // The admission program, handed to src/runtime/admission.ts. It lives in a
170
+ // static block because the class declaration ships, private member names
171
+ // and all: a new method or field would change the published `.d.ts`, and a
172
+ // static block is the one place outside an instance method that may read
173
+ // this bookkeeping while emitting nothing there.
174
+ static {
175
+ provideAdmissionProgram((controller, signal) => Effect.suspend(() => {
176
+ if (controller.closed) {
177
+ controller.closedTotal++;
178
+ return Effect.fail(new ExecutorAdmissionError("executor_closed", "Executor is shutting down."));
179
+ }
180
+ if (signal?.aborted) {
181
+ controller.cancelledTotal++;
182
+ return Effect.fail(new ExecutorAdmissionError("executor_cancelled", "Execution was cancelled before admission."));
183
+ }
184
+ if (controller.active < controller.concurrency) {
185
+ controller.active++;
186
+ controller.admittedTotal++;
187
+ return Effect.succeed(controller.makeLease(0));
188
+ }
189
+ if (controller.waiters.length >= controller.maxQueueSize) {
190
+ controller.rejectedTotal++;
191
+ return Effect.fail(controller.overloaded("Executor queue is full."));
192
+ }
193
+ const waiter = {
194
+ queuedAt: Date.now(),
195
+ outcome: Deferred.makeUnsafe(),
196
+ };
197
+ controller.waiters.push(waiter);
198
+ controller.queuedTotal++;
199
+ // A timeout or abort settles the waiter only if it takes it out of the
200
+ // queue first. Otherwise release() or close() got there in the same
201
+ // tick, and the outcome they recorded is the answer.
202
+ const giveUp = (count, error) => Effect.suspend(() => {
203
+ if (!controller.remove(waiter))
204
+ return Deferred.await(waiter.outcome);
205
+ count();
206
+ return Effect.fail(error());
207
+ });
208
+ // One flat race; each contender is a forked fiber.
209
+ const contenders = [
210
+ Deferred.await(waiter.outcome),
211
+ Effect.sleep(Duration.millis(controller.queueTimeoutMs)).pipe(Effect.andThen(giveUp(() => controller.rejectedTotal++, () => controller.overloaded(`Executor admission timed out after ${controller.queueTimeoutMs}ms.`)))),
212
+ ];
213
+ if (signal) {
214
+ contenders.push(fromSignal(signal).pipe(Effect.catch(() => giveUp(() => controller.cancelledTotal++, () => new ExecutorAdmissionError("executor_cancelled", "Execution was cancelled while queued.")))));
215
+ }
216
+ return Effect.raceAllFirst(contenders).pipe(Effect.onInterrupt(() => controller.cleanup(waiter)));
217
+ }));
201
218
  }
202
219
  }
203
220
  /** Preserve the one-method Workers seam while recognizing richer Node executors. */
@@ -9,6 +9,7 @@
9
9
  // provider args/results must be JSON-serializable.
10
10
  import { getQuickJS, } from "quickjs-emscripten";
11
11
  import { msg } from "../errors.js";
12
+ import { withoutProgramTerminator } from "../program-source.js";
12
13
  import { hostCallLabel, MAX_QUICKJS_LOG_TRANSPORT_BYTES, serializedBytes, } from "./quickjs-protocol.js";
13
14
  /** Load and compile the shared QuickJS WASM module before a run budget starts. */
14
15
  export async function prepareQuickJs() {
@@ -70,8 +71,9 @@ export function normalizeCode(code) {
70
71
  // lines — models routinely prefix their code with a `//` or `/* */` note,
71
72
  // which would otherwise defeat the detection and wrap the whole thing.
72
73
  const head = c.replace(/^(?:\s+|\/\/[^\n]*|\/\*[\s\S]*?\*\/)+/, "");
73
- if (/^async\b/.test(head) || head.startsWith("("))
74
- return c;
74
+ if (/^async\b/.test(head) || head.startsWith("(")) {
75
+ return withoutProgramTerminator(c);
76
+ }
75
77
  return `async () => {\n${c}\n}`;
76
78
  }
77
79
  /**