node-autotask 0.16.0 → 0.17.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 (37) hide show
  1. package/N8N_MCP_MANIFEST.json +2 -2
  2. package/N8N_MCP_MANIFEST.md +3 -3
  3. package/README.md +36 -0
  4. package/capabilities.json +4 -4
  5. package/dist/capabilities.cjs +2 -2
  6. package/dist/capabilities.js +1 -1
  7. package/dist/{chunk-MAYYTYV5.cjs → chunk-4RJG73GY.cjs} +37 -17
  8. package/dist/{chunk-EWMG3HHU.cjs → chunk-5ZGXWS4E.cjs} +3 -3
  9. package/dist/{chunk-JIDR3NPV.js → chunk-6SP6GJJR.js} +3 -3
  10. package/dist/{chunk-VCGC6YCI.cjs → chunk-DQIZUZWP.cjs} +135 -135
  11. package/dist/{chunk-NB254T3F.js → chunk-EGR2ZLYM.js} +49 -39
  12. package/dist/{chunk-U6JUHHMB.js → chunk-HC6YWPIY.js} +36 -16
  13. package/dist/{chunk-L3TK4CN5.cjs → chunk-NQVD2XLH.cjs} +429 -419
  14. package/dist/{chunk-GWALLMAM.js → chunk-UV2PECAL.js} +2 -2
  15. package/dist/{index-CUsvZndu.d.ts → index-BAFdPxjG.d.ts} +56 -7
  16. package/dist/{index-leMyBJze.d.cts → index-CjC0oWZX.d.cts} +56 -7
  17. package/dist/index.cjs +22 -22
  18. package/dist/index.d.cts +2 -2
  19. package/dist/index.d.ts +2 -2
  20. package/dist/index.js +4 -4
  21. package/dist/operations/index.cjs +103 -103
  22. package/dist/operations/index.d.cts +12 -6
  23. package/dist/operations/index.d.ts +12 -6
  24. package/dist/operations/index.js +2 -2
  25. package/dist/pool.cjs +8 -8
  26. package/dist/pool.d.cts +1 -1
  27. package/dist/pool.d.ts +1 -1
  28. package/dist/pool.js +4 -4
  29. package/dist/resources/index.cjs +4 -4
  30. package/dist/resources/index.d.cts +1 -1
  31. package/dist/resources/index.d.ts +1 -1
  32. package/dist/resources/index.js +3 -3
  33. package/docs/API.md +34 -7
  34. package/examples/basic.ts +2 -2
  35. package/examples/mcp-server-http.ts +5 -4
  36. package/examples/mcp-server.ts +3 -3
  37. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "schema": "node-autotask n8n consumer mcp projection v1",
3
- "generatedAt": "2026-10-17T13:48:43.907Z",
3
+ "generatedAt": "2026-10-18T23:23:18.804Z",
4
4
  "generator": "scripts/project-n8n-mcp.mjs",
5
5
  "inputs": {
6
6
  "capabilities": "capabilities.json (the capability registry — the single source of truth)",
@@ -3667,6 +3667,6 @@
3667
3667
  "approvalGatedWrites": 2,
3668
3668
  "destructiveExcluded": 3
3669
3669
  },
3670
- "capabilitiesHash": "fd92667b96dd9c74d9bbda2a34bf50b9791e2f236a6d2bb50b50a02a1d064882",
3670
+ "capabilitiesHash": "26246eab57263743486ab1afda89379b7b26462c592c5b104e727e337de92886",
3671
3671
  "curationHash": "e19117ce73e38d9aded3be7e7f077a4e185d2e10294622b76c17d67f63cf9e3b"
3672
3672
  }
@@ -1,6 +1,6 @@
1
1
  # N8N MCP Manifest — node-autotask (consumer projection)
2
2
 
3
- <!-- GENERATED by scripts/project-n8n-mcp.mjs at 2026-10-17T13:48:43.907Z — do not hand-edit. -->
3
+ <!-- GENERATED by scripts/project-n8n-mcp.mjs at 2026-10-18T23:23:18.804Z — do not hand-edit. -->
4
4
 
5
5
  The n8n CONSUMER projection of the capability registry: the canonical source for what the
6
6
  n8n-side MCP tools must expose. The SDK is canonical — this is a projection of it, never a
@@ -282,6 +282,6 @@ only via a recorded change to `n8n-mcp.curation.json`.
282
282
 
