@devdogsuga/devtools 0.1.40 → 0.1.42

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.
@@ -1,9 +1,9 @@
1
1
  import { a as cliName, d as positionals, u as flagValue } from "./failure-log-B5GG_8T1.js";
2
- import { C as helpPath, S as catalog, T as renderHelp, _ as bail, a as recordEnteredTier, b as explainError, c as describeEnvironment, d as resolveDbConnection, f as sessionIsLocal, i as beginInvocation, l as probeEnvironment, n as bareGroupStartPath, o as recordResolved, p as sessionLabel, r as runMenu, s as reproducibleCommand, t as bareGroupStartFlags, u as nonEmpty, v as errorMessage, w as renderCommandList, x as unwrap, y as explain } from "./menu-Craj11Sn.js";
2
+ import { C as helpPath, S as catalog, T as renderHelp, _ as bail, a as recordEnteredTier, b as explainError, c as describeEnvironment, d as resolveDbConnection, f as sessionIsLocal, i as beginInvocation, l as probeEnvironment, n as bareGroupStartPath, o as recordResolved, p as sessionLabel, r as runMenu, s as reproducibleCommand, t as bareGroupStartFlags, u as nonEmpty, v as errorMessage, w as renderCommandList, x as unwrap, y as explain } from "./menu-DXT1ICTI.js";
3
3
  import { _ as dryRunKind, c as reportRuns, f as supabase, g as runInGroup, h as reportRan, l as run$1, s as dbPush, u as runWithStderr, v as isDryRun, x as wouldRunLine } from "./supabase-project-Bw8sBFcE.js";
4
4
  import { a as ownVersion, n as discoverRepoRoot, r as findRepoRoot } from "./root-C2OmZDwD.js";
5
5
  import { i as loadEnvSession, n as loadEnv, r as loadEnvLoad, t as getEnvSync } from "./peers-RBplwovA.js";
6
- import { d as hasYes, f as isNonInteractive, n as captureDevtoolsError, o as initDevtoolsTelemetry, r as devtoolsEnvironment, t as captureDevtoolsDeprecation } from "./telemetry-Do13RFhc.js";
6
+ import { d as hasYes, f as isNonInteractive, n as captureDevtoolsError, o as initDevtoolsTelemetry, r as devtoolsEnvironment, t as captureDevtoolsDeprecation } from "./telemetry-xNMpvX5K.js";
7
7
  import { n as assertRegistryLoaded, r as loadRegistry, t as scopedProcessEnv } from "./local-env-hH4encfD.js";
8
8
  import { t as runStackCommand } from "./stack-7PuRcaI2.js";
9
9
  import { cancel, confirm, intro, isCancel, log, multiselect, note, outro, password, select, spinner, text } from "@clack/prompts";
