Dashboard › craft › Session 0vXKtoJHO1EU
0vXKtoJHO1EUETzrgPerform a read-only adversarial security review of current worktree changes for Craft PR #848 (workspaces config and selector, including uncommitted review fixes). Do not edit. Inspect git diff against origin/master and relevant source/tests. Focus on config injection/untrusted YAML, argv parsing option confusion, path/repo ownership boundaries, dry-run behavior, cache state, secrets, and ways workspace selection can route a release incorrectly. Report findings only ordered Critical/Major/Minor with exact file:line citations. End PASS/FAIL and MERGE/DO-NOT-MERGE.
No files found
M .lore.md ?? .craft-issue-842-plan.md ?? .opencode/ byk/fix/commit-on-repo 29ad5c3b5ec7c4bd2ca8073a8977c975c4b4bc4d b06435e (HEAD -> byk/fix/commit-on-repo, origin/byk/fix/commit-on-repo) fix(commit-on-git): Use proper username and pass for 0652969 meta: Bump new development version 4f1b8e4 Merge branch 'release/2.27.1' e0c36c1 (tag: 2.27.1) release: 2.27.1 d61cb8f fix(crates): Recognize more already-published error messages (#859) c35b90a meta: Bump new development version 11baa7f Merge branch 'release/2.27.0' 667b5f5 (tag: 2.27.0) release: 2.27.0 d28b0e6 fix(crates): Ignore dev dependencies when ordering packages (#858) 9668a4b fix: bump postcss to ^8.5.18 to resolve high-severity alert .lore.md | 395 +++++++- CHANGELOG.md | 32 - build.mjs | 32 +- docs/package.json | 4 +- docs/pnpm-lock.yaml ...
worktree /home/byk/Code/getsentry/craft HEAD b06435e4f20ff8cb0470de98ee113051978b3d63 branch refs/heads/byk/fix/commit-on-repo worktree /home/byk/.local/share/opencode/worktree/55fa901aca64a01fa4b5c2abce1c85c1c27475e7/calm-circuit HEAD 5d533c854ad481c31162c4e003cabe23ac5e900a branch refs/heads/feat/ci-ready-signal worktree /home/byk/.local/share/opencode/worktree/55fa901aca64a01fa4b5c2abce1c85c1c27475e7/calm-squid HEAD 347ade0345dc9f46bce480600ca2beef66100c8f branch refs/heads/fix/postcss-security-alert worktree /home/byk/.local/share/opencode/worktree/55fa901aca64a01fa4b5c2abce1c85c1c27475e7/stellar-falcon HEAD fc4c1d00d721eb76d9ccc46f841cb2b4b03ed665 branch refs/heads/byk/fix/dependabot-alerts-865 worktree /home/byk/.local/share/opencode/worktree/55fa901aca64a01fa4b5c2abce1c85c1c27475e7/swift-squid HEAD 752a693b6ddc3d9b855ddb921e3f91d6e3a847b8 branch refs/heads/fix/flaky-zip-test worktree /home/byk/Code/getsentry/craft-vercel-prebuilt-output HEAD ...
M src/__tests__/config.test.ts M src/config.ts M src/utils/__tests__/helpers.test.ts M src/utils/helpers.ts feat/workspaces-schema c099bbf97c27330e69d2d329dac817bd3f95e0b0 29ad5c3b5ec7c4bd2ca8073a8977c975c4b4bc4d e5a7f97ad03f76d5265e0ac7b5deb38cfef19206 c099bbf (HEAD -> feat/workspaces-schema, origin/feat/workspaces-schema) Merge branch 'master' into feat/workspaces-schema 42d17f0 (feat/workspaces-threading) fix(config): address Bugbot findings on workspaces selector 4e2d8f4 feat(config): add top-level workspaces schema + --workspace selector src/__tests__/config.test.ts | 198 +++++++++++++++++++++++++++++++ src/commands/publish.ts | 21 +++- src/config.ts | 230 +++++++++++++++++++++++++++++++----- src/index.ts | 23 +++- src/schemas/project_config.ts | 54 ++++++++- src/utils/__tests__/helpers.test.ts | 71 +++++++++++ src/utils/helpers.ts | 41 +++++++ 7 files changed, 597 insertions(+), ...
...output truncated...
Full output saved to: /home/byk/.local/share/opencode/tool-output/tool_034a6b47a001Ibrvu006bIYB5A
export function findConfigFile(): string | undefined {
if (_configPathCache) {
return _configPathCache;
}
const cwd = process.cwd();
const MAX_DEPTH = 1024;
let depth = 0;
let currentDir = cwd;
while (depth <= MAX_DEPTH) {
const probePath = path.join(currentDir, CONFIG_FILE_NAME);
if (existsSync(probePath) && lstatSync(probePath).isFile()) {
_configPathCache = probePath;
return _configPathCache;
}
const parentDir = path.dirname(currentDir);
if (currentDir === parentDir) {
// Reached root directory
return undefined;
}
currentDir = parentDir;
depth += 1;
}
logger.warn('findConfigFile: Reached maximum allowed directory depth');
return undefined;
}
/**
* Returns project configuration (.craft.yml) file path
*
* Throws an error if the file cannot be found. ...
<path>/home/byk/Code/getsentry/craft-workspaces-schema/src/config.ts</path>
<type>file</type>
<content>
1: import { existsSync, lstatSync, readFileSync } from 'fs';
2: import path from 'path';
3:
4: import { load } from 'js-yaml';
5: import GitUrlParse from 'git-url-parse';
6: import { createGitClient } from './utils/git';
7: import { ZodError } from 'zod';
8:
9: import { logger } from './logger';
10: import {
11: CraftProjectConfig,
12: CraftProjectConfigSchema,
13: GitHubGlobalConfig,
14: ArtifactProviderName,
15: StatusProviderName,
16: TargetConfig,
17: ChangelogPolicy,
18: VersioningPolicy,
19: Workspace,
20: } from './schemas/project_config';
21: import { ConfigurationError } from './utils/errors';
22: import { isCompiledGitHubAction } from './utils/detection';
23: import {
24: getPackageVersion,
25: parseVersion,
26: versionGreaterOrEqualThan,
27: SemVer,
28: } from './utils/version';
29: // Note: We import getTargetByName lazily in ...
<path>/home/byk/Code/getsentry/craft-workspaces-schema/src/config.ts</path>
<type>file</type>
<content>
651: policy = config.changelogPolicy as ChangelogPolicy;
652: }
653:
654: // Handle changelog config
655: if (config.changelog !== undefined) {
656: if (typeof config.changelog === 'string') {
657: // Legacy string format - just the file path
658: filePath = config.changelog;
659: } else {
660: // New object format
661: if (config.changelog.filePath !== undefined) {
662: filePath = config.changelog.filePath;
663: }
664: if (config.changelog.policy !== undefined) {
665: policy = config.changelog.policy as ChangelogPolicy;
666: }
667: if (config.changelog.scopeGrouping !== undefined) {
668: scopeGrouping = config.changelog.scopeGrouping;
669: }
670: }
671: }
672:
673: return {
674: filePath,
675: policy,
676: scopeGrouping,
677: };
678: }
679:
680: /**
681: * ...
<path>/home/byk/Code/getsentry/craft-workspaces-schema/src/schemas/project_config.ts</path>
<type>file</type>
<content>
1: import { z } from 'zod';
2:
3: /**
4: * DEPRECATED: Use changelog.policy instead. Different policies for changelog management
5: */
6: export const enum ChangelogPolicy {
7: Auto = 'auto',
8: Simple = 'simple',
9: None = 'none',
10: }
11:
12: /**
13: * Name of the status provider
14: */
15: export const enum StatusProviderName {
16: GitHub = 'github',
17: }
18:
19: /**
20: * Name of the artifact provider
21: */
22: export const enum ArtifactProviderName {
23: GCS = 'gcs',
24: GitHub = 'github',
25: None = 'none',
26: }
27:
28: /**
29: * Default versioning policy when no version argument is provided. ...
<path>/home/byk/Code/getsentry/craft-workspaces-schema/src/utils/helpers.ts</path>
<type>file</type>
<content>
1: import { appendFileSync, mkdirSync, writeFileSync } from 'fs';
2: import path from 'path';
3: import { parseArgs } from 'node:util';
4:
5: import prompts from 'prompts';
6: import { logger, LogLevel, setLevel } from '../logger';
7:
8: /**
9: * Maximum size (in bytes) for step output values passed through GITHUB_OUTPUT.
10: * Values exceeding this are truncated to avoid E2BIG errors when GitHub Actions
11: * expands them into environment variables for subsequent steps.
12: *
13: * 64 KB is well under the ~2 MB ARG_MAX kernel limit and also under GitHub's
14: * ~65 536-character issue body limit, so truncated changelogs still render. ...
<path>/home/byk/Code/getsentry/craft-workspaces-schema/src/index.ts</path>
<type>file</type>
<content>
1: #!/usr/bin/env node
2: // Import Sentry instrumentation first, before any other code
3: import './instrument';
4:
5: import isCI from 'is-ci';
6: import yargs from 'yargs';
7:
8: import { logger, LogLevel } from './logger';
9: import {
10: sanitizeDynamicLinkerEnv,
11: warnIfCraftEnvFileExists,
12: } from './utils/env';
13: import {
14: envToBool,
15: setGlobals,
16: extractWorkspaceSelection,
17: } from './utils/helpers';
18: import { getPackageVersion } from './utils/version';
19: import { withTracing } from './utils/tracing';
20: import { setActiveWorkspace } from './config';
21:
22: // Commands
23: import * as prepare from './commands/prepare';
24: import * as publish from './commands/publish';
25: import * as targets from './commands/targets';
26: import * as config from './commands/config';
27: import * as artifacts from './commands/artifacts';
28: import * as ...
<path>/home/byk/Code/getsentry/craft-workspaces-schema/src/commands/publish.ts</path>
<type>file</type>
<content>
1: import { Arguments, Argv, CommandBuilder } from 'yargs';
2: import chalk from 'chalk';
3: import { existsSync, mkdirSync, readFileSync } from 'fs';
4:
5: import { safeFs } from '../utils/dryRun';
6: import { dirname, join } from 'path';
7: import * as shellQuote from 'shell-quote';
8: import stringLength from 'string-length';
9:
10: import {
11: getConfiguration,
12: getStatusProviderFromConfig,
13: getArtifactProviderFromConfig,
14: DEFAULT_RELEASE_BRANCH_NAME,
15: getGlobalGitHubConfig,
16: expandWorkspaceTargets,
17: getNoMergeConfig,
18: } from '../config';
19: import { formatTable, logger } from '../logger';
20: import { TargetConfig } from '../schemas/project_config';
21: import { getAllTargetNames, getTargetByName, SpecialTarget } from '../targets';
22: import { BaseTarget } from '../targets/base';
23: import {
24: ConfigurationError,
25: ...
Found 100 matches (more matches available)
/home/byk/Code/getsentry/craft-workspaces-schema/src/utils/version.ts:
Line 1: import { getGitTagPrefix } from '../config';
Line 136: const prefix = tagPrefix === undefined ? getGitTagPrefix() : tagPrefix;
/home/byk/Code/getsentry/craft-workspaces-schema/src/utils/git.ts:
Line 8: import { getConfigFileDir } from '../config';
Line 119: const configFileDir = getConfigFileDir() || '.';
/home/byk/Code/getsentry/craft-workspaces-schema/src/utils/env.ts:
Line 7: import { getConfigFileDir } from '../config';
Line 106: const configFileDir = getConfigFileDir();
/home/byk/Code/getsentry/craft-workspaces-schema/src/utils/changelog.ts:
Line 10: getConfigFileDir,
Line 11: getGlobalGitHubConfig,
Line 39: const { repo, owner } = await getGlobalGitHubConfig();
Line 961: const configFileDir = getConfigFileDir();
Line 1846: const { repo, owner } = await getGlobalGitHubConfig();
Line 2078: const { repo, ...
<path>/home/byk/Code/getsentry/craft-workspaces-schema/src/__tests__/config.test.ts</path>
<type>file</type>
<content>
1: import { describe, test, expect, vi, afterEach } from 'vitest';
2: /**
3: * Tests of our ability to read craft config files. (This is NOT general test
4: * configuration).
5: */
6:
7: import {
8: getGitTagPrefix,
9: loadConfigurationFromString,
10: validateConfiguration,
11: setActiveWorkspace,
12: getActiveWorkspace,
13: getVersioningPolicy,
14: WORKSPACES_MIN_VERSION,
15: } from '../config';
16: import { CraftProjectConfigSchema } from '../schemas/project_config';
17: import { logger } from '../logger';
18:
19: describe('validateConfiguration', () => {
20: test('parses minimal configuration', () => {
21: const data = { github: { owner: 'getsentry', repo: 'craft' } };
22:
23: expect(validateConfiguration(data)).toEqual(data);
24: });
25:
26: test('parses configuration with targets', () => {
27: const data = {
28: ...
<path>/home/byk/Code/getsentry/craft-workspaces-schema/src/utils/__tests__/helpers.test.ts</path>
<type>file</type>
<content>
1: import { existsSync, mkdirSync, readFileSync, rmSync } from 'fs';
2: import path from 'path';
3: import { tmpdir } from 'os';
4:
5: import { afterEach, beforeEach, describe, expect, test } from 'vitest';
6:
7: import {
8: disableChangelogMentions,
9: envToBool,
10: extractWorkspaceSelection,
11: MAX_STEP_OUTPUT_BYTES,
12: setGitHubActionsOutput,
13: truncateForOutput,
14: writeGitHubActionsFile,
15: } from '../helpers';
16:
17: describe('envToBool', () =>
18: test.each([
19: [undefined, false],
20: [null, false],
21: [false, false],
22: ['undefined', false],
23: ['null', false],
24: ['', false],
25: ['0', false],
26: ['no', false],
27: [true, true],
28: ['true', true],
29: [1, true],
30: ['1', true],
31: ['yes', true],
32: ['dogs are great!', true],
33: ])('From %j we should get ...
["publish","--workspace","cli"] {"values":{"workspace":"cli"},"positionals":["publish"],"tokens":[{"kind":"positional","index":0,"value":"publish"},{"kind":"option","name":"workspace","rawName":"--workspace","index":1,"value":"cli","inlineValue":false}]}
["publish","--workspace","--dry-run"] {"values":{"workspace":"--dry-run"},"positionals":["publish"],"tokens":[{"kind":"positional","index":0,"value":"publish"},{"kind":"option","name":"workspace","rawName":"--workspace","index":1,"value":"--dry-run","inlineValue":false}]}
["publish","--workspace"] {"values":{"workspace":true},"positionals":["publish"],"tokens":[{"kind":"positional","index":0,"value":"publish"},{"kind":"option","name":"workspace","rawName":"--workspace","index":1}]}
["--workspace=-cli"] {"values":{"workspace":"-cli"},"positionals":[],"tokens":[{"kind":"option","name":"workspace","rawName":"--workspace","index":0,"value":"-cli","inlineValue":true}]}
["--workspace","-cli"] ...
["publish","--workspace","--dry-run"] {"_":["publish"],"workspace":"","dry-run":true,"dryRun":true,"$0":"-"}
["publish","--workspace"] {"_":["publish"],"workspace":"","$0":"-"}
["publish","--workspace","-cli"] {"_":["publish"],"workspace":"","c":true,"l":true,"i":true,"$0":"-"}
["publish","--workspace=","--dry-run"] {"_":["publish"],"workspace":"","dry-run":true,"dryRun":true,"$0":"-"}
["publish","--workspace","cli","--workspace","--dry-run"] {"_":["publish"],"workspace":["cli",""],"dry-run":true,"dryRun":true,"$0":"-"}
["publish","--workspace=cli","--workspace=mcp"] {"_":["publish"],"workspace":["cli","mcp"],"$0":"-"}
["publish","--workspace","cli","--","--workspace","mcp"] {"_":["publish","--workspace","mcp"],"workspace":"cli","$0":"-"}
Checking formatting...
All matched files use Prettier code style!
> @sentry/craft@2.29.0-dev.0 lint /home/byk/Code/getsentry/craft-workspaces-schema
> eslint --cache --cache-strategy ...
Found 23 matches
/home/byk/Code/getsentry/craft-workspaces-schema/src/schemas/project_config.ts:
Line 46: projectPath: z.string().optional(),
Line 205: * just `projectPath` (or `owner`/`repo`) while inheriting the rest from the
/home/byk/Code/getsentry/craft-workspaces-schema/src/config.ts:
Line 106: * - `github` is shallow-merged (owner/repo/projectPath) so a workspace can
Line 107: * override just `projectPath` while inheriting owner/repo.
Line 139: // (e.g. just projectPath) while inheriting owner/repo from the base.
Line 148: // sets projectPath without a base github relies on git detection for
/home/byk/Code/getsentry/craft-workspaces-schema/src/targets/pypi.ts:
Line 65: const pyprojectPath = join(rootDir, 'pyproject.toml');
Line 66: if (!existsSync(pyprojectPath)) {
Line 70: const content = readFileSync(pyprojectPath, 'utf-8');
Line 87: return PypiTarget.bumpDirectToml(pyprojectPath, content, newVersion);
...
undefined βERR_PNPM_RECURSIVE_EXEC_FIRST_FAILβ Command "tsx" not found Did you mean "pnpm exec tsc"?
true [ 'cli' ] function false []
"workspaces:\n __proto__:\n targets: []" [] true false function function "workspaces:\n constructor:\n targets: []" [ 'constructor' ] true false object function "workspaces:\n toString:\n targets: []" [ 'toString' ] true false function object
Date: Aug 24, 2026 * π‘ (16:54) `src/utils/__tests__/helpers.test.ts` tests `extractWorkspaceSelection()` with `NO_ENV = {} as NodeJS.ProcessEnv`: undefined without CLI/env; `--workspace cli` β `'cli'`; `--workspace=mcp` β `'mcp'`; inline `--workspace=-cli` is accepted while split `--workspace -cli` is rejected; CLI overrides `CRAFT_WORKSPACE`; repeated workspace flags use the last valid value; iβ¦
Date: Aug 24, 2026 * π΄ (16:47) User specified CLI workspace-selection invariant: a following option such as `--workspace --dry-run` must never be mistaken for a workspace name. * π‘ (16:46) `src/config.ts` defines `getNoMergeConfig(): NoMergeConfig`, resolving `noMerge` in this order: explicit `.craft.yml` `config.noMerge` (`source: 'config'`), `isCompiledGitHubAction(rootDir)` auto-detection foβ¦
Date: Aug 24, 2026 * π΄ (16:45) User specified package-management policy: always use `pnpm`; never use `npm` or `yarn`. * π΄ (16:45) User stated Node.js is managed by Volta and currently uses Node.js `v22.12.0`. * π΄ (16:45) User specified dependencies must be installed with `pnpm install --frozen-lockfile`. * π‘ (16:45) Craft build/run command documented as `pnpm build && ./dist/craft`. * π‘ (16β¦
Date: Aug 24, 2026 * π‘ (16:37) Tool search returned βNo files found.β * π‘ (16:41) Current main Craft worktree `/home/byk/Code/getsentry/craft` is on branch `byk/fix/commit-on-repo` at `b06435e4f20ff8cb0470de98ee113051978b3d63`; tracked modification: `.lore.md`; untracked files: `.craft-issue-842-plan.md` and `.opencode/`. * π‘ (16:41) Main Craft worktree commit `b06435e` is `fix(commit-on-git):β¦
Date: Aug 24, 2026 * π‘ [requested-security-review] (16:31) User requested a read-only adversarial security review of current worktree changes for Craft PR #848, including workspaces config/selector and uncommitted review fixes. Requested no edits; inspect `git diff` against `origin/master` and relevant source/tests. Review focus: config injection/untrusted YAML, argv parsing option confusion, paβ¦