283
283
  ## Meta
284
284
 
285
- - generatedAt: 2026-10-17T13:48:43.907Z
286
- - capabilitiesHash: fd92667b96dd9c74d9bbda2a34bf50b9791e2f236a6d2bb50b50a02a1d064882
285
+ - generatedAt: 2026-10-18T23:23:18.804Z
286
+ - capabilitiesHash: 26246eab57263743486ab1afda89379b7b26462c592c5b104e727e337de92886
287
287
  - curationHash: e19117ce73e38d9aded3be7e7f077a4e185d2e10294622b76c17d67f63cf9e3b
package/README.md CHANGED
@@ -147,6 +147,42 @@ length and a two-character prefix per value — never a full value. See
147
147
  [`docs/LIVE-TESTING.md`](./docs/LIVE-TESTING.md) §0b.
148
148
 
149
149
 
150
+ ### The full variable set
151
+
152
+ `.env.example` is the committed template; `.env*` is gitignored, so real values never enter git.
153
+
154
+ ```sh
155
+ cp .env.example .env # then fill in the three credentials
156
+ ```
157
+
158
+ Optional settings are **commented out with a sample value** — uncomment a line to set it. For example
159
+ `AUTOTASK_PROFILE=agent` selects the conservative agent profile (page 25, 8,000/hr, 20 s timeout,
160
+ 1 retry, 3 concurrent), and `AUTOTASK_MAX_RETRIES=1` is that profile's retry budget. Leave the five
161
+ server-layer overrides unset rather than blank: an empty value is *invalid* for them by design
162
+ (fail-closed), so a stray `AUTOTASK_MAX_RETRIES=` stops startup with an error naming the variable.
163
+
164
+ | variable | read by | meaning |
165
+ |---|---|---|
166
+ | `AUTOTASK_TRACKING_IDENTIFIER` | `bin/doctor.js`, examples, live scripts | API tracking identifier (aliases: `AUTOTASK_API_CODE`, `AUTOTASK_API_INTEGRATION_CODE`) |
167
+ | `AUTOTASK_USERNAME` | same | API user (alias: `AUTOTASK_USER`) |
168
+ | `AUTOTASK_SECRET` | same | secret — see the single-quote contract above |
169
+ | `AUTOTASK_ZONE` | doctor, examples, live scripts | **catalog name**, not a host (default `old-australian` = webservices6); `other` requires a base URL — the template lists all 23 |
170
+ | `AUTOTASK_BASE_URL` | doctor, examples, live scripts | explicit REST base; **wins** over the zone; include `/atservicesrest` |
171
+ | `AUTOTASK_IMPERSONATION_ID` | doctor, examples | optional `ImpersonationResourceId` header |
172
+ | `AUTOTASK_PROFILE` | reference MCP servers | `library` (default) / `agent` — the agent profile's numbers are compared in the template and in *Agent profile* above |
173
+ | `AUTOTASK_RATE_LIMIT_PER_HOUR` | reference MCP servers | hourly limiter: a positive integer, or `0` / `off` to disable |
174
+ | `AUTOTASK_MAX_CONCURRENT` | reference MCP servers | concurrency guard (vendor max 10) |
175
+ | `AUTOTASK_TIMEOUT_MS` | reference MCP servers | whole-call timeout |
176
+ | `AUTOTASK_MAX_RETRIES` | reference MCP servers | retry budget (`0` disables) |
177
+ | `AUTOTASK_UNTRUSTED_WRAP` | MCP servers | `on` (default) / `off` — the `<untrusted_content>` projection |
178
+ | `AUTOTASK_GATEWAY_MODE` | `examples/mcp-server-http.ts` | `on` for multi-tenant gateway mode (per-request credentials) |
179
+ | `PORT` | `examples/mcp-server-http.ts` | listen port (default 7437) |
180
+ | `AUTOTASK_ENV_FILE` | live scripts | alternate `.env` path (shell variables always win) |
181
+
182
+ The SDK itself never reads `process.env`: pass `apiIntegrationCode` / `userName` / `secret`
183
+ explicitly, or call `loadAutotaskCredentialsFromEnv()`.
184
+
185
+
150
186
  ## Agent profile (conservative limits for LLM-driven servers)
151
187
 
152
188
  `profile: 'agent'` on the config switches the SDK to conservative limits for
