diff --git a/REUSE.toml b/REUSE.toml
index 681d119..dc89f10 100644
--- a/REUSE.toml
+++ b/REUSE.toml
@@ -8,10 +8,13 @@ SPDX-PackageComment = "The code in this project may include calls to APIs (\"API
path = [
".claude/**",
".github/**",
+ ".opencode/**",
+ "openspec/**",
"action.yml",
"test-resources/**",
"README.md",
"CONTRIBUTING.md",
+ "AGENTS.md",
".gitignore",
".husky/**",
"package-lock.json",
diff --git a/openspec/changes/monorepo-support/.openspec.yaml b/openspec/changes/monorepo-support/.openspec.yaml
new file mode 100644
index 0000000..29ed81f
--- /dev/null
+++ b/openspec/changes/monorepo-support/.openspec.yaml
@@ -0,0 +1,2 @@
+schema: sdd-plus-superpowers
+created: 2026-05-14
diff --git a/openspec/changes/monorepo-support/brainstorm.md b/openspec/changes/monorepo-support/brainstorm.md
new file mode 100644
index 0000000..76fbb27
--- /dev/null
+++ b/openspec/changes/monorepo-support/brainstorm.md
@@ -0,0 +1,59 @@
+## Design Summary
+
+Add monorepo support to `pull-request-semver-bumper` enabling independent per-package semver bumping within a single repository. The action auto-detects monorepo mode when a `bumper.monorepo.json` config file exists in the target repo root, determines which packages were touched by the PR's changed files, and bumps each one using the same bump level derived from the PR title. The design prioritizes zero impact on existing single-package users by branching early into an isolated code path.
+
+## Alternatives Considered
+
+### Option A: Early Branch — Separate Monorepo Module
+
+- **Approach**: Detect `bumper.monorepo.json` at runtime in `index.ts` after git setup. If present, branch into a completely separate orchestration path (`src/monorepo/orchestrate.ts`) handling config loading, file detection, per-package bumping, and combined commit. Existing single-package path remains untouched.
+- **Pros**: Zero risk to existing users; clean separation of concerns; each module independently testable; easy mental model ("if config exists → monorepo path")
+- **Cons**: Some shared logic (git setup, PR title parsing) runs before the branch point; two code paths to maintain long-term
+- **Why chosen**: See Agreed Approach below
+
+### Option B: Unified Pipeline with Package Loop
+
+- **Approach**: Refactor `index.ts` to always operate on a `Package[]`. Single-package mode produces a one-element list from inputs; monorepo mode produces N entries from config. Same loop handles both.
+- **Pros**: DRY, single code path; forces cleaner abstractions
+- **Cons**: Touches existing working code (regression risk); complex "N=1 special case"; harder to test parameterized paths; commit message logic gets complicated
+- **Why not chosen**: Higher risk to existing users, over-engineers the single-package case
+
+### Option C: Separate Composite Action
+
+- **Approach**: Create a new top-level `action-monorepo.yml` with an entirely separate Node action entry point.
+- **Pros**: Complete isolation from existing action
+- **Cons**: Massive code duplication; two npm projects to maintain; users must change workflow files; violates "auto-activated, no input changes" requirement
+- **Why not chosen**: Breaks the auto-detection requirement and creates maintenance burden
+
+## Agreed Approach
+
+**Option A: Early Branch with isolated `src/monorepo/` modules.**
+
+This was chosen because:
+- It preserves backward compatibility by construction — the existing code path is never entered in monorepo mode
+- New code is isolated and testable without affecting existing tests
+- Shared utilities (git, semver, parse-commit) are reused without refactoring them
+- It matches the principle of minimal change to existing working code
+- The `type` input defaults to `"auto"` enabling auto-detection for both monorepo and single-package modes
+
+## Key Decisions
+
+- **`type` input defaults to `"auto"`**: When `"auto"` (or omitted), the action auto-detects: `bumper.monorepo.json` exists → monorepo mode, no config → detect single-package type from repo root filesystem markers. Explicit values (`npm`, `maven`, `python`, `version-file`) → existing single-package behavior unchanged.
+- **Detection trigger**: `type: "auto"` + `bumper.monorepo.json` exists → monorepo mode. `type: "auto"` + no config → auto-detect single-package type from repo root. Explicit `type` → single-package with that type (unchanged).
+- **Shared `detect-type.ts` module**: Same filesystem marker logic (`package.json` → npm, `pom.xml` → maven, `pyproject.toml` → python, `VERSION` → version-file) serves both monorepo per-package detection and single-package auto-detection at repo root.
+- **Config lives in target repo**: Each monorepo defines its own structure; the config is read at runtime from the checked-out repo root, after `configureGit()` completes (guarantees PR branch is checked out).
+- **Config read timing**: Detection happens after `configureGit()` since repo files aren't guaranteed before that (fallback clone case). Order: read inputs → configureGit → detect mode → branch into monorepo or single-package path. Skip bump-command validation when `type` is `"auto"`.
+- **Changed-file detection via git diff**: `git diff --name-only origin/...HEAD` — zero new dependencies, leverages existing `simple-git` and `fetch --all` setup.
+- **Config file change triggers full bump**: If `bumper.monorepo.json` itself is among changed files, all declared packages are bumped. Ensures new packages get their initial version.
+- **Single bump level, independent versions**: The bump level (major/minor/patch) is derived from the PR title and applied uniformly. But each package maintains its own independent version — e.g., `foo@1.2.0` bumps to `foo@1.3.0` while `bar@3.0.1` bumps to `bar@3.1.0` (both get `minor`). No per-package scope differentiation.
+- **Per-package type auto-detection**: Filesystem markers (`package.json` → npm, `pom.xml` → maven, `pyproject.toml` → python, `VERSION` → version-file). Same module used for single-package auto-detection at repo root.
+- **Per-package overrides mirror action inputs**: `pom-file`, `version-property-path`, `package-json-file`, `version-file`, `pyproject-file`, `bump-command`, `post-command` — all optional per entry.
+- **Single atomic commit**: All package bumps staged together. Format: `chore: bump version packages/foo@1.2.0 packages/bar@2.1.0`. No partial commits on failure.
+- **`new-version` output differs by mode**: Single-package → plain string `"1.2.0"`. Monorepo → JSON map `{"packages/foo":"1.2.0","packages/bar":"2.1.0"}`. Consumers adopting monorepo mode adapt their parsing.
+- **All-or-nothing error handling**: If any package bump fails, the entire action fails with a clear error identifying the failing package.
+- **Package path matching**: A changed file triggers a bump for every declared package whose `path` is a prefix of the file path. Overlapping paths are allowed — file can trigger multiple packages.
+- **Glob support in paths**: `"path": "packages/*"` expands to immediate subdirectories (one level only) that contain a detectable version file marker. Expanded packages inherit the parent entry's overrides. Exact paths and glob paths coexist in the same config.
+
+## Open Questions
+
+None — design is fully resolved through brainstorming session.
diff --git a/openspec/changes/monorepo-support/design.md b/openspec/changes/monorepo-support/design.md
new file mode 100644
index 0000000..5b541c8
--- /dev/null
+++ b/openspec/changes/monorepo-support/design.md
@@ -0,0 +1,93 @@
+## Context
+
+The `pull-request-semver-bumper` GitHub Action currently supports single-package repositories only. It reads a PR title (Conventional Commits format), determines the bump level, fetches the current version from the base branch, computes the new version via `semver.inc()`, runs a bump command, and commits the result.
+
+The architecture is linear: `index.ts` → git setup → parse PR → fetch version → bump → commit → push. All version operations target a single file in a single location. There is no concept of multiple packages, scoped commits, or selective bumping.
+
+**Constraints:**
+- Backward compatibility is mandatory — existing single-package users must not be affected
+- The action is used across SAP repositories; breaking changes require major version bump
+- `dist/index.js` is committed (ncc bundle); build must remain simple
+- Target repos have heterogeneous structures (npm, maven, python, version-file mixed in one repo)
+
+**Stakeholders:** Monorepo maintainers who currently cannot use this action, plus all existing single-package users who must not experience regressions.
+
+## Goals / Non-Goals
+
+**Goals:**
+- Enable per-package semver bumping in monorepos with a single config file
+- Auto-detect monorepo mode without requiring changes to existing workflow files
+- Support heterogeneous package types within one repo
+- Provide glob-based package discovery for convenience
+- Maintain zero impact on existing single-package behavior
+
+**Non-Goals:**
+- Per-package bump levels based on commit scopes (e.g., `feat(auth):`) — single bump level for all touched packages
+- Synchronized versioning (all packages share one version number) — each package maintains its own independent version
+- Recursive glob discovery (`**`) — only one level deep (`*`)
+- Independent versioning strategies per package (e.g., one on pre-release, another on stable)
+- Single-package type auto-detection is included in this change (not deferred) — shared `detect-type.ts` module
+- Workspace dependency graph resolution (e.g., bumping dependents when a dependency bumps)
+
+## Decisions
+
+**Decision: Early branch architecture**
+- Chosen: Detect monorepo config after `configureGit()`, branch into isolated `src/monorepo/` modules
+- Reason: Zero risk to existing users by construction — the single-package code path is never entered in monorepo mode. New code is independently testable.
+- Alternatives considered: Unified pipeline (regression risk, over-engineering), separate composite action (code duplication, breaks auto-detection requirement)
+
+**Decision: `type` input defaults to `"auto"`**
+- Chosen: Default value `"auto"` triggers auto-detection. Config file presence determines monorepo vs single-package. Same `detect-type.ts` module handles both cases.
+- Reason: Explicit default value is clearer than empty-string semantics. Existing users with explicit types are unaffected. New users get auto-detection out of the box. Single `"auto"` value cleanly covers both monorepo detection and single-package type detection.
+- Alternatives considered: No default / empty string (less explicit), required input (blocks auto-detection), separate boolean input (unnecessary given config file detection)
+
+**Decision: Git diff for changed-file detection**
+- Chosen: `git diff --name-only origin/...HEAD` via existing `simple-git`
+- Reason: Zero new dependencies. `configureGit()` already runs `fetch --all`, so base branch ref is available. Three-dot diff gives exactly "changes introduced by PR branch." No pagination limits.
+- Alternatives considered: GitHub API `pulls/{pr}/files` (requires Octokit, pagination handling for >100 files, stale `@octokit/rest@17.x` already in deps)
+
+**Decision: Config read after `configureGit()`**
+- Chosen: Read `bumper.monorepo.json` only after git setup completes
+- Reason: The action has a fallback clone path (if `.git` doesn't exist). Repo files aren't guaranteed on disk until after `configureGit()`. Reading after checkout also ensures we get the PR branch's version of the config.
+- Alternatives considered: Read before git setup (breaks in fallback clone case)
+
+**Decision: Glob expansion at config load time (one level only)**
+- Chosen: `"path": "packages/*"` expands to immediate subdirectories containing a version file marker
+- Reason: Convenience for large monorepos without recursive discovery surprises. `*` naturally means one level in glob semantics. `**` reserved for future use (rejected today).
+- Alternatives considered: Require all paths to be explicit (tedious for 10+ packages), recursive discovery (too risky, catches test fixtures)
+
+**Decision: All-match semantics for path overlap**
+- Chosen: A changed file triggers bumps for ALL packages whose `path` is a prefix match
+- Reason: Simpler than "first match wins" (no ordering dependency). Config owner controls overlap by choosing non-overlapping paths if desired.
+- Alternatives considered: First match wins (config order matters — fragile), longest prefix match (complex, unnecessary)
+
+**Decision: `new-version` output format differs by mode**
+- Chosen: Plain string in single-package mode, JSON map in monorepo mode
+- Reason: Monorepo mode is new — consumers opting in already make workflow changes. Clean semantic: mode determines output format.
+- Alternatives considered: Always JSON (breaks existing consumers), dynamic per-package outputs (fragile naming)
+
+## Risks / Trade-offs
+
+- [Two code paths to maintain long-term] → Shared utilities (git, semver, parse-commit) remain DRY; only orchestration logic is duplicated. Acceptable given backward compat guarantee.
+- [Glob expansion could discover unintended packages] → Mitigated by requiring a version file marker in subdirectory. Directories without `package.json`/`pom.xml`/`pyproject.toml`/`VERSION` are skipped.
+- [`type: "auto"` with no config and no detectable type at repo root] → Clear error: "Could not detect package type. Specify `type` explicitly or add a version file (package.json, pom.xml, pyproject.toml, or VERSION) to the repo root."
+- [Large PRs with many changed files] → Git diff has no pagination limits (unlike GitHub API's 3000 file cap). Performance is bounded by git operation time, which is already the baseline.
+- [Config file change triggers bump of ALL packages] → Deliberate — ensures new packages get initial version. Documented behavior; users can split config changes into separate PRs if needed.
+
+## Migration Plan
+
+**Deployment steps:**
+1. Make `type` input optional with default `"auto"` in root `action.yml` and all composite wrappers
+2. Add `detect-type.ts` module with shared filesystem marker detection logic
+3. Ship new `src/monorepo/` modules behind config file detection gate
+4. Single-package auto-detection enabled when `type` is `"auto"` and no monorepo config exists
+5. Existing users: no change needed — their explicit `type: npm/maven/etc.` bypasses all auto-detection
+6. New monorepo users: add `bumper.monorepo.json` to repo root, leave `type` at default `"auto"`
+7. New single-package users: can leave `type` at default `"auto"` if repo root has a detectable version file
+
+**Rollback:**
+- Revert to previous version tag (`@v1` → `@v1` prior release). Since monorepo mode is additive and gated behind config file detection, there is no state to clean up — removing the config file also disables monorepo mode.
+
+## Open Questions
+
+None — all design decisions resolved during brainstorming.
diff --git a/openspec/changes/monorepo-support/proposal.md b/openspec/changes/monorepo-support/proposal.md
new file mode 100644
index 0000000..e75adfc
--- /dev/null
+++ b/openspec/changes/monorepo-support/proposal.md
@@ -0,0 +1,48 @@
+## Why
+
+Monorepo repositories cannot use `pull-request-semver-bumper` today because the action only supports a single version file in a single location. Teams with multiple independently-versioned packages in one repo must either maintain separate CI jobs with hardcoded paths or forgo automated version bumping entirely. Adding monorepo support and type auto-detection removes this gap, making the action usable for the growing number of SAP monorepos while simultaneously simplifying onboarding for new single-package users who no longer need to specify their build type explicitly.
+
+## What Changes
+
+**`type` Input Behavior**
+- From: `type` is required; must be one of `npm`, `maven`, `python`, `version-file`
+- To: `type` defaults to `"auto"`; auto-detects monorepo mode (via config file) or single-package type (via filesystem markers). Explicit values still work unchanged.
+- Reason: Enables monorepo auto-activation and simplifies single-package onboarding
+- Impact: Non-breaking — existing users pass explicit types which bypass auto-detection
+
+**New Monorepo Orchestration Path**
+- From: Single linear pipeline in `index.ts` (one package, one bump, one commit)
+- To: Early branch after `configureGit()` into isolated `src/monorepo/` modules when `bumper.monorepo.json` is detected
+- Reason: Zero risk to existing single-package users; clean separation of concerns
+- Impact: Non-breaking — additive code path gated behind config file presence
+
+**`new-version` Output Format**
+- From: Always a plain string (`"1.2.0"`)
+- To: Plain string in single-package mode; JSON map (`{"packages/foo":"1.2.0","packages/bar":"2.1.0"}`) in monorepo mode
+- Reason: Monorepo mode produces multiple versions; a map is the natural representation
+- Impact: Non-breaking — only monorepo mode (new feature) produces the map format
+
+## Capabilities
+
+### New Capabilities
+
+- `monorepo-config-loading`: Parse and validate `bumper.monorepo.json` from target repo root, expand glob patterns (`packages/*`) one level deep, auto-detect package types from filesystem markers
+- `changed-file-detection`: Cross-reference PR changed files (via `git diff`) against declared package paths to determine which packages need bumping
+- `monorepo-orchestration`: Coordinate per-package version bumping — fetch current version per package from base branch, apply uniform bump level, execute per-package bump/post commands, produce single atomic commit
+- `type-auto-detection`: Shared module detecting package type from filesystem markers (`package.json` → npm, `pom.xml` → maven, `pyproject.toml` → python, `VERSION` → version-file). Serves both monorepo per-package detection and single-package auto-detection at repo root.
+- `e2e-test-fixtures`: Restructure `test-resources/` as a single monorepo-style layout with per-type packages. Monorepo E2E tests use the config directly; single-package E2E tests map paths to individual package directories. One fixture set serves both modes.
+
+### Modified Capabilities
+
+None — existing single-package behavior is preserved unchanged. The `type` input default change is additive (new default value, existing explicit values unaffected).
+
+## Impact
+
+- **Source code**: New `src/monorepo/` directory (4 modules); minor addition to `index.ts` (early branch); extension to `git/git.ts` (changed-file detection, multi-package commit message)
+- **action.yml**: `type` input changes from required to optional with default `"auto"`
+- **Composite wrappers**: Unaffected (they pass explicit `build-type` to core action)
+- **Dependencies**: None added — uses existing `simple-git` and `semver`
+- **Outputs**: `new-version` format differs in monorepo mode (JSON map vs string)
+- **CI**: Existing tests restructured; single-package E2E tests point to individual package paths within the unified fixture. New monorepo E2E tests added.
+- **Test resources**: `test-resources/` reorganized as monorepo-style layout — single fixture set serves both monorepo and single-package E2E tests
+- **Bundle size**: Modest increase in `dist/index.js` from new modules
diff --git a/openspec/changes/monorepo-support/specs/changed-file-detection/spec.md b/openspec/changes/monorepo-support/specs/changed-file-detection/spec.md
new file mode 100644
index 0000000..1d1fc18
--- /dev/null
+++ b/openspec/changes/monorepo-support/specs/changed-file-detection/spec.md
@@ -0,0 +1,57 @@
+## ADDED Requirements
+
+### Requirement: Changed files retrieval
+
+The action SHALL retrieve the list of files changed in the PR using `git diff --name-only origin/...HEAD`.
+
+#### Scenario: Normal PR with changed files
+
+- **WHEN** the PR branch has commits that modify files
+- **THEN** the action SHALL return a list of all file paths changed relative to the base branch
+
+#### Scenario: No files changed
+
+- **WHEN** the PR branch has no file differences from the base branch
+- **THEN** the action SHALL return an empty list
+
+---
+
+### Requirement: Package path matching
+
+The action SHALL match each changed file against all declared package paths using prefix matching. A file MAY trigger bumps for multiple packages if their paths overlap.
+
+#### Scenario: File matches single package
+
+- **WHEN** changed file `packages/foo/src/index.ts` exists and package path `packages/foo` is declared
+- **THEN** the action SHALL include `packages/foo` in the set of touched packages
+
+#### Scenario: File matches multiple packages
+
+- **WHEN** changed file `packages/foo/sub/lib.ts` exists and both `packages/foo` and `packages/foo/sub` are declared
+- **THEN** the action SHALL include both packages in the set of touched packages
+
+#### Scenario: File matches no package
+
+- **WHEN** a changed file path does not start with any declared package path
+- **THEN** the action SHALL not include any package for that file
+
+#### Scenario: No packages touched
+
+- **WHEN** no changed files match any declared package path and the config file is not changed
+- **THEN** the action SHALL set output `bumped: false` and exit without making a commit
+
+---
+
+### Requirement: Config file change detection
+
+The action SHALL bump all declared packages when `bumper.monorepo.json` itself is among the changed files.
+
+#### Scenario: Config file modified in PR
+
+- **WHEN** `bumper.monorepo.json` is in the list of changed files
+- **THEN** the action SHALL include ALL packages declared in the config in the set of touched packages
+
+#### Scenario: Config file not modified
+
+- **WHEN** `bumper.monorepo.json` is not in the list of changed files
+- **THEN** the action SHALL only include packages whose paths match changed files
diff --git a/openspec/changes/monorepo-support/specs/e2e-test-fixtures/spec.md b/openspec/changes/monorepo-support/specs/e2e-test-fixtures/spec.md
new file mode 100644
index 0000000..207ab0e
--- /dev/null
+++ b/openspec/changes/monorepo-support/specs/e2e-test-fixtures/spec.md
@@ -0,0 +1,57 @@
+## ADDED Requirements
+
+### Requirement: Unified monorepo-style fixture layout
+
+The `test-resources/` directory SHALL be structured as a monorepo with per-type packages, serving both monorepo and single-package E2E tests from a single fixture set.
+
+#### Scenario: Fixture structure
+
+- **WHEN** the test resources are checked out
+- **THEN** the directory SHALL contain a `bumper.monorepo.json` config and subdirectories for each package type (npm, maven, python, version-file)
+
+#### Scenario: Config file points to fixture packages
+
+- **WHEN** the monorepo E2E test reads `test-resources/bumper.monorepo.json`
+- **THEN** the config SHALL declare paths to the fixture packages within `test-resources/`
+
+---
+
+### Requirement: Single-package E2E tests use fixture paths
+
+Single-package E2E tests SHALL reference individual package directories within the unified fixture layout via path inputs.
+
+#### Scenario: npm single-package test
+
+- **WHEN** the npm E2E test runs
+- **THEN** it SHALL point `package-json-file` to the npm package's `package.json` within the fixture layout
+
+#### Scenario: maven single-package test
+
+- **WHEN** the maven E2E test runs
+- **THEN** it SHALL point `pom-file` to the maven package's `pom.xml` within the fixture layout
+
+#### Scenario: python single-package test
+
+- **WHEN** the python E2E test runs
+- **THEN** it SHALL point `pyproject-file` to the python package's `pyproject.toml` within the fixture layout
+
+#### Scenario: version-file single-package test
+
+- **WHEN** the version-file E2E test runs
+- **THEN** it SHALL point `version-file` to the version-file package's `VERSION` within the fixture layout
+
+---
+
+### Requirement: Monorepo E2E tests
+
+Monorepo E2E tests SHALL validate multi-package bumping using the unified fixture layout.
+
+#### Scenario: Monorepo dry-run test
+
+- **WHEN** the monorepo E2E test runs with `type: auto` and `dry-run: true`
+- **THEN** the action SHALL detect `bumper.monorepo.json`, identify touched packages, compute versions, and set outputs without pushing
+
+#### Scenario: Heterogeneous package types
+
+- **WHEN** the monorepo fixture includes packages of different types (npm, maven, python, version-file)
+- **THEN** the E2E test SHALL verify each package type is bumped correctly using its respective mechanism
diff --git a/openspec/changes/monorepo-support/specs/monorepo-config-loading/spec.md b/openspec/changes/monorepo-support/specs/monorepo-config-loading/spec.md
new file mode 100644
index 0000000..65e7705
--- /dev/null
+++ b/openspec/changes/monorepo-support/specs/monorepo-config-loading/spec.md
@@ -0,0 +1,98 @@
+## ADDED Requirements
+
+### Requirement: Config file detection
+
+The action SHALL detect monorepo mode by checking for a `bumper.monorepo.json` file in the repository root after `configureGit()` completes.
+
+#### Scenario: Config file present
+
+- **WHEN** `bumper.monorepo.json` exists at the repository root and `type` is `"auto"`
+- **THEN** the action SHALL enter monorepo mode
+
+#### Scenario: Config file absent
+
+- **WHEN** `bumper.monorepo.json` does not exist at the repository root and `type` is `"auto"`
+- **THEN** the action SHALL fall through to single-package type auto-detection
+
+#### Scenario: Explicit type bypasses detection
+
+- **WHEN** `type` is set to an explicit value (`npm`, `maven`, `python`, `version-file`)
+- **THEN** the action SHALL use single-package mode regardless of config file presence
+
+---
+
+### Requirement: Config schema validation
+
+The action SHALL validate the parsed `bumper.monorepo.json` against the expected schema and fail with a clear error if validation fails.
+
+#### Scenario: Valid config
+
+- **WHEN** the config file contains a `packages` array with at least one entry, each having a `path` string
+- **THEN** the action SHALL accept the config and proceed
+
+#### Scenario: Empty packages array
+
+- **WHEN** the config file contains an empty `packages` array
+- **THEN** the action SHALL fail with error: "bumper.monorepo.json: packages array must not be empty"
+
+#### Scenario: Missing path field
+
+- **WHEN** a package entry lacks a `path` field
+- **THEN** the action SHALL fail with error identifying the invalid entry
+
+#### Scenario: Duplicate paths
+
+- **WHEN** two package entries declare the same `path` (after glob expansion)
+- **THEN** the action SHALL fail with error identifying the duplicate
+
+#### Scenario: Invalid type value
+
+- **WHEN** a package entry specifies a `type` not in (`npm`, `maven`, `python`, `version-file`)
+- **THEN** the action SHALL fail with error identifying the invalid type
+
+#### Scenario: Absolute or parent-traversal path
+
+- **WHEN** a package entry `path` starts with `/` or contains `..`
+- **THEN** the action SHALL fail with error: "package paths must be relative without parent traversal"
+
+---
+
+### Requirement: Glob expansion
+
+The action SHALL expand glob patterns in package paths one level deep to discover subdirectories that contain a detectable version file marker.
+
+#### Scenario: Wildcard path expansion
+
+- **WHEN** a package entry has `"path": "packages/*"`
+- **THEN** the action SHALL expand it to all immediate subdirectories of `packages/` that contain at least one of: `package.json`, `pom.xml`, `pyproject.toml`, `VERSION`
+
+#### Scenario: No matching subdirectories
+
+- **WHEN** a glob pattern expands to zero qualifying subdirectories
+- **THEN** the action SHALL log a warning but not fail (other packages may still be valid)
+
+#### Scenario: Override inheritance
+
+- **WHEN** a glob entry includes overrides (e.g., `"bump-command": "..."`)
+- **THEN** expanded packages SHALL inherit those overrides
+
+#### Scenario: Recursive glob rejected
+
+- **WHEN** a package entry path contains `**`
+- **THEN** the action SHALL fail with error: "recursive globs (**) are not supported, use single-level (*) only"
+
+---
+
+### Requirement: Per-package override fields
+
+Each package entry SHALL support optional override fields that mirror the action's single-package inputs.
+
+#### Scenario: Override fields applied
+
+- **WHEN** a package entry includes `pom-file`, `version-property-path`, `package-json-file`, `version-file`, `pyproject-file`, `bump-command`, or `post-command`
+- **THEN** the action SHALL use those values instead of defaults for that package
+
+#### Scenario: Override fields absent
+
+- **WHEN** a package entry omits override fields
+- **THEN** the action SHALL use the default file paths and commands for the detected type
diff --git a/openspec/changes/monorepo-support/specs/monorepo-orchestration/spec.md b/openspec/changes/monorepo-support/specs/monorepo-orchestration/spec.md
new file mode 100644
index 0000000..7e5dda2
--- /dev/null
+++ b/openspec/changes/monorepo-support/specs/monorepo-orchestration/spec.md
@@ -0,0 +1,115 @@
+## ADDED Requirements
+
+### Requirement: Per-package version fetching
+
+The action SHALL fetch the current version for each touched package independently from the base branch.
+
+#### Scenario: Fetch version for npm package
+
+- **WHEN** a touched package has type `npm`
+- **THEN** the action SHALL read the version from `git show origin/:/` and parse the `version` field
+
+#### Scenario: Fetch version for maven package
+
+- **WHEN** a touched package has type `maven`
+- **THEN** the action SHALL read the version from `git show origin/:/` using the configured `version-property-path`
+
+#### Scenario: Fetch version for python package
+
+- **WHEN** a touched package has type `python`
+- **THEN** the action SHALL read the version from `git show origin/:/` and parse the `version` field
+
+#### Scenario: Fetch version for version-file package
+
+- **WHEN** a touched package has type `version-file`
+- **THEN** the action SHALL read the version from `git show origin/:/` as a plain string
+
+---
+
+### Requirement: Uniform bump level application
+
+The action SHALL apply the same bump level (derived from PR title) to all touched packages. Each package maintains its own independent version.
+
+#### Scenario: Minor bump across packages with different versions
+
+- **WHEN** bump level is `minor`, package A is at `1.2.0`, and package B is at `3.0.1`
+- **THEN** the action SHALL bump A to `1.3.0` and B to `3.1.0`
+
+#### Scenario: Major bump
+
+- **WHEN** bump level is `major` and package is at `1.2.3`
+- **THEN** the action SHALL bump to `2.0.0`
+
+---
+
+### Requirement: Per-package bump command execution
+
+The action SHALL execute the appropriate bump command for each touched package in its package directory.
+
+#### Scenario: Default bump command for npm
+
+- **WHEN** package type is `npm` and no custom `bump-command` is specified
+- **THEN** the action SHALL execute the default npm version command in the package directory with `@NEW_VERSION@` replaced
+
+#### Scenario: Custom bump command
+
+- **WHEN** a package entry specifies a `bump-command`
+- **THEN** the action SHALL execute that command in the package directory with `@NEW_VERSION@` replaced by the computed version
+
+#### Scenario: Post command execution
+
+- **WHEN** a package entry specifies a `post-command`
+- **THEN** the action SHALL execute the post command in the package directory after the bump command succeeds
+
+---
+
+### Requirement: Single atomic commit
+
+The action SHALL stage all version file changes across all touched packages and create a single combined commit.
+
+#### Scenario: Multiple packages bumped
+
+- **WHEN** packages `packages/foo` (bumped to `1.3.0`) and `packages/bar` (bumped to `2.1.0`) are touched
+- **THEN** the action SHALL create one commit with message: `chore: bump version packages/foo@1.3.0 packages/bar@2.1.0`
+
+#### Scenario: Single package bumped in monorepo
+
+- **WHEN** only one package `packages/foo` (bumped to `1.3.0`) is touched
+- **THEN** the action SHALL create one commit with message: `chore: bump version packages/foo@1.3.0`
+
+#### Scenario: Dry-run mode
+
+- **WHEN** `dry-run` input is `true`
+- **THEN** the action SHALL compute versions and execute bump commands but SHALL NOT push the commit
+
+---
+
+### Requirement: All-or-nothing error handling
+
+The action SHALL fail entirely if any package bump operation fails. No partial commits SHALL be created.
+
+#### Scenario: Bump command fails for one package
+
+- **WHEN** the bump command fails for package B after package A succeeded
+- **THEN** the action SHALL fail with an error identifying package B and SHALL NOT commit or push any changes
+
+#### Scenario: Version fetch fails
+
+- **WHEN** fetching the current version fails for a package (e.g., file not found on base branch)
+- **THEN** the action SHALL fail with a clear error identifying the package and file path
+
+---
+
+### Requirement: Monorepo outputs
+
+The action SHALL set outputs appropriate for monorepo mode.
+
+#### Scenario: Packages bumped successfully
+
+- **WHEN** one or more packages are bumped
+- **THEN** the action SHALL set `bumped: true`, `bumpLevel: `, and `new-version` as a JSON map of `{: }`
+
+#### Scenario: No packages touched
+
+- **WHEN** no packages are in the touched set
+- **THEN** the action SHALL set `bumped: false` and `new-version` as an empty JSON object `{}`
diff --git a/openspec/changes/monorepo-support/specs/type-auto-detection/spec.md b/openspec/changes/monorepo-support/specs/type-auto-detection/spec.md
new file mode 100644
index 0000000..e8be9bc
--- /dev/null
+++ b/openspec/changes/monorepo-support/specs/type-auto-detection/spec.md
@@ -0,0 +1,72 @@
+## ADDED Requirements
+
+### Requirement: Filesystem marker detection
+
+The `detect-type` module SHALL determine a package type by checking for the presence of well-known files in the target directory, using a fixed priority order.
+
+#### Scenario: npm detected
+
+- **WHEN** `package.json` exists in the target directory
+- **THEN** the module SHALL return type `npm`
+
+#### Scenario: maven detected
+
+- **WHEN** `pom.xml` exists in the target directory and `package.json` does not
+- **THEN** the module SHALL return type `maven`
+
+#### Scenario: python detected
+
+- **WHEN** `pyproject.toml` exists in the target directory and neither `package.json` nor `pom.xml` exist
+- **THEN** the module SHALL return type `python`
+
+#### Scenario: version-file detected
+
+- **WHEN** a `VERSION` file exists in the target directory and no other markers are present
+- **THEN** the module SHALL return type `version-file`
+
+#### Scenario: No markers found
+
+- **WHEN** none of the recognized markers exist in the target directory
+- **THEN** the module SHALL return `null` (detection failed)
+
+#### Scenario: Detection priority
+
+- **WHEN** multiple markers exist in the same directory (e.g., both `package.json` and `pom.xml`)
+- **THEN** the module SHALL use priority order: `package.json` > `pom.xml` > `pyproject.toml` > `VERSION`
+
+---
+
+### Requirement: Single-package auto-detection at repo root
+
+When `type` is `"auto"` and no `bumper.monorepo.json` exists, the action SHALL auto-detect the package type from the repository root.
+
+#### Scenario: Type detected at root
+
+- **WHEN** `type` is `"auto"`, no monorepo config exists, and `package.json` exists at repo root
+- **THEN** the action SHALL proceed in single-package mode with type `npm`
+
+#### Scenario: No type detected at root
+
+- **WHEN** `type` is `"auto"`, no monorepo config exists, and no markers are found at repo root
+- **THEN** the action SHALL fail with error: "Could not detect package type. Specify `type` explicitly or add a version file (package.json, pom.xml, pyproject.toml, or VERSION) to the repo root."
+
+---
+
+### Requirement: Per-package type detection in monorepo mode
+
+In monorepo mode, when a package entry does not specify `type`, the action SHALL auto-detect the type from the package directory.
+
+#### Scenario: Type auto-detected for package
+
+- **WHEN** a package entry omits `type` and `pom.xml` exists in its directory
+- **THEN** the action SHALL assign type `maven` to that package
+
+#### Scenario: Type detection fails for package
+
+- **WHEN** a package entry omits `type` and no markers exist in its directory
+- **THEN** the action SHALL fail with error identifying the package path and listing expected markers
+
+#### Scenario: Explicit type overrides detection
+
+- **WHEN** a package entry specifies `"type": "maven"`
+- **THEN** the action SHALL use `maven` regardless of what files exist in the directory
diff --git a/openspec/config.yaml b/openspec/config.yaml
new file mode 100644
index 0000000..392946c
--- /dev/null
+++ b/openspec/config.yaml
@@ -0,0 +1,20 @@
+schema: spec-driven
+
+# Project context (optional)
+# This is shown to AI when creating artifacts.
+# Add your tech stack, conventions, style guides, domain knowledge, etc.
+# Example:
+# context: |
+# Tech stack: TypeScript, React, Node.js
+# We use conventional commits
+# Domain: e-commerce platform
+
+# Per-artifact rules (optional)
+# Add custom rules for specific artifacts.
+# Example:
+# rules:
+# proposal:
+# - Keep proposals under 500 words
+# - Always include a "Non-goals" section
+# tasks:
+# - Break tasks into chunks of max 2 hours