DashboardcraftSession 0KwOn8srOYSu

Session 0KwOn8srOYSu

Full ID: 0KwOn8srOYSuylGb8
Messages: 34
Distillations: 5
Time range: 2026-09-08 13:30:37 — 2026-09-08 13:44:08

Conversation (34 messages)

Read-only research only. Inspect /home/byk/Code/getsentry/cli for its directory-walking and workspace-discovery implementation suitable for reuse by Craft PR #872. Identify exact modules, algorithms/contracts (globs, ignores, symlink handling, path normalization, validation), dependencies, public APIs, and test coverage, with file:line citations. Compare conceptually to Craft's current workspace resolver only if you need to read it; do not modify either repository. Return concise recommendation: directly reuse/extract/adapt vs keep Craft implementation, including compatibility/security risks.

gateway · 2026-09-08 13:30:37
result
<path>/home/byk/Code/getsentry/cli</path>
<type>directory</type>
<entries>
.craft.yml
.env.local
.git/
.github/
.gitignore
.lore.md
.node-cache/
.nojekyll
.npmrc
.opencode/
.ruff_cache/
AGENTS.md
apps/
CHANGELOG.md
codemods/
coverage-isolated/
coverage/
dist-bin/
dist-build/
dist/
docs/
LICENSE.md
node_modules/
package.json
packages/
pnpm-lock.yaml
pnpm-workspace.yaml
README.md
test-results.junit.xml
test/