package/capabilities.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
- "generatedAt": "2026-10-17T13:48:43.536Z",
2
+ "generatedAt": "2026-10-18T23:23:18.606Z",
3
3
  "groups": {
4
4
  "B": {
5
5
  "planHash": "bd88648453f58ede018062ce66acefacb672fecaa450af89f421057809971e14",
6
- "builtAt": "2026-10-17T13:48:43.535Z",
6
+ "builtAt": "2026-10-18T23:23:18.605Z",
7
7
  "records": [
8
8
  {
9
9
  "id": "appointments.count",
@@ -56168,7 +56168,7 @@
56168
56168
  },
56169
56169
  "A": {
56170
56170
  "planHash": "bd88648453f58ede018062ce66acefacb672fecaa450af89f421057809971e14",
56171
- "builtAt": "2026-10-17T13:48:43.536Z",
56171
+ "builtAt": "2026-10-18T23:23:18.606Z",
56172
56172
  "records": [
56173
56173
  {
56174
56174
  "id": "companies.count",
@@ -112388,7 +112388,7 @@
112388
112388
  },
112389
112389
  "operations": {
112390
112390
  "planHash": "bd88648453f58ede018062ce66acefacb672fecaa450af89f421057809971e14",
112391
- "builtAt": "2026-10-17T13:48:43.536Z",
112391
+ "builtAt": "2026-10-18T23:23:18.606Z",
112392
112392
  "records": [
112393
112393
  {
112394
112394
  "id": "operations.aggregate",
@@ -2,9 +2,9 @@
2
2
 
3
3
 
4
4
 
5
- var _chunkEWMG3HHUcjs = require('./chunk-EWMG3HHU.cjs');
5
+ var _chunk5ZGXWS4Ecjs = require('./chunk-5ZGXWS4E.cjs');
6
6
 
7
7
 
8
8
 
9
9
 
10
- exports.CAPABILITIES = _chunkEWMG3HHUcjs.CAPABILITIES; exports.CAPABILITY_GROUPS = _chunkEWMG3HHUcjs.CAPABILITY_GROUPS; exports.CAPABILITY_PLAN_HASHES = _chunkEWMG3HHUcjs.CAPABILITY_PLAN_HASHES;
10
+ exports.CAPABILITIES = _chunk5ZGXWS4Ecjs.CAPABILITIES; exports.CAPABILITY_GROUPS = _chunk5ZGXWS4Ecjs.CAPABILITY_GROUPS; exports.CAPABILITY_PLAN_HASHES = _chunk5ZGXWS4Ecjs.CAPABILITY_PLAN_HASHES;
@@ -2,7 +2,7 @@ import {
2
2
  CAPABILITIES,
3
3
  CAPABILITY_GROUPS,
4
4
  CAPABILITY_PLAN_HASHES
5
- } from "./chunk-JIDR3NPV.js";
5
+ } from "./chunk-6SP6GJJR.js";
6
6
  export {
7
7
  CAPABILITIES,
8
8
  CAPABILITY_GROUPS,
@@ -1,6 +1,6 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2; var _class3; var _class4; var _class5; var _class6;
2
2
 
3
- var _chunkEWMG3HHUcjs = require('./chunk-EWMG3HHU.cjs');
3
+ var _chunk5ZGXWS4Ecjs = require('./chunk-5ZGXWS4E.cjs');
4
4
 
5
5
  // src/auth.ts
6
6
  var AUTH_HEADERS = {
@@ -171,6 +171,7 @@ var AutotaskError = class extends Error {
171
171
 
172
172
 
173
173
 
174
+ /** Legacy unlabeled id list (issue #116) — see `AutotaskErrorOptions.resourceIds`; the labeled companion rides on `details.idRefs`. */
174
175
 
175
176
 
176
177
 
@@ -15655,7 +15656,7 @@ function unwrapItems(body, operation) {
15655
15656
  }
15656
15657
  return { items: body.items, pageDetails: body.pageDetails };
15657
15658
  }
15658
- function unwrapItem(body, id, operation) {
15659
+ function unwrapItem(body, id, operation, entity) {
15659
15660
  if (!isRecord2(body) || !("item" in body)) {
15660
15661
  throw new AutotaskError("Expected the item envelope { item }; got a different shape", {
15661
15662
  code: "INVALID_RESPONSE",
@@ -15671,6 +15672,7 @@ function unwrapItem(body, id, operation) {
15671
15672
  {
15672
15673
  httpStatus: 200,
15673
15674
  resourceIds: id !== void 0 ? [id] : void 0,
15675
+ ...id !== void 0 && entity !== void 0 ? { details: { idRefs: [{ entity, id }] } } : {},
15674
15676
  operation,
15675
15677
  suggestedAction: "Verify the id, or resolve the record by name first."
15676
15678
  }
@@ -15991,7 +15993,7 @@ function capabilitySets() {
15991
15993
  const fieldOps = /* @__PURE__ */ new Map();
15992
15994
  const udfOps = /* @__PURE__ */ new Map();
15993
15995
  const resources = /* @__PURE__ */ new Set();
15994
- for (const rec of _chunkEWMG3HHUcjs.CAPABILITIES) {
15996
+ for (const rec of _chunk5ZGXWS4Ecjs.CAPABILITIES) {
15995
15997
  if (rec.resource === "operations") continue;
15996
15998
  resources.add(rec.resource);
15997
15999
  if (rec.operation === "getFieldInfo") fieldOps.set(rec.resource, rec);
@@ -16991,6 +16993,19 @@ function decodeFileData(body) {
16991
16993
  { code: "INVALID_RESPONSE", category: "server" }
16992
16994
  );
16993
16995
  }
16996
+ var DEPLURAL_EXCEPTIONS = {
16997
+ tag_aliase: "tag_alias"
16998
+ };
16999
+ function entityNameFromPath(resourcePath) {
17000
+ const segment = resourcePath.slice(resourcePath.lastIndexOf("/") + 1);
17001
+ const snake = segment.replace(/([A-Z])/g, (_m, c, i) => (i > 0 ? `_` : "") + c.toLowerCase()).replace(/_{2,}/g, "_");
17002
+ if (snake.endsWith("ies")) return `${snake.slice(0, -3)}y`;
17003
+ if (snake.endsWith("s")) {
17004
+ const stripped = snake.slice(0, -1);
17005
+ return _nullishCoalesce(DEPLURAL_EXCEPTIONS[stripped], () => ( stripped));
17006
+ }
17007
+ return snake;
17008
+ }
16994
17009
  var BaseResource = class {
16995
17010
 
16996
17011
 
@@ -17000,6 +17015,10 @@ var BaseResource = class {
17000
17015
  get resourcePath() {
17001
17016
  return this.config.resourcePath;
17002
17017
  }
17018
+ /** The vendor entity this resource's ids identify (issue #116 — the `details.idRefs` label, e.g. `company`). */
17019
+ get entityName() {
17020
+ return entityNameFromPath(this.resourcePath);
17021
+ }
17003
17022
  /** Parent-scoped template (from the config); undefined for top-level resources. */
17004
17023
  get parentScopedPath() {
17005
17024
  return this.config.parentScopedPath;
@@ -17507,7 +17526,7 @@ var BaseResource = class {
17507
17526
  async getGlobal(id, fresh = false) {
17508
17527
  const numeric = parseIdentifier(id, "id");
17509
17528
  const res = await this.cachedGet(`${this.resourcePath}/${numeric}`, `${this.config.key}.get`, fresh, this.config.key);
17510
- return unwrapItem(res, numeric, `${this.config.key}.get`);
17529
+ return unwrapItem(res, numeric, `${this.config.key}.get`, this.entityName);
17511
17530
  }
17512
17531
  /**
17513
17532
  * V2 merge read: a FRESH single-record GET that skips response redaction
@@ -17529,7 +17548,7 @@ var BaseResource = class {
17529
17548
  skipResponseRedaction: true,
17530
17549
  maxRetries: _optionalChain([readOpts, 'optionalAccess', _172 => _172.maxRetries])
17531
17550
  });
17532
- return unwrapItem(res, numeric, `${this.config.key}.get`);
17551
+ return unwrapItem(res, numeric, `${this.config.key}.get`, this.entityName);
17533
17552
  }
17534
17553
  /**
17535
17554
  * Issue #34 fallback merge read: a FRESH parent-scoped single-record GET
@@ -17548,13 +17567,13 @@ var BaseResource = class {
17548
17567
  skipResponseRedaction: true,
17549
17568
  maxRetries: _optionalChain([readOpts, 'optionalAccess', _173 => _173.maxRetries])
17550
17569
  });
17551
- return unwrapItem(res, numeric, `${this.config.key}.get`);
17570
+ return unwrapItem(res, numeric, `${this.config.key}.get`, this.entityName);
17552
17571
  }
17553
17572
  /** Parent-scoped `GET .../{parentId}/<Child>/{id}` → `{ item }` unwrapped. */
17554
17573
  async getScopedRaw(parentId, id, fresh = false) {
17555
17574
  const numeric = parseIdentifier(id, "id");
17556
17575
  const res = await this.cachedGet(this.scopedItemPath(parentId, id), `${this.config.key}.get`, fresh, this.config.key);
17557
- return unwrapItem(res, numeric, `${this.config.key}.get`);
17576
+ return unwrapItem(res, numeric, `${this.config.key}.get`, this.entityName);
17558
17577
  }
17559
17578
  /**
17560
17579
  * Attachment single-read: the vendor answers the model DIRECTLY (swagger),
@@ -17564,23 +17583,23 @@ var BaseResource = class {
17564
17583
  async getScopedModel(parentId, id, fresh = false) {
17565
17584
  const numeric = parseIdentifier(id, "id");
17566
17585
  const res = await this.cachedGet(this.scopedItemPath(parentId, id), `${this.config.key}.get`, fresh, this.config.key);
17567
- return this.unwrapModelLike(res, numeric);
17586
+ return this.unwrapModelLike(res, numeric, this.entityName);
17568
17587
  }
17569
- unwrapModelLike(body, id) {
17588
+ unwrapModelLike(body, id, entity) {
17570
17589
  if (!isRecord2(body)) {
17571
17590
  throw new AutotaskError(
17572
17591
  `Expected an attachment model (or { item } / { items }) envelope for ID ${id}; got a different shape`,
17573
- { code: "INVALID_RESPONSE", category: "server", resourceIds: [id] }
17592
+ { code: "INVALID_RESPONSE", category: "server", resourceIds: [id], details: { idRefs: [{ entity, id }] } }
17574
17593
  );
17575
17594
  }
17576
17595
  if (Object.keys(body).length === 0) {
17577
- throw new NotFoundError(`The record with ID ${id} was not found`, { httpStatus: 200, resourceIds: [id] });
17596
+ throw new NotFoundError(`The record with ID ${id} was not found`, { httpStatus: 200, resourceIds: [id], details: { idRefs: [{ entity, id }] } });
17578
17597
  }
17579
- if ("item" in body) return unwrapItem(body, id);
17598
+ if ("item" in body) return unwrapItem(body, id, void 0, entity);
17580
17599
  if (Array.isArray(body.items)) {
17581
17600
  const first = body.items[0];
17582
17601
  if (first === null || first === void 0) {
17583
- throw new NotFoundError(`The record with ID ${id} was not found`, { httpStatus: 200, resourceIds: [id] });
17602
+ throw new NotFoundError(`The record with ID ${id} was not found`, { httpStatus: 200, resourceIds: [id], details: { idRefs: [{ entity, id }] } });
17584
17603
  }
17585
17604
  return first;
17586
17605
  }
@@ -17928,7 +17947,7 @@ var BaseResource = class {
17928
17947
  if (!isRecord2(res)) {
17929
17948
  throw new AutotaskError(
17930
17949
  `Expected the deleted attachment model for ID ${numeric}; got a different shape`,
17931
- { code: "INVALID_RESPONSE", category: "server", resourceIds: [numeric] }
17950
+ { code: "INVALID_RESPONSE", category: "server", resourceIds: [numeric], details: { idRefs: [{ entity: this.entityName, id: numeric }] } }
17932
17951
  );
17933
17952
  }
17934
17953
  return res;
@@ -18319,9 +18338,9 @@ var BaseResource = class {
18319
18338
  const resource = RESOURCE_KEY_BY_PATH[entityPath];
18320
18339
  const res = await this.cachedGet(`${entityPath}/${numeric}`, `${this.config.key}.fetchRecord`, fresh, resource);
18321
18340
  if (this.config.attachmentGet) {
18322
- return this.unwrapModelLike(res, numeric);
18341
+ return this.unwrapModelLike(res, numeric, entityNameFromPath(entityPath));
18323
18342
  }
18324
- return unwrapItem(res, numeric, `${this.config.key}.fetchRecord`);
18343
+ return unwrapItem(res, numeric, `${this.config.key}.fetchRecord`, entityNameFromPath(entityPath));
18325
18344
  }
18326
18345
  /**
18327
18346
  * `getContext` part fetch: a single-record read that degrades to `null`
@@ -18428,6 +18447,7 @@ var BaseResource = class {
18428
18447
  {
18429
18448
  code: "RESOLUTION_AMBIGUOUS",
18430
18449
  resourceIds: ids,
18450
+ details: { idRefs: ids.map((cid) => ({ entity: this.entityName, id: cid })) },
18431
18451
  // issue #59 PR-B: the miss-channel pointer (the generic floor names
18432
18452
  // the resource's own search op — reachable only where searchFields
18433
18453
  // is non-empty, so the named op always exists here).
@@ -18564,7 +18584,7 @@ var BaseResource = class {
18564
18584
  const ids = matches.map((m) => m.id).filter((id) => typeof id === "number");
18565
18585
  throw new ResolutionError(
18566
18586
  `findBy${field}: "${value}" is ambiguous on ${this.config.key} (matched ${matches.length} records)`,
18567
- { code: "RESOLUTION_AMBIGUOUS", resourceIds: ids }
18587
+ { code: "RESOLUTION_AMBIGUOUS", resourceIds: ids, details: { idRefs: ids.map((cid) => ({ entity: this.entityName, id: cid })) } }
18568
18588
  );
18569
18589
  }
18570
18590
  return matches[0];
@@ -2,7 +2,7 @@
2
2
  var CAPABILITY_GROUPS = {
3
3
  "B": {
4
4
  "planHash": "bd88648453f58ede018062ce66acefacb672fecaa450af89f421057809971e14",
5
- "builtAt": "2026-10-17T13:48:43.535Z",
5
+ "builtAt": "2026-10-18T23:23:18.605Z",
6
6
  "records": [
7
7
  {
8
8
  "id": "appointments.count",
@@ -56167,7 +56167,7 @@ var CAPABILITY_GROUPS = {
56167
56167
  },
56168
56168
  "A": {
56169
56169
  "planHash": "bd88648453f58ede018062ce66acefacb672fecaa450af89f421057809971e14",
56170
- "builtAt": "2026-10-17T13:48:43.536Z",
56170
+ "builtAt": "2026-10-18T23:23:18.606Z",
56171
56171
  "records": [
56172
56172
  {
56173
56173
  "id": "companies.count",
@@ -112387,7 +112387,7 @@ var CAPABILITY_GROUPS = {
112387
112387
  },
112388
112388
  "operations": {
112389
112389
  "planHash": "bd88648453f58ede018062ce66acefacb672fecaa450af89f421057809971e14",
112390
- "builtAt": "2026-10-17T13:48:43.536Z",
112390
+ "builtAt": "2026-10-18T23:23:18.606Z",
112391
112391
  "records": [
112392
112392
  {
112393
112393
  "id": "operations.aggregate",
@@ -2,7 +2,7 @@
2
2
  var CAPABILITY_GROUPS = {
3
3
  "B": {
4
4
  "planHash": "bd88648453f58ede018062ce66acefacb672fecaa450af89f421057809971e14",
5
- "builtAt": "2026-10-17T13:48:43.535Z",
5
+ "builtAt": "2026-10-18T23:23:18.605Z",
6
6
  "records": [
7
7
  {
8
8
  "id": "appointments.count",
@@ -56167,7 +56167,7 @@ var CAPABILITY_GROUPS = {
56167
56167
  },
56168
56168
  "A": {
56169
56169
  "planHash": "bd88648453f58ede018062ce66acefacb672fecaa450af89f421057809971e14",
56170
- "builtAt": "2026-10-17T13:48:43.536Z",
56170
+ "builtAt": "2026-10-18T23:23:18.606Z",
56171
56171
  "records": [
56172
56172
  {
56173
56173
  "id": "companies.count",
@@ -112387,7 +112387,7 @@ var CAPABILITY_GROUPS = {
112387
112387
  },
112388
112388
  "operations": {
112389
112389
  "planHash": "bd88648453f58ede018062ce66acefacb672fecaa450af89f421057809971e14",
112390
- "builtAt": "2026-10-17T13:48:43.536Z",
112390
+ "builtAt": "2026-10-18T23:23:18.606Z",
112391
112391
  "records": [
112392
112392
  {
112393
112393
  "id": "operations.aggregate",