node-autotask 0.19.0 → 0.21.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 (40) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/MCP_TOOL_CATALOG.json +1397 -10
  3. package/MCP_TOOL_MANIFEST.md +130 -130
  4. package/MCP_TOOL_OVERRIDES.json +1 -1
  5. package/N8N_MCP_MANIFEST.json +44 -9
  6. package/N8N_MCP_MANIFEST.md +8 -8
  7. package/capabilities.json +11135 -2033
  8. package/capabilities.schema.json +39 -0
  9. package/dist/capabilities.cjs +2 -2
  10. package/dist/capabilities.d.cts +9 -0
  11. package/dist/capabilities.d.ts +9 -0
  12. package/dist/capabilities.js +1 -1
  13. package/dist/{chunk-JM52ZU7T.cjs → chunk-CBUY3MKB.cjs} +11134 -2032
  14. package/dist/{chunk-NDK7WYWA.js → chunk-DM67SXCO.js} +11134 -2032
  15. package/dist/{chunk-D5RAQ4DE.js → chunk-GBVUXAUA.js} +3 -3
  16. package/dist/{chunk-7RDR5DSI.cjs → chunk-HEW4WJLC.cjs} +394 -394
  17. package/dist/{chunk-4YKV7ORF.js → chunk-JRSU6PKP.js} +2 -2
  18. package/dist/{chunk-LB2X4X4B.js → chunk-KD6LOSAK.js} +215 -54
  19. package/dist/{chunk-TIM75K3G.cjs → chunk-PMPFQDVM.cjs} +135 -135
  20. package/dist/{chunk-QDYSHAU6.cjs → chunk-QWAWNQEZ.cjs} +223 -62
  21. package/dist/{index-aZ3tCh1h.d.cts → index-ByWYfNog.d.cts} +105 -9
  22. package/dist/{index-DLugNSr7.d.ts → index-DSnuyiTr.d.ts} +105 -9
  23. package/dist/index.cjs +22 -22
  24. package/dist/index.d.cts +2 -2
  25. package/dist/index.d.ts +2 -2
  26. package/dist/index.js +4 -4
  27. package/dist/operations/index.cjs +184 -136
  28. package/dist/operations/index.d.cts +2 -2
  29. package/dist/operations/index.d.ts +2 -2
  30. package/dist/operations/index.js +79 -31
  31. package/dist/pool.cjs +8 -8
  32. package/dist/pool.d.cts +1 -1
  33. package/dist/pool.d.ts +1 -1
  34. package/dist/pool.js +4 -4
  35. package/dist/resources/index.cjs +4 -4
  36. package/dist/resources/index.d.cts +1 -1
  37. package/dist/resources/index.d.ts +1 -1
  38. package/dist/resources/index.js +3 -3
  39. package/docs/API.md +83 -24
  40. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -7,6 +7,33 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.21.0] - 2026-10-21
