Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .craft.yml
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,17 @@ workspaces:
assert_match version.to_s, shell_output("#{bin}/sentry --version").chomp
end
end
# No preReleaseCommand: Craft bumps package.json through the npm target.
packages/logger:
changelog:
policy: auto

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Craft auto changelog lacks CHANGELOG

Medium Severity

The new cli-logger Craft workspace sets changelog.policy to auto, but packages/cli-logger has no CHANGELOG.md. The CLI workspace that uses the same policy keeps that file next to the package. Craft’s prepare step reads and updates it, so the first cli-logger release can fail before npm publish.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 3b25814. Configure here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checked this against Craft: with changelog.policy: auto, prepareChangelog creates the missing file instead of failing (src/commands/prepare.ts: if (!existsSync(relativePath)) { if (changelogPolicy === ChangelogPolicy.Auto) { ... safeFs.writeFile(relativePath, "# Changelog\n") } ...}). That code is in the v3 tag release.yml uses. For a workspace, the default path is <workspace>/CHANGELOG.md (getDefaultChangelogFilePath in src/config.ts), so the first cli-logger release creates packages/cli-logger/CHANGELOG.md and commits it on the release branch. Leaving the config as is.

releaseBranchPrefix: "release/{{workspaceName}}"
targets:
- name: github
tagPrefix: "{{workspaceName}}@"
includeNames: '/^{{packageSimpleName}}-\d.*\.tgz$/'
- name: npm
includeNames: '/^{{packageSimpleName}}-\d.*\.tgz$/'
packages/mcp-server:
changelogPolicy: none
preReleaseCommand: >-
Expand Down
9 changes: 7 additions & 2 deletions .github/workflows/merge-jobs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Post-merge tasks

on:
push:
branches: ["main", "release/*", "release/mcp/**"]
branches: ["main", "release/*", "release/mcp/**", "release/logger/**"]
workflow_dispatch:

jobs:
Expand All @@ -26,7 +26,7 @@ jobs:
run: pnpm install

- name: Build
run: pnpm --filter '@sentry/mcp-server...' --if-present run build
run: pnpm --filter '@sentry/mcp-server...' --filter @sentry/logger --if-present run build

- name: Run linter
run: pnpm lint
Expand All @@ -38,12 +38,17 @@ jobs:
working-directory: packages/mcp-server
run: pnpm pack --pack-destination dist

- name: Package logger
working-directory: packages/logger
run: pnpm pack --pack-destination dist

