node-autotask 0.19.0 → 0.20.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.
- package/CHANGELOG.md +16 -0
- package/MCP_TOOL_CATALOG.json +6 -6
- package/MCP_TOOL_MANIFEST.md +127 -127
- package/N8N_MCP_MANIFEST.json +44 -9
- package/N8N_MCP_MANIFEST.md +8 -8
- package/capabilities.json +1938 -1826
- package/capabilities.schema.json +6 -0
- package/dist/capabilities.cjs +2 -2
- package/dist/capabilities.js +1 -1
- package/dist/{chunk-NDK7WYWA.js → chunk-2T77J2ZM.js} +1937 -1825
- package/dist/{chunk-JM52ZU7T.cjs → chunk-FLYTKJKV.cjs} +1937 -1825
- package/dist/{chunk-LB2X4X4B.js → chunk-GA6UCX3Z.js} +207 -51
- package/dist/{chunk-4YKV7ORF.js → chunk-JEJUFXHX.js} +2 -2
- package/dist/{chunk-QDYSHAU6.cjs → chunk-L6V66V22.cjs} +215 -59
- package/dist/{chunk-TIM75K3G.cjs → chunk-RMLGOCGA.cjs} +135 -135
- package/dist/{chunk-D5RAQ4DE.js → chunk-XSYJB4IW.js} +3 -3
- package/dist/{chunk-7RDR5DSI.cjs → chunk-YH5CPRDN.cjs} +394 -394
- package/dist/{index-aZ3tCh1h.d.cts → index-AN-NjLi9.d.cts} +100 -9
- package/dist/{index-DLugNSr7.d.ts → index-CvLLsOCP.d.ts} +100 -9
- package/dist/index.cjs +22 -22
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +4 -4
- package/dist/operations/index.cjs +184 -136
- package/dist/operations/index.d.cts +2 -2
- package/dist/operations/index.d.ts +2 -2
- package/dist/operations/index.js +79 -31
- package/dist/pool.cjs +8 -8
- package/dist/pool.d.cts +1 -1
- package/dist/pool.d.ts +1 -1
- package/dist/pool.js +4 -4
- package/dist/resources/index.cjs +4 -4
- package/dist/resources/index.d.cts +1 -1
- package/dist/resources/index.d.ts +1 -1
- package/dist/resources/index.js +3 -3
- package/docs/API.md +78 -22
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.20.0] - 2026-10-20
|
|
11
|
+
|
|
12
|
+
**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.
|
|
13
|
+
|
|
14
|
+
**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).
|
|
15
|
+
|
|
16
|
+
**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.
|
|
17
|
+
|
|
18
|
+
**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.
|
|
19
|
+
|
|
20
|
+
**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.
|
|
21
|
+
|
|
22
|
+
**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.
|
|
23
|
+
|
|
24
|
+
**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).
|
|
25
|
+
|
|
10
26
|
## [0.19.0] - 2026-10-19
|
|
11
27
|
|
|
12
28
|
**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.
|
package/MCP_TOOL_CATALOG.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"generatedBy": "scripts/build-tool-catalog.mjs",
|
|
3
|
-
"generatedAt": "2026-10-
|
|
4
|
-
"planHash": "
|
|
3
|
+
"generatedAt": "2026-10-20T01:49:50.366Z",
|
|
4
|
+
"planHash": "f6a579e0b7a8544f6e477a730d21a9ba031536392d8dbaeb2f73c61ca290ae91",
|
|
5
5
|
"metaTools": [
|
|
6
6
|
{
|
|
7
7
|
"name": "autotask_catalog",
|
|
@@ -9891,7 +9891,7 @@
|
|
|
9891
9891
|
{
|
|
9892
9892
|
"operation": "time_entries.dateWorkedWindow",
|
|
9893
9893
|
"tool": "autotask_timeEntry_date_worked_window",
|
|
9894
|
-
"purpose": "The
|
|
9894
|
+
"purpose": "The unambiguous-named alias for time_entries.postedWithin (issue #66): the dateWorked window read with the posted/unposted split, counted in one pass — same wire, same result (incl. truncated). The window is ON dateWorked (entries worked within [from, to]); \"postedWithin\" keeps its historical name (its \"posted\" is the posted/unposted split over the returned rows, never a posted-date window).",
|
|
9895
9895
|
"preferredWhen": null,
|
|
9896
9896
|
"backingOperation": "time_entries.dateWorkedWindow",
|
|
9897
9897
|
"effect": "read",
|
|
@@ -10170,7 +10170,7 @@
|
|
|
10170
10170
|
{
|
|
10171
10171
|
"operation": "time_entries.postedWithin",
|
|
10172
10172
|
"tool": "autotask_timeEntry_posted_within",
|
|
10173
|
-
"purpose": "Get time entries
|
|
10173
|
+
"purpose": "Get time entries WORKED within an inclusive dateWorked window with the posted/unposted split, counted in one pass. The window is ON the dateWorked field — the name's \"posted\" is the posted/unposted SPLIT counted over the returned rows (the server-side postedDate exist|notExist predicate), never a posted-date window: no postedDate window op exists (the vendored TimeEntryModel declares no postedDate filter, and ww29-class zones 500 on postedDate filters ONLY WHEN the `posted` narrowing is set — omit `posted` on such zones — W-D3). The counts cover the returned rows only; truncated flags the capped window. time_entries.dateWorkedWindow is the unambiguous name.",
|
|
10174
10174
|
"preferredWhen": null,
|
|
10175
10175
|
"backingOperation": "time_entries.postedWithin",
|
|
10176
10176
|
"effect": "read",
|
|
@@ -20634,7 +20634,7 @@
|
|
|
20634
20634
|
{
|
|
20635
20635
|
"operation": "tickets.search",
|
|
20636
20636
|
"tool": "autotask_ticket_search",
|
|
20637
|
-
"purpose": "Search ticket records by text (contains on the
|
|
20637
|
+
"purpose": "Search ticket records by text (a vendor contains filter on title only — the vendor exposes no free-text search and no matched-field reporting).",
|
|
20638
20638
|
"preferredWhen": null,
|
|
20639
20639
|
"backingOperation": "tickets.search",
|
|
20640
20640
|
"effect": "read",
|
|
@@ -20725,7 +20725,7 @@
|
|
|
20725
20725
|
{
|
|
20726
20726
|
"operation": "operations.aggregate",
|
|
20727
20727
|
"tool": "autotask_aggregate",
|
|
20728
|
-
"purpose": "Fold any query surface into groups/sums/totals in one bounded call — or count it with the vendor count endpoint when no folding is needed — with blind-surface and truncation honesty; date fields bucket via the closed groupBy suffix <field>@month | @week | @year (ISO labels, UTC-anchored)",
|
|
20728
|
+
"purpose": "Fold any query surface into groups/sums/totals in one bounded call — or count it with the vendor count endpoint when no folding is needed — with blind-surface and truncation honesty (caps documented: the walk scans at most 2500 rows and top keeps at most 100 groups — a truncated aggregate is a PARTIAL answer, never a tenant-wide total); date fields bucket via the closed groupBy suffix <field>@month | @week | @year (ISO labels, UTC-anchored)",
|
|
20729
20729
|
"preferredWhen": "For existence checks and totals over any queryable table (count mode is one call vs a 50k-char page); group-by/sum folds the vendor has no endpoint for; a targeted read is cheaper when you need the rows",
|
|
20730
20730
|
"backingOperation": "operations.aggregate",
|
|
20731
20731
|
"effect": "read",
|