@togglhq/cli 1.11.82 → 1.11.84

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/README.md CHANGED
@@ -282,7 +282,7 @@ Disable product analytics:
282
282
  TOGGL_PRODUCT_ANALYTICS=off
283
283
  ```
284
284
 
285
- Optional error reporting via Sentry is off unless you set `TOGGL_SENTRY=1` and `SENTRY_DSN`.
285
+ Error reporting is on by default. It sends a redacted error category, the stack trace with package-relative file paths, the CLI, Node and OS versions, and sampled request timings without query strings. It never sends command arguments, output, exception text, your hostname, local paths, or your project's dependency list. Disable it with `TOGGL_SENTRY=off`, or send it to your own Sentry project with `TOGGL_SENTRY_DSN`.
286
286
 
287
287
  ## License
288
288
 
package/build/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { a as CommanderError, i as shutdownCliTelemetry, n as captureCliException, r as initCliTelemetry, t as createProgram } from "./program-DZlKCm-L.js";
2
+ import { a as CommanderError, i as shutdownCliTelemetry, n as captureCliException, r as initCliTelemetry, t as createProgram } from "./program-oQlvs6CQ.js";
3
3
  import { readFileSync } from "node:fs";
4
4
  import { dirname, join } from "node:path";
5
5
  import { fileURLToPath } from "node:url";
package/build/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import { t as createProgram } from "./program-DZlKCm-L.js";
1
+ import { t as createProgram } from "./program-oQlvs6CQ.js";
2
2
  export { createProgram };
@@ -5495,10 +5495,6 @@ function _joinExpects$1(values$1, separator) {
5495
5495
  */
5496
5496
  const ISO_DATE_REGEX$1 = /^\d{4}-(?:0[1-9]|1[0-2])-(?:[12]\d|0[1-9]|3[01])$/u;
5497
5497
  /**
5498
- * [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) date-time regex.
5499
- */
5500
- const ISO_DATE_TIME_REGEX$1 = /^\d{4}-(?:0[1-9]|1[0-2])-(?:[12]\d|0[1-9]|3[01])[T ](?:0\d|1\d|2[0-3]):[0-5]\d$/u;
5501
- /**
5502
5498
  * [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) timestamp regex. Allows a
5503
5499
  * space as a date/time separator and an optional space before the UTC offset.
5504
5500
  */
@@ -5552,22 +5548,6 @@ function isoDate$1(message$1) {
5552
5548
  };
5553
5549
  }
5554
5550
  /* @__NO_SIDE_EFFECTS__ */
5555
- function isoDateTime$1(message$1) {
5556
- return {
5557
- kind: "validation",
5558
- type: "iso_date_time",
5559
- reference: isoDateTime$1,
5560
- async: false,
5561
- expects: null,
5562
- requirement: ISO_DATE_TIME_REGEX$1,
5563
- message: message$1,
5564
- "~run"(dataset, config$1) {
5565
- if (dataset.typed && !this.requirement.test(dataset.value)) _addIssue$1(this, "date-time", dataset, config$1);
5566
- return dataset;
5567
- }
5568
- };
5569
- }
5570
- /* @__NO_SIDE_EFFECTS__ */
5571
5551
  function isoTimestamp(message$1) {
5572
5552
  return {
5573
5553
  kind: "validation",
@@ -10799,7 +10779,7 @@ const PublicMeEntryRequestSchema = /* @__PURE__ */ object$2({
10799
10779
  ]))
10800
10780
  });
10801
10781
  //#endregion
10802
- //#region ../../node_modules/.pnpm/@toggl+queries@2.2.79_@tanstack+react-query@5.99.0_react@19.2.5__@toggl+sync@0.2.4_reac_56300fbe33d90fb3e87cf472df5e3bc8/node_modules/@toggl/queries/dist/org/invitation/requests.mjs
10782
+ //#region ../../node_modules/.pnpm/@toggl+queries@2.2.81_@tanstack+react-query@5.99.0_react@19.2.5__@toggl+sync@0.2.4_reac_7f3699a62de19d0eb5476883f6a27f4a/node_modules/@toggl/queries/dist/org/invitation/requests.mjs
10803
10783
  async function getInvitations(httpClient, signal) {
10804
10784
  return (await httpClient.get(`invitations`, { signal })).json();
10805
10785
  }
@@ -10816,7 +10796,7 @@ async function resendInvitation(httpClient, organization_id, organization_user_i
10816
10796
  return (await httpClient.post(`organizations/${organization_id}/invitations/${organization_user_id}/resend`, { signal })).json();
10817
10797
  }
10818
10798
  //#endregion
10819
- //#region ../../node_modules/.pnpm/@toggl+queries@2.2.79_@tanstack+react-query@5.99.0_react@19.2.5__@toggl+sync@0.2.4_reac_56300fbe33d90fb3e87cf472df5e3bc8/node_modules/@toggl/queries/dist/org/utils/requests.mjs
10799
+ //#region ../../node_modules/.pnpm/@toggl+queries@2.2.81_@tanstack+react-query@5.99.0_react@19.2.5__@toggl+sync@0.2.4_reac_7f3699a62de19d0eb5476883f6a27f4a/node_modules/@toggl/queries/dist/org/utils/requests.mjs
10820
10800
  function buildSearchParams(params, flattenArrays = false) {
10821
10801
  const searchParams = new URLSearchParams();
10822
10802
  Object.entries(params).forEach(([key, value]) => {
@@ -10828,7 +10808,7 @@ function buildSearchParams(params, flattenArrays = false) {
10828
10808
  return searchParams;
10829
10809
  }
10830
10810
  //#endregion
10831
- //#region ../../node_modules/.pnpm/@toggl+queries@2.2.79_@tanstack+react-query@5.99.0_react@19.2.5__@toggl+sync@0.2.4_reac_56300fbe33d90fb3e87cf472df5e3bc8/node_modules/@toggl/queries/dist/org/organization-user/requests.mjs
10811
+ //#region ../../node_modules/.pnpm/@toggl+queries@2.2.81_@tanstack+react-query@5.99.0_react@19.2.5__@toggl+sync@0.2.4_reac_7f3699a62de19d0eb5476883f6a27f4a/node_modules/@toggl/queries/dist/org/organization-user/requests.mjs
10832
10812
  async function getOrganizationUser(httpClient, organization_id, organization_user_id, signal) {
10833
10813
  return (await httpClient.get(`organizations/${organization_id}/users/${organization_user_id}`, { signal })).json();
10834
10814
  }
@@ -10842,7 +10822,7 @@ async function patchOrganizationUserActive(httpClient, organization_id, organiza
10842
10822
  return (await httpClient.patch(`organizations/${organization_id}/users/${organization_user_id}/active_status/${status}`, { signal })).json();
10843
10823
  }
10844
10824
  //#endregion
10845
- //#region ../../node_modules/.pnpm/@toggl+queries@2.2.79_@tanstack+react-query@5.99.0_react@19.2.5__@toggl+sync@0.2.4_reac_56300fbe33d90fb3e87cf472df5e3bc8/node_modules/@toggl/queries/dist/org/workspace/requests.mjs
10825
+ //#region ../../node_modules/.pnpm/@toggl+queries@2.2.81_@tanstack+react-query@5.99.0_react@19.2.5__@toggl+sync@0.2.4_reac_7f3699a62de19d0eb5476883f6a27f4a/node_modules/@toggl/queries/dist/org/workspace/requests.mjs
10846
10826
  async function getWorkspaces(httpClient, organization_id, signal) {
10847
10827
  return (await httpClient.get(`organizations/${organization_id}/workspaces`, { signal })).json();
10848
10828
  }
@@ -10851,7 +10831,7 @@ async function getWorkspaceUserMeRoles(httpClient, organization_id, workspace_id
10851
10831
  }
10852
10832
  const WorkingHoursCreateInputSchema = /* @__PURE__ */ object$2({
10853
10833
  working_hours: /* @__PURE__ */ pipe$2(/* @__PURE__ */ number$2(), /* @__PURE__ */ maxValue$1(168)),
10854
- starting_hours: /* @__PURE__ */ optional$1(/* @__PURE__ */ pipe$2(/* @__PURE__ */ number$2(), /* @__PURE__ */ minValue$1(0), /* @__PURE__ */ maxValue$1(24))),
10834
+ starting_hours: /* @__PURE__ */ optional$1(/* @__PURE__ */ pipe$2(/* @__PURE__ */ number$2(), /* @__PURE__ */ maxValue$1(24))),
10855
10835
  weekday: /* @__PURE__ */ optional$1(/* @__PURE__ */ pipe$2(/* @__PURE__ */ number$2(), /* @__PURE__ */ minValue$1(0), /* @__PURE__ */ maxValue$1(6)))
10856
10836
  });
10857
10837
  const WorkingHoursUpdateInputSchema = /* @__PURE__ */ object$2({
@@ -10862,7 +10842,7 @@ const WorkingHoursUpdateInputSchema = /* @__PURE__ */ object$2({
10862
10842
  });
10863
10843
  const StatusOKSchema = /* @__PURE__ */ object$2({ status: /* @__PURE__ */ string$1() });
10864
10844
  //#endregion
10865
- //#region ../../node_modules/.pnpm/@toggl+queries@2.2.79_@tanstack+react-query@5.99.0_react@19.2.5__@toggl+sync@0.2.4_reac_56300fbe33d90fb3e87cf472df5e3bc8/node_modules/@toggl/queries/dist/org/holiday-calendar/requests.mjs
10845
+ //#region ../../node_modules/.pnpm/@toggl+queries@2.2.81_@tanstack+react-query@5.99.0_react@19.2.5__@toggl+sync@0.2.4_reac_7f3699a62de19d0eb5476883f6a27f4a/node_modules/@toggl/queries/dist/org/holiday-calendar/requests.mjs
10866
10846
  async function holidayListDates(httpClient, organization_id, { year, country }, signal) {
10867
10847
  return (await httpClient.get(`holidays/organizations/${organization_id}/calendar/dates`, {
10868
10848
  signal,
@@ -10873,12 +10853,12 @@ async function holidayListDates(httpClient, organization_id, { year, country },
10873
10853
  })).json();
10874
10854
  }
10875
10855
  //#endregion
10876
- //#region ../../node_modules/.pnpm/@toggl+queries@2.2.79_@tanstack+react-query@5.99.0_react@19.2.5__@toggl+sync@0.2.4_reac_56300fbe33d90fb3e87cf472df5e3bc8/node_modules/@toggl/queries/dist/shared-data/status/requests.mjs
10856
+ //#region ../../node_modules/.pnpm/@toggl+queries@2.2.81_@tanstack+react-query@5.99.0_react@19.2.5__@toggl+sync@0.2.4_reac_7f3699a62de19d0eb5476883f6a27f4a/node_modules/@toggl/queries/dist/shared-data/status/requests.mjs
10877
10857
  async function getStatus(httpClient, signal) {
10878
10858
  return (await httpClient.get(`shared_data/api/status`, { signal })).json();
10879
10859
  }
10880
10860
  //#endregion
10881
- //#region ../../node_modules/.pnpm/@toggl+queries@2.2.79_@tanstack+react-query@5.99.0_react@19.2.5__@toggl+sync@0.2.4_reac_56300fbe33d90fb3e87cf472df5e3bc8/node_modules/@toggl/queries/dist/org/timeoff/requests.mjs
10861
+ //#region ../../node_modules/.pnpm/@toggl+queries@2.2.81_@tanstack+react-query@5.99.0_react@19.2.5__@toggl+sync@0.2.4_reac_7f3699a62de19d0eb5476883f6a27f4a/node_modules/@toggl/queries/dist/org/timeoff/requests.mjs
10882
10862
  async function timeoffListMyEntries(httpClient, organization_id, { from, to }, signal) {
10883
10863
  return (await httpClient.get(`timeoff/organizations/${organization_id}/me`, {
10884
10864
  signal,
@@ -10906,7 +10886,7 @@ async function timeoffDeleteMyEntry(httpClient, organization_id, id, signal) {
10906
10886
  return response.json();
10907
10887
  }
10908
10888
  //#endregion
10909
- //#region ../../node_modules/.pnpm/@toggl+queries@2.2.79_@tanstack+react-query@5.99.0_react@19.2.5__@toggl+sync@0.2.4_reac_56300fbe33d90fb3e87cf472df5e3bc8/node_modules/@toggl/queries/dist/shared-data/working-hours/requests.mjs
10889
+ //#region ../../node_modules/.pnpm/@toggl+queries@2.2.81_@tanstack+react-query@5.99.0_react@19.2.5__@toggl+sync@0.2.4_reac_7f3699a62de19d0eb5476883f6a27f4a/node_modules/@toggl/queries/dist/shared-data/working-hours/requests.mjs
10910
10890
  async function getMyWorkingHours(httpClient, organization_id, signal) {
10911
10891
  return (await httpClient.get(`shared_data/api/workinghours/${organization_id}/me`, { signal })).json();
10912
10892
  }
@@ -12672,6 +12652,120 @@ function redactUnsafeSentryMessages(event) {
12672
12652
  for (const value of event.exception?.values ?? []) if (!isSafeSentryMessage(value.value)) value.value = REDACTED_SENTRY_MESSAGE;
12673
12653
  return event;
12674
12654
  }
12655
+ /**
12656
+ * Shared Sentry setup for the public CLI and MCP packages. Reporting is on by
12657
+ * default there, so everything the SDK attaches on its own has to be safe to
12658
+ * send from any user's machine, not only the exception message. Both packages
12659
+ * build their `Sentry.init` options from here so the two cannot drift.
12660
+ */
12661
+ function normalized(raw) {
12662
+ const value = raw?.trim();
12663
+ return value ? value.toLowerCase() : void 0;
12664
+ }
12665
+ function isOff(raw) {
12666
+ const value = normalized(raw);
12667
+ return value === "0" || value === "false" || value === "off" || value === "no";
12668
+ }
12669
+ function isOn(raw) {
12670
+ const value = normalized(raw);
12671
+ return value === "1" || value === "true" || value === "on" || value === "yes";
12672
+ }
12673
+ /**
12674
+ * Picks the DSN the public build reports to, or `undefined` when reporting is
12675
+ * off.
12676
+ *
12677
+ * `TOGGL_SENTRY_DSN` is the override. The generic `SENTRY_DSN` is what most Node
12678
+ * apps set, and the MCP loads the working directory's `.env`, so on its own it
12679
+ * must not redirect Toggl's errors into the user's project. It is still honoured
12680
+ * with an explicit `TOGGL_SENTRY=1`, the old opt-in, and `SENTRY_DSN=off` still
12681
+ * switches reporting off.
12682
+ */
12683
+ function resolvePublicSentryDsn(builtIn, env = process.env) {
12684
+ if (isOff(env.TOGGL_SENTRY) || normalized(env.SENTRY_DSN) === "off") return void 0;
12685
+ const override = env.TOGGL_SENTRY_DSN?.trim();
12686
+ if (override) return override.toLowerCase() === "off" ? void 0 : override;
12687
+ const legacy = env.SENTRY_DSN?.trim();
12688
+ if (legacy && isOn(env.TOGGL_SENTRY)) return legacy;
12689
+ return builtIn;
12690
+ }
12691
+ /**
12692
+ * `/Users/jane/.npm/_npx/…/node_modules/@togglhq/mcp/build/cli.js` becomes
12693
+ * `@togglhq/mcp/build/cli.js`. A path outside `node_modules` keeps only its file
12694
+ * name, so no home directory or login leaves the machine.
12695
+ */
12696
+ function toPackageRelativePath(path) {
12697
+ const unified = path.replace(/^file:\/\//, "").replaceAll("\\", "/");
12698
+ const at = unified.lastIndexOf("/node_modules/");
12699
+ if (at !== -1) return unified.slice(at + 14);
12700
+ if (!unified.includes("/")) return unified;
12701
+ return unified.slice(unified.lastIndexOf("/") + 1);
12702
+ }
12703
+ function scrubStacktrace(stacktrace) {
12704
+ for (const frame of stacktrace?.frames ?? []) {
12705
+ if (typeof frame.filename === "string") frame.filename = toPackageRelativePath(frame.filename);
12706
+ if (typeof frame.abs_path === "string") frame.abs_path = toPackageRelativePath(frame.abs_path);
12707
+ }
12708
+ }
12709
+ const QUERY_ATTRIBUTES = [
12710
+ "http.query",
12711
+ "url.query",
12712
+ "http.fragment",
12713
+ "url.fragment"
12714
+ ];
12715
+ const URL_ATTRIBUTES = [
12716
+ "url.full",
12717
+ "http.url",
12718
+ "http.target",
12719
+ "url"
12720
+ ];
12721
+ function stripQuery(value) {
12722
+ return value.replace(/[?#]\S*/, "");
12723
+ }
12724
+ function scrubSpan(span) {
12725
+ if (!span) return;
12726
+ if (typeof span.description === "string") span.description = stripQuery(span.description);
12727
+ const data = span.data;
12728
+ if (!data) return;
12729
+ for (const key of QUERY_ATTRIBUTES) delete data[key];
12730
+ for (const key of URL_ATTRIBUTES) {
12731
+ const value = data[key];
12732
+ if (typeof value === "string") data[key] = stripQuery(value);
12733
+ }
12734
+ }
12735
+ /**
12736
+ * Last word on every event the public build sends: messages reduced to fixed
12737
+ * categories, no hostname, no breadcrumbs, no dependency list, no request data,
12738
+ * package-relative stack paths, and no query strings on spans.
12739
+ */
12740
+ function scrubPublicSentryEvent(event) {
12741
+ redactUnsafeSentryMessages(event);
12742
+ delete event.server_name;
12743
+ delete event.breadcrumbs;
12744
+ delete event.modules;
12745
+ delete event.request;
12746
+ for (const value of event.exception?.values ?? []) scrubStacktrace(value.stacktrace);
12747
+ for (const thread of event.threads?.values ?? []) scrubStacktrace(thread.stacktrace);
12748
+ for (const span of event.spans ?? []) scrubSpan(span);
12749
+ scrubSpan(event.contexts?.trace);
12750
+ return event;
12751
+ }
12752
+ /**
12753
+ * Privacy options shared by `initCliTelemetry` and `initPublicSentry`.
12754
+ *
12755
+ * `sendDefaultPii: false` leaves the hostname (`server_name`), console and fetch
12756
+ * breadcrumbs, absolute stack paths, the working directory's package.json
12757
+ * dependencies (`Modules`) and incoming request data in place. Console
12758
+ * breadcrumbs in the MCP include the workspace name it logs at startup.
12759
+ */
12760
+ const PUBLIC_SENTRY_PRIVACY_OPTIONS = {
12761
+ sendDefaultPii: false,
12762
+ includeServerName: false,
12763
+ maxBreadcrumbs: 0,
12764
+ integrations: (defaults) => defaults.filter((integration) => integration.name !== "Modules"),
12765
+ beforeBreadcrumb: () => null,
12766
+ beforeSend: (event) => scrubPublicSentryEvent(event),
12767
+ beforeSendTransaction: (event) => scrubPublicSentryEvent(event)
12768
+ };
12675
12769
  const DEFAULT_POSTHOG_HOST = "https://eu.i.posthog.com";
12676
12770
  /**
12677
12771
  * The shared Toggl **production** PostHog project — the same token the Track
@@ -27151,11 +27245,12 @@ async function runValidatedOperation(operation, options, deps) {
27151
27245
  }
27152
27246
  //#endregion
27153
27247
  //#region src/telemetry.ts
27154
- function envEnabled(raw) {
27155
- if (raw === void 0) return false;
27156
- const normalized = raw.trim().toLowerCase();
27157
- return normalized === "1" || normalized === "true" || normalized === "on" || normalized === "yes";
27158
- }
27248
+ /**
27249
+ * Public client DSN for the `toggl-cli` Sentry project. Safe to ship: it only
27250
+ * accepts events. The pack audit allowlists this exact value and still rejects
27251
+ * any other `ingest.sentry.io` DSN.
27252
+ */
27253
+ const PUBLIC_SENTRY_DSN = "https://499edd257e0c64778932e6b7c7a0f8e9@o43910.ingest.us.sentry.io/4512156592046080";
27159
27254
  let sentryEnabled = false;
27160
27255
  let productAnalyticsEnabled = false;
27161
27256
  let lastCommandError;
@@ -27165,23 +27260,18 @@ function initCliTelemetry(packageVersion) {
27165
27260
  packageVersion,
27166
27261
  distinctId: resolveProductAnalyticsDistinctId("cli")
27167
27262
  });
27168
- if (!envEnabled(process.env.TOGGL_SENTRY)) {
27169
- sentryEnabled = false;
27170
- return;
27171
- }
27172
- const dsn = process.env.SENTRY_DSN;
27173
- if (!dsn || dsn === "off") {
27174
- console.error("[Telemetry] TOGGL_SENTRY is set but SENTRY_DSN is missing; Sentry left disabled");
27263
+ const dsn = resolvePublicSentryDsn(PUBLIC_SENTRY_DSN);
27264
+ if (!dsn) {
27175
27265
  sentryEnabled = false;
27176
27266
  return;
27177
27267
  }
27178
27268
  Sentry.init({
27179
27269
  dsn,
27270
+ release: `@togglhq/cli@${packageVersion}`,
27180
27271
  environment: process.env.NODE_ENV ?? "production",
27181
27272
  tracesSampleRate: .1,
27182
- sendDefaultPii: false,
27183
27273
  enableLogs: false,
27184
- beforeSend: (event) => redactUnsafeSentryMessages(event)
27274
+ ...PUBLIC_SENTRY_PRIVACY_OPTIONS
27185
27275
  });
27186
27276
  Sentry.setTag("cli.session.id", crypto.randomUUID());
27187
27277
  sentryEnabled = true;
@@ -27804,4 +27894,4 @@ Common commands:
27804
27894
  //#endregion
27805
27895
  export { CommanderError as a, shutdownCliTelemetry as i, captureCliException as n, initCliTelemetry as r, createProgram as t };
27806
27896
 
27807
- //# sourceMappingURL=program-DZlKCm-L.js.map
27897
+ //# sourceMappingURL=program-oQlvs6CQ.js.map
package/build/program.js CHANGED
@@ -1,2 +1,2 @@
1
- import { t as createProgram } from "./program-DZlKCm-L.js";
1
+ import { t as createProgram } from "./program-oQlvs6CQ.js";
2
2
  export { createProgram };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@togglhq/cli",
3
- "version": "1.11.82",
3
+ "version": "1.11.84",
4
4
  "description": "Toggl CLI for Toggl 2.0 API operations.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
@@ -56,7 +56,7 @@
56
56
  "devDependencies": {
57
57
  "@toggl/cli-core": "workspace:^",
58
58
  "@toggl/operations": "workspace:^",
59
- "@toggl/queries": "2.2.79",
59
+ "@toggl/queries": "2.2.81",
60
60
  "@types/node": "22.19.11",
61
61
  "tsdown": "0.21.8",
62
62
  "typescript": "5.9.3",