- name: Archive artifacts
uses: actions/upload-artifact@v4
with:
name: ${{ github.sha }}
path: |
${{ github.workspace }}/packages/mcp-server/dist/*.tgz
${{ github.workspace }}/packages/logger/dist/*.tgz

- name: Publish Test Report
uses: mikepenz/action-junit-report@cf701569b05ccdd861a76b8607a66d76f6fd4857
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ on:
default: mcp
options:
- cli
- logger
- mcp
bump:
description: Version bump type
Comment thread
sentry-junior[bot] marked this conversation as resolved.
Resolved
Expand Down Expand Up @@ -64,6 +65,10 @@ jobs:
workspace=packages/cli
package_path=packages/cli
;;
logger)
workspace=packages/logger
package_path=packages/logger
;;
mcp)
workspace=packages/mcp-server
package_path=packages/mcp-server
Expand Down
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ toolkit/
│ └── local/ # Sentry Local browser viewer
├── packages/
│ ├── cli/ # Sentry CLI (see packages/cli/AGENTS.md)
│ ├── logger/ # Structured logger (@sentry/logger on npm)
│ ├── toolkit-core/ # Shared CLI/MCP primitives
│ ├── mcp-core/ # Core MCP implementation (private)
│ ├── mcp-server/ # stdio transport (@sentry/mcp-server on npm)
Expand Down
4 changes: 3 additions & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ directories below; the MCP index explains which guides apply to that product.

For package-specific rules, see the root [AGENTS.md](../AGENTS.md) and the
[CLI AGENTS.md](../packages/cli/AGENTS.md). `packages/toolkit-core/` contains
shared primitives used by both products.
shared primitives used by both products. `packages/logger/` is the structured
logger the CLI uses, published to npm as `@sentry/logger`; see its
[README](../packages/logger/README.md).

## Ownership

Expand Down
1 change: 1 addition & 0 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@
"@mastra/client-js": "^1.38.0",
"@sentry/api": "catalog:",
"@sentry/core": "catalog:",
"@sentry/logger": "workspace:*",
"@sentry/mcp-server": "workspace:*",
"@sentry/node": "catalog:",
"@sentry/search-syntax": "catalog:",
Expand Down
9 changes: 5 additions & 4 deletions packages/cli/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -432,10 +432,11 @@ export async function runCli(cliArgs: string[]): Promise<void> {
async function promptImportConsent(): Promise<
"accepted" | "declined" | "cancelled"
> {
const { logger: logModule } = await import("./lib/logger.js");
const confirmed = await logModule
.withTag("import")
.prompt("Import from .sentryclirc?", { type: "confirm", initial: true });
const { prompt } = await import("./lib/prompt.js");
const confirmed = await prompt("Import from .sentryclirc?", {
type: "confirm",
initial: true,
});
if (confirmed === true) {
return "accepted";
}
Expand Down
3 changes: 2 additions & 1 deletion packages/cli/src/commands/auth/login.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import {
toLoginUser,
} from "../../lib/interactive-login.js";
import { logger } from "../../lib/logger.js";
import { prompt } from "../../lib/prompt.js";
import {
buildHostRefusalMessage,
isLoginHostTrusted,
Expand Down Expand Up @@ -394,7 +395,7 @@ async function handleExistingAuth(force: boolean): Promise<boolean> {
// Interactive TTY: prompt user to confirm re-authentication
const userInfo = getUserInfo();
const identity = userInfo ? formatUserIdentity(userInfo) : "current user";
const confirmed = await log.prompt(
const confirmed = await prompt(
`Already authenticated as ${identity}. Add another account? ` +
"(The current account stays saved; see 'sentry auth list'. Use --force to replace it.)",
{ type: "confirm", initial: false },
Expand Down
3 changes: 2 additions & 1 deletion packages/cli/src/commands/cli/defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import { ValidationError } from "../../lib/errors.js";
import { formatDefaultsResult } from "../../lib/formatters/human.js";
import { CommandOutput } from "../../lib/formatters/output.js";
import { logger } from "../../lib/logger.js";
import { prompt } from "../../lib/prompt.js";
import {
FORCE_FLAG,
guardNonInteractive,
Expand Down Expand Up @@ -380,7 +381,7 @@ export const defaultsCommand = buildCommand({
// Clear all defaults (with confirmation)
guardNonInteractive(flags);
if (!isConfirmationBypassed(flags)) {
const confirmed = await log.prompt(
const confirmed = await prompt(
`This will clear all defaults (${Object.keys(DEFAULTS_REGISTRY).join(", ")}). Continue?`,
{ type: "confirm" },
);
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/src/commands/cli/feedback.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { parseText } from "../../lib/completion-target.js";
import { ConfigError, ValidationError } from "../../lib/errors.js";
import { formatFeedbackResult } from "../../lib/formatters/human.js";
import { CommandOutput } from "../../lib/formatters/output.js";
import { logger } from "../../lib/logger.js";
import { prompt } from "../../lib/prompt.js";

/** Structured result of the feedback submission */
export type FeedbackResult = {
Expand Down Expand Up @@ -69,7 +69,7 @@ export const feedbackCommand = buildCommand({
if (!isatty(0)) {
throw new ValidationError("Please provide a feedback message.");
}
const response = await logger.prompt("Enter your feedback message:", {
const response = await prompt("Enter your feedback message:", {
type: "text",
placeholder: "e.g. I love this tool!",
});
Expand Down
3 changes: 2 additions & 1 deletion packages/cli/src/commands/cli/import.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { success, warning } from "../../lib/formatters/colors.js";
import { renderMarkdown } from "../../lib/formatters/markdown.js";
import { CommandOutput } from "../../lib/formatters/output.js";
import { logger } from "../../lib/logger.js";
import { prompt } from "../../lib/prompt.js";
import { DRY_RUN_FLAG } from "../../lib/mutate-command.js";
import { normalizeUserInputToOrigin } from "../../lib/sentry-urls.js";
import type {
Expand Down Expand Up @@ -229,7 +230,7 @@ async function confirmImport(): Promise<boolean> {
if (!isatty(0)) {
return false;
}
const confirmed = await log.prompt("Import these settings to the new CLI?", {
const confirmed = await prompt("Import these settings to the new CLI?", {
type: "confirm",
initial: true,
});
Expand Down
3 changes: 2 additions & 1 deletion packages/cli/src/commands/issue/plan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
FRESH_FLAG,
} from "../../lib/list-command.js";
import { logger } from "../../lib/logger.js";
import { prompt } from "../../lib/prompt.js";
import {
type AutofixState,
extractExaminedFiles,
Expand Down Expand Up @@ -184,7 +185,7 @@ async function confirmRootCauseAndContinue(
log.info("Root cause identified:");
log.info(`"${primaryCause.description}"`);

const proceed = await log.prompt("Generate a solution plan for it?", {
const proceed = await prompt("Generate a solution plan for it?", {
type: "confirm",
initial: true,
});
Expand Down
3 changes: 2 additions & 1 deletion packages/cli/src/commands/log/view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import {
FRESH_FLAG,
} from "../../lib/list-command.js";
import { logger } from "../../lib/logger.js";
import { prompt } from "../../lib/prompt.js";
import {
type BoundArguments,
boundArguments,
Expand Down Expand Up @@ -306,7 +307,7 @@ async function handleWebOpen(orgSlug: string, logIds: string[]): Promise<void> {
);
return;
}
const confirmed = await log.prompt(`Open ${logIds.length} browser tabs?`, {
const confirmed = await prompt(`Open ${logIds.length} browser tabs?`, {
type: "confirm",
initial: false,
});
Expand Down
3 changes: 2 additions & 1 deletion packages/cli/src/commands/trial/start.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { ContextError, ValidationError } from "../../lib/errors.js";
import { success } from "../../lib/formatters/colors.js";
import { CommandOutput } from "../../lib/formatters/output.js";
import { logger as log } from "../../lib/logger.js";
import { prompt } from "../../lib/prompt.js";
import {
type BoundArguments,
boundArguments,
Expand Down Expand Up @@ -230,7 +231,7 @@ async function promptOpenBrowser(url: string): Promise<boolean> {

// Prompt to open browser if interactive TTY (stdin for input, stderr for display)
if (isatty(0) && isatty(2)) {
const confirmed = await logger.prompt("Open in browser?", {
const confirmed = await prompt("Open in browser?", {
type: "confirm",
initial: true,
});
Expand Down
Loading
Loading