11
+
12
+ **Structured bag properties, core ops in the catalog, op-key error text (issues #162, #163, #164, #177, #178, #179, #180, #181).** The plan hash moves to `baf3e855956e` (MINOR) — plan-pinned consumers must re-pin.
13
+ - **Bag `properties` (#162).** every object-typed `inputSchema` arg whose prose declares a `{ key?: type (...) }` bag now also carries `properties: [{ name, type, optional, default? }]` (e.g. `companies.query` params: `limit` default 500, `fieldCheck` default true), derived from the same description text at generation time so the two cannot drift. Additive; the prose is unchanged.
14
+ - **Core ops in `MCP_TOOL_CATALOG.catalog` (#163).** the 10 core-profile backing ops (`resources.whoAmI`, `version.get`, `threshold_information.get`, `operations.resolveAny`, `operations.searchAcrossResources`, `{companies,configuration_items,contacts,projects,tickets}.resolve`) are now catalog rows, flagged `core: true` (every row carries `core`); `counts.catalogRows` equals `registryOperations` (1213). `coreProfile` is unchanged.
15
+ - **Property types (#177).** bag `properties` types are now real type expressions (`(number | string)[]` for `ticketIds`, `string` for the date strings, `'find' | 'delete'` for `operations.recovery` action); a test fails on any unrecognised type token.
16
+ - **Literal defaults (#179).** string-literal enum defaults (`companies.unbilledWork` `source`/`rollup`, `contracts.profitability` `labourCostMethod`) and the `operations.fieldCatalog` `include` array default now appear in `properties[].default`; non-literal prose defaults (e.g. 'today') stay prose-only.
17
+ - **Array defaults and bag keys (#180, #181).** `CapabilityArgSchema.properties[].default` is now typed `number | boolean | string | string[]` (also `BagProperty` and `capabilities.schema.json`, `default` allows an array of strings), so `operations.fieldCatalog` `include` default `['fields']` validates; `names` / `maxNameReads` (default false / 20) are now documented for `tickets.fullContext`, `companies.fullProfile` and `configuration_items.profile` and appear in their `properties`. A test checks every record's properties against the schema and every key of a named `*Options` interface against the record bag. `testHash` / `capabilities.json` served text moved.
18
+ - **Served text (#178).** served capability descriptions, the plan and docs point at the op key `operations.resolveAny` instead of the tool name.
19
+ - **Error text (#164).** the pre-request refusals of `operations.fetchMany` / `operations.expandResourceNames` for non-numeric string ids name the op key `operations.resolveAny`, not the tool name.
20
+
21
+ ## [0.20.0] - 2026-10-20
22
+
23
+ **Filter pre-validation, the latest-probe count cache, and the window/search/aggregate served-text corrections (issues #125, #127, #128, #129, #130, #131).** The plan hash moves to `f6a579e0b7a8` (MINOR) — plan-pinned consumers must re-pin.
24
+
25
+ **Invoke-bag filter field-name check (#125).** The bounded query op's invoke bag now name-checks the filter condition field names PRE-REQUEST — every leaf condition's `field` (grouping `and`/`or` recurses into `items`) against the same live-first authority as the #119b includeFields check (the tenant's live entity field metadata through the cache-aware channel, degrading to the vendored spec when that read faults). A refusal costs zero QUERY wire — the query POST and the count probe that anchors `latest` are never issued (a cold fieldCache performs one authority metadata GET first — zero on a warm one) — as one typed `CONFIG_ERROR` with the field-catalog pointer. Under a live-metadata FAULT the vendored spec is the authority, and the resource's plan-pinned live-only fields (the record's `metadata.liveOnlyFields` — the live entity carries them, the vendor model omits them: `time_entries.postedDate`/`postedOnTime`, the W-D3 spec gap) are exempt from the vendored refusal (issue #144 — the pre-#125 behaviour is preserved under degradation; a truly unknown name is still refused). The `count` verb's bag (closed to `filter` + the `fieldCheck` opt-out — issue #145) is name-checked the same way (issue #140 — the documented unchecked scope is the direct queryBounded/queryAll client paths AND the `operations.aggregate` filter, which is grammar-checked only — its groupBy/sum field names ARE checked; name-checking the aggregate filter is a separate follow-up, the op's own field whitelist being the different authority). The one `udf: true` condition per query is exempt (a tenant UDF name is absent from the vendored spec by definition); `fieldCheck: false` opts out of both name checks (the shape/grammar checks always run). Direct queryBounded/queryAll client paths remain unchecked by design (the #119b rule).
26
+
27
+ **Latest-walk count-probe cache (#127).** The count-anchored `latest: N` mechanism is the query family's dominant latency term (20–45 s of serial rowless vendor count calls per invocation, live-measured 2026-10-19) — a re-asked "top N" within 30 s now makes ZERO extra vendor count calls. The walk's count probes (the initial `count(F)` + every `id gt T` threshold probe) are cached per client in a short-TTL in-process store (30 s TTL, 4096-entry memory guard, keyed by resource + canonical filter, cleared on any real write through the same client — a probe in flight across the write is discarded by the cache's invalidation epoch (issue #139 — the cleared cache is not re-populated with a pre-write count). Never cached: the blind-surface/pinned-empty sentinels (the plan-pinned stamps stay fresh), a total of 0, errors, and anything outside the probe path — the plain `count` op and `operations.aggregate` promise fresh totals. Process-internal: no served keys, no config surface; a write made elsewhere shows up once the 30 s TTL expires (the documented snapshot trade). The truncation guard covers the growth-of-total direction only (issue #157): a stale-LOW total within the TTL is resolved by ONE fresh re-probe of the total when a full-set walk truncates against a cached total — a larger fresh total continues the walk to it, and LATEST_WINDOW_INCOMPLETE stands only when the fresh probe confirms the cached value (bounded: at most one extra count probe per walk), never by the guard alone — and a total of 0 is never cached, so a repeated call after an out-of-band insert re-probes instead of returning a false empty.
28
+
29
+ **Window ops default to the hard cap (#128).** The date-window family (time_entries/billing_items/invoices) silently defaulted to the first 25 rows; the default is now the 500-row hard cap, and the served text names the escalation path for >500 rows (the bounded query op with the same date-window filter, 2500-row walk cap). Envelope shapes unchanged.
30
+
31
+ **postedWithin is a dateWorked window (#129).** The served text now states unambiguously that the window is on `dateWorked` (entries worked within [from, to]); "postedWithin" is the historical name — its 'posted' is the posted/unposted split counted over the returned rows (the `postedDate` exist/notExist narrowing + postedCount/unpostedCount), never a posted-date window. The postedDate-window variant is rejected: the vendored TimeEntryModel declares no postedDate filter and ww29-class zones 500 on postedDate filters only when the `posted` narrowing is set — `time_entries.dateWorkedWindow` is the unambiguous op.
32
+
33
+ **Aggregate caps + the partial marker (#130).** The served `autotask_aggregate` text states the exact caps (2500-row scan = the bounded-query hard max; 100-group top cap, default top 25, larger top clamped never raised) and the explicit rule: a truncated aggregate (hasMore true or groupsTruncated true — totalScanned stays reported for reasoning) is a PARTIAL answer — never a tenant-wide total — with the escalation path (narrow the filter so the set fits the caps; the bounded query op with the same filter within its 2500-row walk cap; raw REST for the rest). The envelope flags were already honest (no code change — no new count keys, zero-sentinel rule); the partial-marker flags are now unit-pinned.
34
+
35
+ **tickets.search scope (#131).** The served text names the searched-field scope: a vendor `contains` filter on title ONLY (no free-text search, no matched-field reporting), plus the vendor-contains caveat — looser than a literal substring (case/token matching), so a search can return MORE hits than a local title-substring check (measured 2026-10-19: 25 vs 24); a per-field `contains` filter in tickets.query is the precise tool. The issue's non-title-field hypothesis is not documented (unverified from source).
36
+
10
37
  ## [0.19.0] - 2026-10-19
11
38
 
12
39
  **Maintenance-page detection at any status, pattern-miss capture, and two manifest/packaging corrections (issues #114, #115, #123).** The plan hash moves to `078f288c2800` (MINOR) — plan-pinned consumers must re-pin.