(30 entries)
</entries>
gateway · 2026-09-08 13:31:02
result
<path>/home/byk/Code/getsentry/cli/AGENTS.md</path>
<type>file</type>
<content>
1: # Jared (Outpost agent)
2: 
3: Autonomous GitHub coding agent. Work in `/workspace/repo`.
4: 
5: ## Model tiers
6: 
7: The primary model is chosen per event (see `src/agents/models.ts`): heavy for
8: code-producing situations, cheaper for lightweight ones.
9: 
10: | Role | Subagent | Model |
11: | --- | --- | --- |
12: | Triage / plan / review (heavy) | (primary Jared) | Claude Opus 4.8 |
13: | Triage / plan / review (light) | (primary Jared) | xAI Grok 4.3 |
14: | Explore | `explore` | OpenAI gpt-5-mini |
15: | Implement | `implement` | Moonshot kimi-k2.7-code |
16: | Ship (commit/push/PR) | `ship` | xAI Grok (`grok-build-0.1`) |
17: 
18: Pipeline: triage → explore → plan → implement → review → ship.
19: (`worker` is a deprecated alias of `implement`.)
20: 
21: Operators also talk to Jared directly from the Outpost dashboard. ...
gateway · 2026-09-08 13:31:11
result
/home/byk/Code/getsentry/cli/.gitignore
/home/byk/Code/getsentry/cli/pnpm-workspace.yaml
/home/byk/Code/getsentry/cli/packages/cli/.gitignore
/home/byk/Code/getsentry/cli/codemods/sentry-v3-to-v4/.gitignore
/home/byk/Code/getsentry/cli/packages/cli/test/init-eval/templates/sveltekit-app/.gitignore
/home/byk/Code/getsentry/cli/packages/cli/test/init-eval/templates/react-vite-app/.gitignore
/home/byk/Code/getsentry/cli/packages/cli/test/init-eval/templates/python-flask-app/.gitignore
/home/byk/Code/getsentry/cli/packages/cli/test/init-eval/templates/python-fastapi-app/.gitignore
/home/byk/Code/getsentry/cli/packages/cli/src/lib/global-flags.ts
/home/byk/Code/getsentry/cli/packages/cli/src/lib/walk-up.ts
/home/byk/Code/getsentry/cli/packages/cli/test/init-eval/templates/nextjs-app/.gitignore
/home/byk/Code/getsentry/cli/packages/cli/test/lib/global-flags.test.ts
/home/byk/Code/getsentry/cli/packages/cli/src/lib/scan/glob.ts
/home/byk/Code/getsentry/cli/packages/cli/src/lib/scan/walker.ts
...
gateway · 2026-09-08 13:31:16
result
<path>/home/byk/Code/getsentry/cli/packages/cli/src/lib/scan/walker.ts</path>
<type>file</type>
<content>
1: /**
2:  * Streaming DFS directory walker with time-budgeted exploration.
3:  *
4:  * ### Contract
5:  *
6:  * `walkFiles(opts)` returns an `AsyncIterable<WalkEntry>` yielding one
7:  * entry per regular file under `opts.cwd`. Directories are traversed
8:  * but never yielded. Symbolic links are skipped unless
9:  * `followSymlinks: true`. Paths are POSIX-normalized.
10:  *
11:  * ### Depth + time budget
12:  *
13:  * The walker visits every directory at depth ≤ `minDepth` regardless
14:  * of wall-clock — that's the exhaustive-scan guarantee. Beyond
15:  * `minDepth`, each candidate descent is gated on
16:  * `clock() - startedAt ≤ timeBudgetMs`. When the budget is blown,
17:  * already-queued directories at any depth still drain (their contents
18:  * are yielded) but no new dirs at `depth > minDepth` are pushed.
19:  *
20:  * Traversal is DFS. ...
gateway · 2026-09-08 13:31:31
result
<path>/home/byk/Code/getsentry/cli/packages/cli/src/lib/scan/walker.ts</path>
<type>file</type>
<content>
225: async function* walkFilesImpl(opts: WalkOptions): AsyncGenerator<WalkEntry> {
226:   const cfg = normalizeOptions(opts);
227:   const matcher = await buildMatcher(cfg);
228:   const stats: WalkStats = {
229:     filesYielded: 0,
230:     dirsVisited: 0,
231:     filesSkippedBySize: 0,
232:     filesSkippedByBinary: 0,
233:     hitTimeBudget: false,
234:     maxDepthReached: 0,
235:   };
236:   const startedAt = cfg.clock();
237:   const visitedInodes = new Set<string>();
238:   // Seed the root's inode so a descendant symlink pointing back at the scan
239:   // root is treated as a cycle. The root frame is pushed directly (below)
240:   // rather than through `maybeDescend`, which is the only place inodes are
241:   // otherwise recorded — so without this seed a symlink → root would re-list
242:   // the root's entire subtree under a second path prefix. ...
gateway · 2026-09-08 13:31:37
result
<path>/home/byk/Code/getsentry/cli/packages/cli/src/lib/scan/walker.ts</path>
<type>file</type>
<content>
540: /**
541:  * Process a single directory entry: skip / descend / yield.
542:  *
543:  * Extracted from the generator body purely to keep cognitive complexity
544:  * under Biome's ceiling. Mutates `ctx.stats`, pushes directories onto
545:  * `ctx.stack`, and returns a `WalkEntry` when a file should be yielded.
546:  */
547: // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: filter cascade (hidden, symlink, dir, file, ignore, ext) is inherently branchy
548: async function processEntry(
549:   entry: Dirent,
550:   frame: DirFrame,
551:   ctx: WalkContext
552: ): Promise<WalkEntry | null> {
553:   const { cfg, matcher } = ctx;
554:   if (!cfg.hidden && entry.name.startsWith(".")) {
555:     return null;
556:   }
557:   if (entry.isSymbolicLink() && !cfg.followSymlinks) {
558:     return null;
559:   }
560:   // String-concat `abs` rather than `path.join` — measured ...
gateway · 2026-09-08 13:31:44
result
<path>/home/byk/Code/getsentry/cli/packages/cli/src/lib/scan/ignore.ts</path>
<type>file</type>
<content>
1: /**
2:  * IgnoreStack — per-directory `.gitignore` aggregation for the scanner.
3:  *
4:  * ### Why a stack of instances
5:  *
6:  * The `ignore` npm package implements one `.gitignore`-file's semantics
7:  * (last-matching rule wins inside that file, negations with `!`, etc.).
8:  * It does NOT know about nested `.gitignore` files.
9:  *
10:  * Real git treats nested `.gitignore` files cumulatively: parent rules
11:  * apply inside every subtree, and child `.gitignore` files can add new
12:  * rules that apply only in their subtree (including negations that
13:  * un-ignore something a parent had ignored). See `gitignore(5)`.
14:  *
15:  * To match that semantics we keep a `Map<relDir, Ignore>` of per-dir
16:  * `.gitignore` contents. ...
gateway · 2026-09-08 13:32:11
result
<path>/home/byk/Code/getsentry/cli/packages/cli/src/lib/scan/glob.ts</path>
<type>file</type>
<content>
1: /**
2:  * Pure-TS glob engine built on top of `walkFiles`.
3:  *
4:  * Accepts one or more glob patterns (picomatch syntax) and yields
5:  * files under `cwd` matching at least one `patterns` entry and no
6:  * `exclude` entry. Matching uses the `picomatch` package.
7:  *
8:  * ### Pattern semantics
9:  *
10:  * - Patterns with a `/` are matched against the POSIX-normalized
11:  *   relative path (e.g., `src/*.ts` only matches files directly in
12:  *   `src/`).
13:  * - Patterns without a `/` are matched against just the basename
14:  *   (e.g., `*.ts` matches `any/dir/x.ts`).
15:  * - `dot: true` — the matcher accepts dotfiles, matching the
16:  *   walker's default `hidden: true`.
17:  * - `**` spans directory boundaries.
18:  *
19:  * Uses picomatch's full grammar: extglobs (`+(a|b)`), braces
20:  * (`{a,b}`), negation (`!pattern`), etc. ...
gateway · 2026-09-08 13:32:18
result
/home/byk/Code/getsentry/cli/packages/cli/src/lib/scan/types.ts
/home/byk/Code/getsentry/cli/packages/cli/src/lib/scan/path-utils.ts
/home/byk/Code/getsentry/cli/packages/cli/src/lib/scan/index.ts
/home/byk/Code/getsentry/cli/packages/cli/src/lib/scan/constants.ts
gateway · 2026-09-08 13:32:40
result
<path>/home/byk/Code/getsentry/cli/packages/cli/src/lib/scan/types.ts</path>
<type>file</type>
<content>
1: /**
2:  * Public types for the scan module.
3:  *
4:  * The walker and ignore stack share a small contract defined here; the
5:  * types are intentionally narrow for PR 1 (walker-only). PR 2 will add
6:  * `GrepOptions` / `GrepMatch` / `GrepResult` on top.
7:  */
8: 
9: /**
10:  * A single filesystem entry yielded by `walkFiles`. Always a regular file —
11:  * directories are traversed but never yielded, and symbolic links are
12:  * skipped unless `followSymlinks: true` is set on the walker.
13:  *
14:  * Paths are POSIX-normalized (`/`-separated) on all platforms.
15:  */
16: export type WalkEntry = {
17:   /** Absolute path on disk. Native separators. */
18:   absolutePath: string;
19:   /**
20:    * POSIX-normalized path relative to `WalkOptions.cwd`.
21:    * Does not start with `./`. Does not end with `/`.
22:    */
23:   relativePath: string;
24:   /** Size in bytes. ...
gateway · 2026-09-08 13:32:43
result
<path>/home/byk/Code/getsentry/cli/packages/cli/src/lib/scan/path-utils.ts</path>
<type>file</type>
<content>
1: /**
2:  * Internal path + pattern utilities shared by the grep and glob
3:  * engines. Not part of the public barrel — implementation details
4:  * factored out to prevent drift between the two engines.
5:  */
6: 
7: import path from "node:path";
8: import picomatch from "picomatch";
9: 
10: /**
11:  * A precompiled glob matcher. We cache whether the pattern is
12:  * "path-mode" (tested against the relative path, e.g. `src/*.ts`)
13:  * vs "basename-mode" (tested against just the file's basename, e.g.
14:  * `*.ts`) so the per-file call skips the `pattern.includes("/")` check
15:  * every time.
16:  *
17:  * Matches the init-wizard's fs-fallback heuristic and ripgrep's
18:  * `--glob` semantics: patterns with `/` anchor to the relative path
19:  * from cwd, patterns without `/` match the basename anywhere. ...
gateway · 2026-09-08 13:32:51
result
<path>/home/byk/Code/getsentry/cli/packages/cli/src/lib/scan/index.ts</path>
<type>file</type>
<content>
1: // biome-ignore-all lint/performance/noBarrelFile: intentional public API
2: /**
3:  * Scan module — pure-TS ripgrep-compatible file scanner.
4:  *
5:  * PR 1 exports the file-walking foundation. PR 2 adds the grep and
6:  * glob engines (`grepFiles`, `globFiles` + collect helpers). PR 3
7:  * will migrate the DSN scanner to this module.
8:  *
9:  * @example
10:  * ```ts
11:  * import { walkFiles, TEXT_EXTENSIONS } from "./lib/scan/index.js";
12:  *
13:  * for await (const entry of walkFiles({ cwd, extensions: TEXT_EXTENSIONS })) {
14:  *   if (!entry.isBinary) console.log(entry.relativePath);
15:  * }
16:  * ```
17:  *
18:  * @example
19:  * ```ts
20:  * import { collectGrep } from "./lib/scan/index.js";
21:  *
22:  * const { matches, stats } = await collectGrep({
23:  *   cwd: "/path/to/repo",
24:  *   pattern: "(?i)TODO",
25:  *   include: "*.ts",
26:  *   maxResults: ...
gateway · 2026-09-08 13:33:06
result
<path>/home/byk/Code/getsentry/cli/packages/cli/src/lib/scan/constants.ts</path>
<type>file</type>
<content>
1: /**
2:  * Shared constants for the `scan` module.
3:  *
4:  * These values are deliberately policy-free defaults for a general-purpose
5:  * scanner. Callers that need stricter DSN-style filtering should spread
6:  * `DSN_ADDITIONAL_SKIP_DIRS` into their `alwaysSkipDirs` option.
7:  *
8:  * Single source of truth: `src/lib/dsn/code-scanner.ts` previously owned
9:  * `TEXT_EXTENSIONS`, `MAX_FILE_SIZE`, `CONCURRENCY_LIMIT`, `normalizePath`,
10:  * and `isMonorepoPackageDir`. Once PR 3 lands, `code-scanner.ts` re-imports
11:  * from here instead of duplicating.
12:  */
13: 
14: import { availableParallelism } from "node:os";
15: import path from "node:path";
16: // Re-exported below so scan callers don't have to reach into `dsn/`.
17: import { MONOREPO_ROOTS as DSN_MONOREPO_ROOTS } from "../dsn/types.js";
18: 
19: /**
20:  * File extensions the walker classifies as text without ...
gateway · 2026-09-08 13:33:16
result
<path>/home/byk/Code/getsentry/cli/packages/cli/package.json</path>
<type>file</type>
<content>
1: {
2:   "name": "sentry",
3:   "version": "0.44.0-dev.0",
4:   "description": "Sentry CLI - A command-line interface for using Sentry built by robots and humans for robots and humans",
5:   "repository": {
6:     "type": "git",
7:     "url": "git+https://github.com/getsentry/cli.git"
8:   },
9:   "main": "./dist/index.cjs",
10:   "type": "module",
11:   "types": "./dist/index.d.cts",
12:   "exports": {
13:     ".": {
14:       "import": {
15:         "types": "./dist/index.d.mts",
16:         "default": "./dist/index.mjs"
17:       },
18:       "require": {
19:         "types": "./dist/index.d.cts",
20:         "default": "./dist/index.cjs"
21:       }
22:     }
23:   },
24:   "bin": {
25:     "sentry": "./dist/bin.cjs"
26:   },
27:   "files": [
28:     "dist/bin.cjs",
29:     "dist/index.cjs",
30:     "dist/index.mjs",
31:     "dist/index.d.cts",
32:     "dist/index.d.mts",
33:     ...
gateway · 2026-09-08 13:33:38
result
Found 3 matches
/home/byk/Code/getsentry/cli/packages/cli/src/lib/dsn/parser.ts:
  Line 222:  * The fingerprint uniquely identifies the set of projects detected in a workspace.


/home/byk/Code/getsentry/cli/packages/cli/src/lib/dsn/env-file.ts:
  Line 216:         // symlinks too — pnpm/Yarn workspaces can symlink packages, and


/home/byk/Code/getsentry/cli/packages/cli/src/lib/detect-agent.ts:
  Line 135:   // workspaces, not just when the AI agent is driving the CLI
gateway · 2026-09-08 13:33:49
result
<path>/home/byk/Code/getsentry/cli/packages/cli/test/lib/scan/walker.test.ts</path>
<type>file</type>
<content>
1: /**
2:  * Unit tests for `walkFiles` in `src/lib/scan/walker.ts`.
3:  *
4:  * Each test builds a small sandbox under `tmpdir()`, runs the walker
5:  * with specific options, and asserts the yielded relative paths (order
6:  * doesn't matter — we compare via Set).
7:  *
8:  * Time-budget tests inject a mock clock so we can verify the min-depth
9:  * guarantee without flaky wall-clock dependencies.
10:  */
11: 
12: import {
13:   mkdirSync,
14:   mkdtempSync,
15:   rmSync,
16:   symlinkSync,
17:   writeFileSync,
18: } from "node:fs";
19: import { tmpdir } from "node:os";
20: import { join } from "node:path";
21: import { afterAll, describe, expect, test } from "vitest";
22: import type { WalkEntry } from "../../../src/lib/scan/types.js";
23: import { walkFiles } from "../../../src/lib/scan/walker.js";
24: 
25: const ROOT = mkdtempSync(join(tmpdir(), ...
gateway · 2026-09-08 13:34:14
result
<path>/home/byk/Code/getsentry/cli/packages/cli/test/lib/scan/glob.test.ts</path>
<type>file</type>
<content>
1: /**
2:  * Unit tests for `src/lib/scan/glob.ts` (`globFiles`, `collectGlob`).
3:  *
4:  * Pin down the picomatch-backed semantics the init wizard's
5:  * fs-fallback (and rg) expose:
6:  *
7:  *   - `*.ts` (no `/`) matches basename anywhere in tree.
8:  *   - `src/*.ts` (with `/`) matches against the relative path.
9:  *   - `**\/*.ts` matches `.ts` anywhere.
10:  *   - Multiple patterns OR.
11:  *   - `exclude` suppresses.
12:  *   - `maxResults` caps + sets `truncated: true`.
13:  *   - `path` narrows the walk root and yields cwd-relative paths.
14:  */
15: 
16: import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
17: import { tmpdir } from "node:os";
18: import { join } from "node:path";
19: import { afterAll, describe, expect, test } from "vitest";
20: import { collectGlob } from "../../../src/lib/scan/glob.js";
21: 
22: const ROOT = ...
gateway · 2026-09-08 13:34:25
result
<path>/home/byk/Code/getsentry/cli/packages/cli/test/lib/scan/ignore.test.ts</path>
<type>file</type>
<content>
1: /**
2:  * Unit tests for `src/lib/scan/ignore.ts` (IgnoreStack).
3:  *
4:  * Pins the semantics we care about most:
5:  *
6:  *   1. A single root `.gitignore` behaves like a plain `ignore` instance.
7:  *   2. `alwaysSkipDirs` basenames are skipped even when no `.gitignore`
8:  *      mentions them (basename-anywhere semantics).
9:  *   3. Nested `.gitignore` files apply ON TOP OF parent patterns —
10:  *      cumulative, root→leaf, with child negations overriding parents.
11:  *   4. `.git/info/exclude` is treated as an additional root `.gitignore`
12:  *      when requested.
13:  *   5. Malformed inputs (absolute paths, empty relPath) are handled
14:  *      gracefully. ...
gateway · 2026-09-08 13:34:51
result
<path>/home/byk/Code/getsentry/cli/packages/cli/test/lib/scan/walker.property.test.ts</path>
<type>file</type>
<content>
1: /**
2:  * Property tests for `walkFiles`.
3:  *
4:  * Two invariants we want to hold for any randomly generated tree:
5:  *
6:  *   1. Descent cap: no file yielded beyond `maxDepth + 1`. The walker
7:  *      caps directory *descent* at `maxDepth` — files inside those
8:  *      last-entered dirs still yield (they sit at parent_depth + 1).
9:  *   2. minDepth guarantee: for any tree, with `timeBudgetMs: 0` and a
10:  *      fixed `minDepth = N`, every file at depth ≤ N is yielded
11:  *      regardless of budget.
12:  *
13:  * Trees are built from a flat `(path, kind)` list. Generation is
14:  * constrained to ASCII alphanumerics + `_` to avoid tripping over the
15:  * `ignore` package's pattern escaping quirks. ...
gateway · 2026-09-08 13:35:18
result
<path>/home/byk/Code/getsentry/cli/packages/cli/test/lib/scan/ignore.property.test.ts</path>
<type>file</type>
<content>
1: /**
2:  * Property test: a root-only IgnoreStack behaves identically to a
3:  * plain `ignore` instance.
4:  *
5:  * This isn't a full cumulative-semantics test (the nested case is
6:  * covered by the unit tests) — it's a round-trip anchor so refactors
7:  * to the stack's root path can't silently diverge from the upstream
8:  * package.
9:  */
10: 
11: import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
12: import { tmpdir } from "node:os";
13: import { join } from "node:path";
14: import {
15:   array,
16:   asyncProperty,
17:   constantFrom,
18:   assert as fcAssert,
19: } from "fast-check";
20: import ignore from "ignore";
21: import { afterAll, describe, expect, test } from "vitest";
22: import { IgnoreStack } from "../../../src/lib/scan/ignore.js";
23: import { DEFAULT_NUM_RUNS } from "../../model-based/helpers.js";
24: 
25: const ROOT = ...
gateway · 2026-09-08 13:35:37
result
/home/byk/Code/getsentry/craft/src/utils/workspaces.ts
/home/byk/Code/getsentry/craft/src/utils/__tests__/workspaces.test.ts
/home/byk/Code/getsentry/craft/src/utils/__fixtures__/workspaces/pnpm-workspace/pnpm-workspace.yaml
gateway · 2026-09-08 13:35:43
result
<path>/home/byk/Code/getsentry/craft/src/utils/workspaces.ts</path>
<type>file</type>
<content>
1: import { readFileSync } from 'fs';
2: import * as path from 'path';
3: import { load } from 'js-yaml';
4: import { glob } from 'glob';
5: 
6: import { logger } from '../logger';
7: 
8: /**
9:  * Check if an error is a "file not found" error
10:  */
11: function isNotFoundError(err: unknown): boolean {
12:   return err instanceof Error && 'code' in err && err.code === 'ENOENT';
13: }
14: 
15: /** Information about a workspace package */
16: export interface WorkspacePackage {
17:   /** The package name from package.json */
18:   name: string;
19:   /** Absolute path to the package directory */
20:   location: string;
21:   /** Whether the package is private */
22:   private: boolean;
23:   /** Whether the package has publishConfig.access set to 'public' */
24:   hasPublicAccess: boolean;
25:   /** Dependencies that are also workspace packages */
26:   workspaceDependencies: string[];
27: ...
gateway · 2026-09-08 13:35:54
result
Found 6 matches
/home/byk/Code/getsentry/craft/src/utils/workspaces.ts:
  Line 111: async function resolveWorkspaceGlobs(

  Line 173:   const workspacesGlobs = extractWorkspacesGlobs(packageJson.workspaces);

  Line 174:   if (workspacesGlobs.length === 0) {

  Line 181:   const packages = await resolveWorkspaceGlobs(rootDir, workspacesGlobs);

  Line 186:     } ${type} workspace packages from ${workspacesGlobs.join(', ')}`,

  Line 216:   const packages = await resolveWorkspaceGlobs(rootDir, patterns);
gateway · 2026-09-08 13:36:06
result
<path>/home/byk/Code/getsentry/craft/src/utils/__tests__/workspaces.test.ts</path>
<type>file</type>
<content>
1: import { resolve } from 'path';
2: 
3: import {
4:   discoverWorkspaces,
5:   filterWorkspacePackages,
6:   packageNameToArtifactPattern,
7:   packageNameToArtifactFromTemplate,
8:   topologicalSortPackages,
9:   WorkspacePackage,
10: } from '../workspaces';
11: 
12: const fixturesDir = resolve(__dirname, '../__fixtures__/workspaces');
13: 
14: describe('discoverWorkspaces', () => {
15:   test('discovers npm workspaces', async () => {
16:     const result = await discoverWorkspaces(
17:       resolve(fixturesDir, 'npm-workspace'),
18:     );
19: 
20:     expect(result.type).toBe('npm');
21:     expect(result.packages).toHaveLength(2);
22: 
23:     const packageNames = result.packages.map(p => p.name).sort();
24:     expect(packageNames).toEqual(['@test/pkg-a', '@test/pkg-b']);
25: 
26:     // Check that pkg-b is marked as private
27:     const pkgB = result.packages.find(p ...
gateway · 2026-09-08 13:36:17
result
Found 29 matches
/home/byk/Code/getsentry/cli/packages/cli/src/lib/dsn/parser.ts:
  Line 15:   MONOREPO_ROOTS,

  Line 211:     MONOREPO_ROOTS.includes(root as (typeof MONOREPO_ROOTS)[number])


/home/byk/Code/getsentry/cli/packages/cli/src/lib/dsn/types.ts:
  Line 138: export const MONOREPO_ROOTS = [


/home/byk/Code/getsentry/cli/packages/cli/src/lib/dsn/scan-options.ts:
  Line 17:   isMonorepoPackageDir,

  Line 51:   return isMonorepoPackageDir(relPath) ? 0 : currentDepth + 1;


/home/byk/Code/getsentry/cli/packages/cli/src/lib/dsn/project-root.ts:
  Line 92:   "package.json",


/home/byk/Code/getsentry/cli/packages/cli/src/lib/dev-script.ts:
  Line 10:   /** Human label for what was detected (e.g., "package.json scripts.dev"). */

  Line 14: /** Ordered list of npm script names to look for in package.json. */

  Line 31:  * 1. package.json scripts (dev > develop > serve > start)

  Line 69: /** Try to detect a dev command from package.json scripts. ...
gateway · 2026-09-08 13:36:28
result
<path>/home/byk/Code/getsentry/cli/packages/cli/src/lib/dsn/types.ts</path>
<type>file</type>
<content>
110:   resolved: optional(ResolvedProjectInfoSchema),
111:   allResolved: optional(array(ResolvedProjectInfoSchema)),
112:   cachedAt: number(),
113: });
114: 
115: /**
116:  * Result of DSN detection with support for monorepos.
117:  *
118:  * In monorepos, multiple DSNs are valid (different packages/apps may have different Sentry projects).
119:  * The `primary` DSN is always the first one found, and `all` contains every detected DSN. ...
gateway · 2026-09-08 13:36:43
result
<path>/home/byk/Code/getsentry/cli/packages/cli/src/lib/dsn/scan-options.ts</path>
<type>file</type>
<content>
1: /**
2:  * DSN scanner preset for `walkFiles`.
3:  *
4:  * Expresses the policy the DSN scanner applies: a depth-3 cap, full
5:  * DSN skip list (including test/fixture dirs), monorepo-boundary
6:  * depth reset, and the `TEXT_EXTENSIONS` allowlist.
7:  *
8:  * Lives in `dsn/` rather than `scan/` so the core scanner module
9:  * stays policy-free. Other callers (the init wizard, future features)
10:  * bring their own presets.
11:  */
12: 
13: import type { WalkOptions } from "../scan/index.js";
14: import {
15:   DEFAULT_SKIP_DIRS,
16:   DSN_ADDITIONAL_SKIP_DIRS,
17:   isMonorepoPackageDir,
18:   TEXT_EXTENSIONS,
19: } from "../scan/index.js";
20: 
21: /**
22:  * DSN scanner depth limit. `maxDepth` caps directory descent; files
23:  * inside the last-entered directory are still yielded regardless. ...
gateway · 2026-09-08 13:36:51
result
Found 16 matches
/home/byk/Code/getsentry/cli/packages/cli/src/lib/init/tools/shared.ts:
  Line 9: export function safePath(cwd: string, relative: string): string {


/home/byk/Code/getsentry/cli/packages/cli/src/lib/init/tools/project-file.ts:
  Line 4: import { safePath } from "./shared.js";

  Line 75:     const absPath = safePath(cwd, filePath);


/home/byk/Code/getsentry/cli/packages/cli/src/lib/init/tools/list-dir.ts:
  Line 5: import { safePath } from "./shared.js";

  Line 25:   const targetPath = safePath(cwd, params.path);

  Line 98:       safePath(state.cwd, relNative);


/home/byk/Code/getsentry/cli/packages/cli/src/lib/init/tools/file-changes/prepare.ts:
  Line 10: import { safePath } from "../shared.js";

  Line 234:     absolutePath = safePath(cwd, change.path);


/home/byk/Code/getsentry/cli/packages/cli/src/lib/init/tools/file-changes/apply.ts:
  Line 11: import { safePath } from "../shared.js";

  Line 45:       safePath(change.root, change.path) !== ...
gateway · 2026-09-08 13:36:57
result
<path>/home/byk/Code/getsentry/cli/packages/cli/src/lib/init/tools/shared.ts</path>
<type>file</type>
<content>
1: import fs from "node:fs";
2: import path from "node:path";
3: import { ApiError } from "../../errors.js";
4: import type { ToolPayload, ToolResult } from "../types.js";
5: 
6: /**
7:  * Resolve a path relative to cwd and verify it stays inside the project root.
8:  */
9: export function safePath(cwd: string, relative: string): string {
10:   const resolved = path.resolve(cwd, relative);
11:   const normalizedCwd = path.resolve(cwd);
12:   if (
13:     !resolved.startsWith(normalizedCwd + path.sep) &&
14:     resolved !== normalizedCwd
15:   ) {
16:     throw new Error(`Path "${relative}" resolves outside project directory`);
17:   }
18: 
19:   let realCwd: string;
20:   try {
21:     realCwd = fs.realpathSync(normalizedCwd);
22:   } catch {
23:     return resolved;
24:   }
25: 
26:   let checkPath = resolved;
27:   for (;;) {
28:     try {
29:       const real = ...
gateway · 2026-09-08 13:37:48
result
Found 1 matches
/home/byk/Code/getsentry/craft/src/config.ts:
  Line 571:  * to implement their own expansion logic (e.g., npm workspace expansion).
gateway · 2026-09-08 13:37:55
result
<path>/home/byk/Code/getsentry/craft/src/config.ts</path>
<type>file</type>
<content>
500: 
501: /**
502:  * Returns whether the release branch should be merged after publishing.
503:  *
504:  * Resolution order:
505:  * 1. Explicit `noMerge` value in .craft.yml takes precedence
506:  * 2. Auto-detect compiled GitHub Actions (Node.js actions with dist/ folder)
507:  * 3. Default to false (merge the branch)
508:  *
509:  * Compiled GitHub Actions typically have their `dist/` folder gitignored on
510:  * main/master but need it in release branches for the action to work. Merging
511:  * the release branch back would overwrite the clean main branch with compiled
512:  * artifacts.
513:  *
514:  * @returns Configuration object with noMerge value and its source
515:  */
516: export function getNoMergeConfig(): NoMergeConfig {
517:   const config = getConfiguration();
518: 
519:   // Explicit config takes precedence
520:   if (config.noMerge !== undefined) {
521:     return {
522:       ...
gateway · 2026-09-08 13:38:41
result
No files found
gateway · 2026-09-08 13:38:49
result
Found 5 matches
/home/byk/Code/getsentry/cli/packages/cli/test/lib/init/tools/filesystem-tools.test.ts:
  Line 1152:     const unsafePaths: unknown[] = [

  Line 1163:     for (const unsafePath of unsafePaths) {

  Line 1172:                 path: unsafePath as never,


/home/byk/Code/getsentry/cli/packages/cli/test/lib/init/tools/search-tools.test.ts:
  Line 13:  * - The sandbox guard — `safePath` at the adapter boundary must


/home/byk/Code/getsentry/cli/packages/cli/test/lib/init/tools/list-dir.test.ts:
  Line 296:     // `safePath` allows nonexistent paths under the sandbox; `readdir`
gateway · 2026-09-08 13:44:08

Distillations (5)

Gen 0 2026-09-08 13:39:22 · 544 tokens

Date: Sep 8, 2026 * 🟡 (13:35) Source artifact `packages/cli/test/lib/scan/ignore.property.test.ts:1-125`: Property suite uses `fast-check`, Vitest, and isolated filesystem directories under `ROOT = mkdtempSync(join(tmpdir(), "scan-ignore-prop-"))`, removed in `afterAll()` via `rmSync(ROOT, { recursive: true, force: true })`. * 🟡 (13:35) Source artifact `ignore.property.test.ts:34-63`: `segmentA…

Gen 0 2026-09-08 13:38:56 · 1556 tokens

Date: Sep 8, 2026 * 🟡 (13:34) Source artifact `packages/cli/test/lib/scan/walker.test.ts:1-878`: Vitest unit suite creates isolated `tmpdir()` sandboxes and compares sorted yielded `WalkEntry.relativePath` sets. It verifies basic traversal of all depths; nonexistent `cwd` and empty directories yield `[]`; relative `cwd: "./relative"` throws an error matching `/absolute/`. * 🟡 (13:34) Source art…

Gen 0 2026-09-08 13:38:13 · 2582 tokens

Date: Sep 8, 2026 * 🔴 (13:32) User stated `WalkEntry` yielded by `walkFiles` is always a regular file; directories are traversed but never yielded, and symlinks are skipped unless `followSymlinks: true`. * 🔴 (13:32) User stated `WalkEntry.isBinary` uses `TEXT_EXTENSIONS` as an always-text extension fast path; other extensions are classified by reading the first 8 KB and detecting a NUL byte. UT…

Gen 0 2026-09-08 13:35:24 · 634 tokens

Date: Sep 8, 2026 * 🔴 (13:32) User stated `globFiles` public output is always relative to the caller's `cwd`. * 🟡 (13:32) Source artifact `packages/cli/src/lib/scan/glob.ts:1-28`: pure-TypeScript glob engine layers on `walkFiles`; accepts picomatch-syntax `patterns` and optional `exclude`, yielding files under `cwd` that match at least one include and no exclusion. Slash-containing patterns mat…

Gen 0 2026-09-08 13:35:10 · 2418 tokens

Date: Sep 8, 2026 * 🔴 [requested-read-only-research] (13:30) User directed read-only research only: inspect `/home/byk/Code/getsentry/cli` for directory-walking and workspace-discovery implementation potentially reusable by Craft PR #872; do not modify either repository. * 🟡 (13:30) User requested identification with file:line citations of exact modules, algorithms/contracts (globs, ignores, sy…