@@ -1931,7 +1931,7 @@ function targetHeader(target, count) {
1931
1931
  "#",
1932
1932
  ...comment(`The ${count} key${count === 1 ? "" : "s"} a \`pnpm devtools env push --target ${target}\` routes, and nothing else. The committed defaults and the per-developer values go nowhere, and a minted credential is signed at deploy time rather than stored, so none of the three has a line here to fill in.`),
1933
1933
  "#",
1934
- ...comment(target === "production" ? "The apply-tier credential IS here — SUPABASE_ACCESS_TOKEN reaches the production-apply GitHub environment, and no other target carries it." : `The apply-tier credential is NOT here. It exists to reshape production, so a copy in ${target} would be a second write-capable token to rotate for no benefit — and \`env push\` skips it outside production anyway.`),
1934
+ ...comment(target === "production" ? "The apply-tier credential IS here — SUPABASE_ACCESS_TOKEN reaches the production GitHub environment, and no other target carries it." : `The apply-tier credential is NOT here. It exists to reshape production, so a copy in ${target} would be a second write-capable token to rotate for no benefit — and \`env push\` skips it outside production anyway.`),
1935
1935
  "#",
1936
1936
  ...comment(`Fill the values in, or run \`pnpm devtools env pull --target ${target}\` to fetch what Bitwarden already holds. Nothing is commented out: push reads assignments, and a commented line is not one — a value typed on it would be silently skipped.`),
1937
1937
  "#",
package/dist/launch.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import { a as cliName, t as installFailureLog } from "./failure-log-B5GG_8T1.js";
2
- import { C as helpPath, S as catalog, _ as bail, g as setMenuEnvHook, h as realEnvEntryDeps, m as enterSessionEnvironment, n as bareGroupStartPath, u as nonEmpty, v as errorMessage, x as unwrap } from "./menu-Craj11Sn.js";
2
+ import { C as helpPath, S as catalog, _ as bail, g as setMenuEnvHook, h as realEnvEntryDeps, m as enterSessionEnvironment, n as bareGroupStartPath, u as nonEmpty, v as errorMessage, x as unwrap } from "./menu-DXT1ICTI.js";
3
3
  import { b as setDryRun, m as formatCommand, v as isDryRun, y as resolveDryRun } from "./supabase-project-Bw8sBFcE.js";
4
4
  import { n as discoverRepoRoot, r as findRepoRoot, t as RepoNotFoundError } from "./root-C2OmZDwD.js";
5
5
  import { i as loadEnvSession, r as loadEnvLoad } from "./peers-RBplwovA.js";
6
- import { d as hasYes, f as isNonInteractive, m as stripTierFlag, n as captureDevtoolsError, o as initDevtoolsTelemetry, p as stripNoEnvFlag, s as lastSentryEventId } from "./telemetry-Do13RFhc.js";
6
+ import { d as hasYes, f as isNonInteractive, m as stripTierFlag, n as captureDevtoolsError, o as initDevtoolsTelemetry, p as stripNoEnvFlag, s as lastSentryEventId } from "./telemetry-xNMpvX5K.js";
7
7
  import { confirm, select } from "@clack/prompts";
8
8
  //#region ../cli-core/src/session.ts
9
9
  /**
@@ -166,7 +166,7 @@ async function startStack() {
166
166
  * post-tier-resolution path.
167
167
  */
168
168
  async function dispatch(argv) {
169
- const { main } = await import("./cli-CeCAuSJd.js");
169
+ const { main } = await import("./cli-BkHyIT5V.js");
170
170
  try {
171
171
  await main(argv);
172
172
  } catch (err) {
@@ -2,7 +2,7 @@ import { c as YES, d as positionals, i as suppressFailureLog, l as createCatalog
2
2
  import { a as listContainerNames, i as foreignStackProjectId, n as containerPrefix, o as readProjectId, p as supabaseCapture, r as foreignStackMessage, t as STACK_API_PORT } from "./supabase-project-Bw8sBFcE.js";
3
3
  import { r as findRepoRoot } from "./root-C2OmZDwD.js";
4
4
  import { n as loadEnv, r as loadEnvLoad } from "./peers-RBplwovA.js";
5
- import { c as reportDevtoolsError, f as isNonInteractive } from "./telemetry-Do13RFhc.js";
5
+ import { c as reportDevtoolsError, f as isNonInteractive } from "./telemetry-xNMpvX5K.js";
6
6
  import { cancel, confirm, isCancel, log, note, select, text } from "@clack/prompts";
7
7
  import { existsSync } from "node:fs";
8
8
  import { writeFile } from "node:fs/promises";
@@ -2,7 +2,7 @@ import { a as cliName, n as noteError } from "./failure-log-B5GG_8T1.js";
2
2
  import { a as ownVersion, n as discoverRepoRoot } from "./root-C2OmZDwD.js";
3
3
  import { readFileSync } from "node:fs";
4
4
  import * as Sentry from "@sentry/node";
5
- import { buildSentryOptions } from "@devdogsuga/telemetry";
5
+ import "@sentry/core";
6
6
  //#region ../cli-core/src/mode.ts
7
7
  /**
8
8
  * Non-interactive mode: the one definition both published CLIs share.
@@ -75,6 +75,142 @@ function stripTierFlag(argv) {
75
75
  };
76
76
  }
77
77
  //#endregion
78
+ //#region ../telemetry/dist/constants.js
79
+ /**
80
+ * `tracesSampleRate` by environment. Every environment not listed samples at
81
+ * 0 — that is the "else 0" branch, not an omission, and covers `development`,
82
+ * `ci`, and `local` today without needing an entry each.
83
+ */
84
+ const TRACES_SAMPLE_RATE_BY_ENVIRONMENT = {
85
+ production: .2,
86
+ staging: .05
87
+ };
88
+ function tracesSampleRateFor(environment) {
89
+ return TRACES_SAMPLE_RATE_BY_ENVIRONMENT[environment] ?? 0;
90
+ }
91
+ /**
92
+ * Tag keys every surface should spell the same way, so a Sentry search for
93
+ * `service:platform` or `alert:true` works regardless of which app or
94
+ * package produced the event.
95
+ */
96
+ const TAG_KEYS = {
97
+ /** Which of {@link SERVICES} produced the event. */
98
+ SERVICE: "service",
99
+ /** Set to `"true"` on every event sent through {@link alert}. */
100
+ ALERT: "alert"
101
+ };
102
+ //#endregion
103
+ //#region ../telemetry/dist/scrub.js
104
+ /**
105
+ * Pure scrubbing functions plus the `beforeSend` that composes them.
106
+ *
107
+ * Every function here operates on plain strings or a plain `Event` object —
108
+ * no Sentry client, no network, nothing that needs a DSN to unit-test.
109
+ */
110
+ const POSIX_PATH = /(?<=^|[\s"'(<])\/(?:[^\s"'()<>:]+\/)+([^\s"'()<>:]+)/g;
111
+ const WINDOWS_PATH = /[A-Za-z]:\\(?:[^\s"'()<>]+\\)*([^\s"'()<>]+)/g;
112
+ /** Replaces absolute filesystem paths in `text` with just their basename. */
113
+ function scrubPaths(text) {
114
+ return text.replace(WINDOWS_PATH, "$1").replace(POSIX_PATH, "$1");
115
+ }
116
+ const EMAIL = /[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}/g;
117
+ /** Redacts anything that looks like an email address. */
118
+ function scrubEmails(text) {
119
+ return text.replace(EMAIL, "[redacted-email]");
120
+ }
121
+ const ENV_ASSIGNMENT = /\b([A-Z][A-Z0-9_]{2,}(?:_KEY|_TOKEN|_SECRET|_PASSWORD)\w*)=[^\s"'`)]+/g;
122
+ const BEARER_TOKEN = /\b[Bb]earer\s+[A-Za-z0-9._-]+/g;
123
+ /** Redacts env-var-style assignments and bearer tokens. */
124
+ function scrubSecrets(text) {
125
+ return text.replace(ENV_ASSIGNMENT, "$1=[redacted]").replace(BEARER_TOKEN, "Bearer [redacted]");
126
+ }
127
+ /** Runs all three text scrubbers, in order. */
128
+ function scrubText(text) {
129
+ return scrubSecrets(scrubEmails(scrubPaths(text)));
130
+ }
131
+ function scrubFrame(frame) {
132
+ return {
133
+ ...frame,
134
+ filename: frame.filename ? scrubText(frame.filename) : frame.filename,
135
+ abs_path: frame.abs_path ? scrubText(frame.abs_path) : frame.abs_path,
136
+ context_line: frame.context_line ? scrubText(frame.context_line) : frame.context_line
137
+ };
138
+ }
139
+ function scrubException(exception) {
140
+ return {
141
+ ...exception,
142
+ value: exception.value ? scrubText(exception.value) : exception.value,
143
+ stacktrace: exception.stacktrace ? {
144
+ ...exception.stacktrace,
145
+ frames: exception.stacktrace.frames?.map(scrubFrame)
146
+ } : exception.stacktrace
147
+ };
148
+ }
149
+ /**
150
+ * Applies every scrubber to the parts of an event that carry free text:
151
+ * the top-level message, each exception's message and stack frames, and
152
+ * breadcrumb messages. Never returns `null` — this is a scrub, not a filter;
153
+ * see {@link browserNoiseFilter} in `./browser-filter.ts` for dropping
154
+ * events outright.
155
+ */
156
+ function scrubEvent(event, _hint) {
157
+ return {
158
+ ...event,
159
+ message: event.message ? scrubText(event.message) : event.message,
160
+ exception: event.exception ? { values: event.exception.values?.map(scrubException) } : event.exception,
161
+ breadcrumbs: event.breadcrumbs?.map((crumb) => crumb.message ? {
162
+ ...crumb,
163
+ message: scrubText(crumb.message)
164
+ } : crumb)
165
+ };
166
+ }
167
+ //#endregion
168
+ //#region ../telemetry/dist/options.js
169
+ /**
170
+ * Chains `beforeSend`-shaped functions left to right, short-circuiting the
171
+ * moment one drops the event. Used to compose the shared scrubbers with a
172
+ * consumer's own additions (e.g. {@link browserNoiseFilter} on the browser
173
+ * side only) without every consumer re-implementing the chaining.
174
+ */
175
+ function composeBeforeSend(...fns) {
176
+ return (event, hint) => {
177
+ let current = event;
178
+ for (const fn of fns) {
179
+ if (current === null) return null;
180
+ current = fn(current, hint);
181
+ }
182
+ return current;
183
+ };
184
+ }
185
+ /**
186
+ * The options every `Sentry.init()` call in the workspace shares: DSN,
187
+ * environment, release passthrough, the sample-rate table, Sentry Logs, PII
188
+ * off by default, and the scrubbing `beforeSend` chain.
189
+ *
190
+ * Returns `undefined` when `dsn` is falsy, so every consumer can write
191
+ * `const opts = buildSentryOptions(...); if (opts) Sentry.init(opts);` and
192
+ * no-op cleanly with no DSN configured (the normal case in local dev).
193
+ *
194
+ * The return type is `@sentry/core`'s `Options` (`CoreOptions`) — the
195
+ * options shape shared by `@sentry/node`, `@sentry/cloudflare`, and
196
+ * `@sentry/nextjs`'s `init()` calls alike, so this same object is valid
197
+ * input to any of them.
198
+ */
199
+ function buildSentryOptions({ service, environment, dsn, release, extraBeforeSend = [] }) {
200
+ if (!dsn) return void 0;
201
+ return {
202
+ dsn,
203
+ environment,
204
+ release,
205
+ tracesSampleRate: tracesSampleRateFor(environment),
206
+ sampleRate: 1,
207
+ enableLogs: true,
208
+ sendDefaultPii: false,
209
+ initialScope: { tags: { [TAG_KEYS.SERVICE]: service } },
210
+ beforeSend: composeBeforeSend(scrubEvent, ...extraBeforeSend)
211
+ };
212
+ }
213
+ //#endregion
78
214
  //#region ../cli-core/src/telemetry.ts
79
215
  /**
80
216
  * devtools' own Sentry wiring — the CLI is a consumer of
package/dist/telemetry.js CHANGED
@@ -1,2 +1,2 @@
1
- import { a as hasRealCaller, c as reportDevtoolsError, i as devtoolsTelemetryEnabled, l as reportDevtoolsFailure, n as captureDevtoolsError, o as initDevtoolsTelemetry, r as devtoolsEnvironment, s as lastSentryEventId, t as captureDevtoolsDeprecation, u as resolveDevtoolsDsn } from "./telemetry-Do13RFhc.js";
1
+ import { a as hasRealCaller, c as reportDevtoolsError, i as devtoolsTelemetryEnabled, l as reportDevtoolsFailure, n as captureDevtoolsError, o as initDevtoolsTelemetry, r as devtoolsEnvironment, s as lastSentryEventId, t as captureDevtoolsDeprecation, u as resolveDevtoolsDsn } from "./telemetry-xNMpvX5K.js";
2
2
  export { captureDevtoolsDeprecation, captureDevtoolsError, devtoolsEnvironment, devtoolsTelemetryEnabled, hasRealCaller, initDevtoolsTelemetry, lastSentryEventId, reportDevtoolsError, reportDevtoolsFailure, resolveDevtoolsDsn };
package/env.ts CHANGED
@@ -50,7 +50,7 @@ declare({
50
50
  "A Supabase personal access token, carrying full account privileges " +
51
51
  "across both Supabase organizations. Only `supabase config push` " +
52
52
  "needs it -- the one mutation with no dry run -- so in GitHub it " +
53
- "reaches the production-apply environment only, behind required " +
53
+ "reaches the production environment only, behind required " +
54
54
  "reviewers.",
55
55
  scope: "environment",
56
56
  secrecy: "secret",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devdogsuga/devtools",
3
- "version": "0.1.40",
3
+ "version": "0.1.42",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Contributor CLI for a DevDogsUGA checkout: the real tools with the session's tier filled in, a menu over them, and the checks CI runs. Ships built JS; run via `pnpm dlx @devdogsuga/devtools` (or the `devtools` bin once installed) from inside a DevDogsUGA clone.",
@@ -24,14 +24,14 @@
24
24
  ],
25
25
  "dependencies": {
26
26
  "@clack/prompts": "1.7.0",
27
+ "@sentry/core": "10.75.1",
27
28
  "@sentry/node": "10.75.1",
28
29
  "@supabase/supabase-js": "^2.112.3",
29
30
  "dotenv": "^17.4.2",
30
31
  "postgres": "^3.4.9",
31
32
  "tsx": "^4.23.12",
32
33
  "typescript": "^6.0.3",
33
- "zod": "4.4.3",
34
- "@devdogsuga/telemetry": "0.1.5"
34
+ "zod": "4.4.3"
35
35
  },
36
36
  "peerDependencies": {
37
37
  "@devdogsuga/db": "*",
@@ -52,9 +52,10 @@
52
52
  "tsdown": "^0.23.0",
53
53
  "vitest": "^4.1.11",
54
54
  "@devdogsuga/cli-core": "0.0.0",
55
- "@devdogsuga/config": "0.1.3",
56
55
  "@devdogsuga/env": "0.1.6",
57
- "@devdogsuga/db": "0.1.4"
56
+ "@devdogsuga/db": "0.1.4",
57
+ "@devdogsuga/config": "0.1.3",
58
+ "@devdogsuga/telemetry": "0.1.5"
58
59
  },
59
60
  "scripts": {
60
61
  "build": "tsdown && node scripts/write-build-info.mjs && node ../../scripts/check-bundle-imports.mjs",