Skip to content

Support source-to-destination mappings in aw.yml includes - #53698

Merged
pelikhan merged 5 commits into
mainfrom
copilot/support-source-to-destination-mappings
Aug 18, 2026
Merged

Support source-to-destination mappings in aw.yml includes#53698
pelikhan merged 5 commits into
mainfrom
copilot/support-source-to-destination-mappings

Conversation

Copilot AI commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Nested aw.yml packages treat .github/** entries as repository-root-relative (ADR-41790), so a distribution repository cannot keep executable workflow assets inert under a package directory and still install them into the consumer's .github/workflows/. includes accepted only path strings, with no way to express separate source and destination paths.

includes entries may now be an object declaring a package-relative source and a repository-relative destination:

# factory/aw.yml — installed via `gh aw add owner/repo/factory`
name: Factory
includes:
  - source: payload/workflows/reviewer.md      # fetched from factory/payload/workflows/
    destination: .github/workflows/reviewer.md # installed at the repo root
    kind: agentic-workflow
  - source: payload/workflows/controller.yml
    destination: .github/workflows/controller.yml
    kind: action-workflow

The sources stay outside .github/workflows/ in the distribution repository, so they never run there.

Schema

  • includes items accept the existing string form or an object with required source/destination and optional kind (agentic-workflow | action-workflow).

Model and resolution

  • Manifest entries parse into repositoryPackageInclude; resolution yields resolvedPackageInstallable{SourcePath, DestinationPath}, replacing bare path strings across package resolution (resolvedRepositoryPackage.InstallationSource).
  • Legacy string semantics are unchanged: .github/** stays repository-root-relative, everything else stays package-relative. Mapping source is always resolved against the package path; destination is validated independently as a repository-root install path.
  • String entries get an implicit destination (.github/workflows/<basename>), unifying downstream handling.

Validation

Mappings are rejected for absolute paths (including Windows drive prefixes), .. traversal, unsupported or .lock.yml extensions, extension changes between source and destination, destinations outside or nested under .github/workflows/, and kind that disagrees with the source extension. Local packages additionally reject symlinked, missing, or directory sources. Duplicate destinations are detected before any file is written. No package-provided shell code is executed.

Install and update

  • WorkflowSpec.DestinationPath carries the resolved install path; WorkflowName is derived from it, so a mapped entry installs under its destination name. .md compiles, .yml is copied verbatim.
  • gh aw update keys installed workflows by destination and maps them back to package sources, preserving manifest-scoped source tracking.
  • gh aw add-wizard reuses AddResolvedWorkflows, so semantics are identical across add, add-wizard, and update.

Docs

Reference and specification (§4.9) updated, including an explicit statement of the differing resolution rules for .github/** string entries versus mapping sources.

Tests

New add_package_manifest_mapping_test.go covers nested packages (remote fetch of factory/payload/... installing to .github/workflows/...), root packages, mixed legacy/mapping entries, destination renaming, every rejection case, duplicate destinations for both .md and .yml, local symlink/missing-source handling, update name→source mapping, and an end-to-end install asserting mapped destinations for agentic and deterministic workflows.

Copilot AI and others added 2 commits August 18, 2026 13:44
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Support source-to-destination mappings for inert nested packages Support source-to-destination mappings in aw.yml includes Aug 18, 2026
Copilot AI requested a review from pelikhan August 18, 2026 13:53
@pelikhan
pelikhan marked this pull request as ready for review August 18, 2026 14:34
Copilot AI balanced review requested due to automatic review settings August 18, 2026 14:34
@github-actions

github-actions Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Design Decision Gate 🏗️ completed the design decision gate check.

🏗️ ADR gate enforced by Design Decision Gate 🏗️

@github-actions

github-actions Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

PR Code Quality Reviewer completed the code quality review.

🔎 Code quality review by PR Code Quality Reviewer

@github-actions

github-actions Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Test Quality Sentinel completed test quality analysis.

Test Quality Sentinel skipped because pre-fetch PR data was unavailable: unable to fetch test file diff

🧪 Test quality analysis by Test Quality Sentinel

@github-actions

github-actions Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

🧠 Matt Pocock Skills Reviewer has completed the skills-based review. ✅

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer

@github-actions

github-actions Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Ponytail Reviewer completed successfully!

Generated by Ponytail Reviewer for #53698

@github-actions

Copy link
Copy Markdown
Contributor

Comment Memory

reviewed_at: 2026-08-18T00:00:00Z
review_event: REQUEST_CHANGES
top_themes:
  - update path still assumes new manifest-managed entries are markdown
  - mapped .yml action workflows are not added correctly during gh aw update
files_reviewed:
  - docs/src/content/docs/reference/aw-yml-package-manifest.md
  - docs/src/content/docs/specs/repository-package-manifest-specification.md
  - pkg/cli/add_command.go
  - pkg/cli/add_package_manifest.go
  - pkg/cli/add_package_manifest_mapping_test.go
  - pkg/cli/add_package_manifest_test.go
  - pkg/cli/add_workflow_resolution.go
  - pkg/cli/add_workflow_resolution_manifest_ref_test.go
  - pkg/cli/compile_repository_manifest.go
  - pkg/cli/spec.go
  - pkg/cli/update_manifest.go
  - pkg/parser/schemas/aw_manifest_schema.json
comment_count: 1

Note

This comment is managed by comment memory.

It stores persistent context for this thread in the code block at the top of this comment.
Edit only the text inside the backtick fences; workflow metadata and the footer are regenerated automatically.

Learn more about comment memory

🔎 Code quality review by PR Code Quality Reviewer · gpt54 · 25.6 AIC · ⌖ 10 AIC · ⊞ 7K ·
Comment /review to run again

@github-actions github-actions Bot left a comment

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.

REQUEST_CHANGES

The manifest-mapping parsing and validation look mostly reasonable, but the update path still assumes every newly added manifest-managed workflow is markdown. That leaves the new source→destination support incomplete for .yml action-workflow mappings and will break gh aw update for that case.

Blocking theme
  • New manifest-managed action workflows added during gh aw update are still funneled through markdown-only frontmatter rewriting and written as *.md, so mapped .yml entries cannot be added correctly.

🔎 Code quality review by PR Code Quality Reviewer · gpt54 · 25.6 AIC · ⌖ 10 AIC · ⊞ 7K
Comment /review to run again

Comments that could not be inline-anchored

pkg/cli/update_manifest.go:301

This breaks gh aw update for manifest-managed .yml mappings: when a package adds a new action-workflow entry, addManifestManagedWorkflow still rewrites frontmatter and writes name + &quot;.md&quot;, so the update path either errors on YAML input or installs the new file with the wrong extension instead of creating the declared .yml workflow.

<details><summary>💡 Why this is blocking</summary>

manifestWorkflowPathByName() now correctly includes only markdown entries, but the add path still a…

@github-actions github-actions Bot left a comment

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.

Review: Support source-to-destination mappings in aw.yml includes

The implementation is well-structured. The type refactor ([]string[]resolvedPackageInstallable) is applied consistently across all call sites, the JSON schema is updated to accept both string and object entries, and the new test file provides solid coverage of the mapping feature.

Two issues worth addressing:

🟡 Medium — validateUniqueManifestInstallDestinations not called in validateLocalRepositoryPackageContents

resolveRepositoryPackageInstallablePaths (remote) and resolveLocalRepositoryPackage (local install) both call validateUniqueManifestInstallDestinations after the PR. However, validateLocalRepositoryPackageContents in compile_repository_manifest.go (used by gh aw compile) only calls validateManifestInstallableWorkflowPrivacy — it does not call validateUniqueManifestInstallDestinations. Two mapping entries with the same destination will therefore pass gh aw compile silently, even though the spec says duplicate destinations must be rejected before any file is written.

🔵 Low — normalizePackageInstallablePaths deduplicates on source path, not destination

if _, exists := seen[sourcePath]; exists {
    continue
}
seen[sourcePath] = struct{}{}

Two entries with different sources but the same destination (e.g. a string entry and a mapping entry that both resolve to .github/workflows/foo.md) will both be retained and will only be caught later by validateUniqueManifestInstallDestinations. That later check covers the case, so this isn't a bug per se — but adding the destination to the seen key (or checking both) in normalizePackageInstallablePaths would make the deduplication self-contained and easier to reason about.

🧵 Reviewed using Impeccable skills by Impeccable Skills Reviewer · sonnet46 · 54.4 AIC · ⌖ 9.01 AIC · ⊞ 5.7K

installationSources = packageInstallablesFromSourcePaths(scanned)
}

return validateManifestInstallableWorkflowPrivacy(manifestPath, installationSources, func(sourcePath string) ([]byte, error) {

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.

Missing validateUniqueManifestInstallDestinations call

validateLocalRepositoryPackageContents (used by gh aw compile) builds installationSources but then only calls validateManifestInstallableWorkflowPrivacy. It never calls validateUniqueManifestInstallDestinations, so two mapping entries that resolve to the same destination will silently pass gh aw compile even though the spec requires this to be rejected before any file is written.

Add the missing check after the existing validateManifestInstallableWorkflowPrivacy call:

if err := validateUniqueManifestInstallDestinations(installationSources, manifestPath); err != nil {
    return err
}

@copilot please address this.

Copilot AI left a comment

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.

Pull request overview

Adds source-to-destination mappings for repository package workflows while preserving legacy include resolution.

Changes:

  • Extends manifest schema, parsing, validation, and resolution.
  • Threads destinations through installation and update logic.
  • Adds mapping tests and documentation.
Show a summary per file
File Description
pkg/parser/schemas/aw_manifest_schema.json Defines mapping schema.
pkg/cli/update_manifest.go Maps installed names to sources.
pkg/cli/spec.go Adds destination metadata.
pkg/cli/compile_repository_manifest.go Adapts manifest validation.
pkg/cli/add_workflow_resolution.go Resolves local and remote destinations.
pkg/cli/add_workflow_resolution_manifest_ref_test.go Updates resolution fixtures.
pkg/cli/add_package_manifest.go Parses and validates mappings.
pkg/cli/add_package_manifest_test.go Updates manifest tests.
pkg/cli/add_package_manifest_mapping_test.go Tests mapping behavior.
pkg/cli/add_command.go Installs using destination-derived names.
docs/src/content/docs/specs/repository-package-manifest-specification.md Specifies mappings.
docs/src/content/docs/reference/aw-yml-package-manifest.md Documents mapping usage.

Review details

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

Suppressed comments (2)

pkg/cli/add_package_manifest.go:1073

  • Distinct mappings that reuse one source are silently collapsed because deduplication keys only on sourcePath. For example, mapping payload/reviewer.md to both reviewer.md and reviewer-copy.md installs only the first destination, even though these are not duplicate entries. Include the destination in the key so only identical mappings are ignored.
		if _, exists := seen[sourcePath]; exists {
			continue
		}
		seen[sourcePath] = struct{}{}

pkg/cli/add_workflow_resolution.go:579

  • Lstat checks only the final component and follows symlinked parent directories. A source such as payload/workflows/reviewer.md is therefore accepted when payload/workflows is a symlink, including when it points outside the package, violating the local-source containment requirement. Check every path component with Lstat (or compare fully resolved package/source paths) before reading the file.
	info, err := os.Lstat(absolutePath)
  • Files reviewed: 12/12 changed files
  • Comments generated: 5
  • Review effort level: Balanced

Comment on lines 556 to 559
if _, exists := seen[absolutePath]; exists {
continue
}
seen[absolutePath] = struct{}{}
Comment on lines 115 to 117
includeInstallablePaths, _, _ := splitManifestIncludePaths(manifest.Includes)
includeInstallablePaths = append(includeInstallablePaths, manifest.Files...)
includeInstallablePaths = append(includeInstallablePaths, manifestIncludesFromPaths(manifest.Files)...)
installationSources := normalizePackageInstallablePaths(includeInstallablePaths, "")
Comment on lines +55 to +59
if !strings.HasSuffix(strings.ToLower(installable.DestinationPath), ".md") {
continue
}
workflowID := normalizeWorkflowID(filepath.Base(p))
byName[workflowID] = p
workflowID := normalizeWorkflowID(filepath.Base(installable.DestinationPath))
byName[workflowID] = installable.SourcePath
Comment on lines +116 to +118
- `source` or `destination` is empty, absolute, or contains a path-traversal sequence that escapes its root;
- `source` resolves to a symbolic link or to a path outside the package root;
- `source` or `destination` does not end in `.md` or `.yml`, or ends in `.lock.yml`;
Comment on lines +578 to +586
slashed := filepath.ToSlash(p)
if strings.HasPrefix(slashed, "/") || strings.HasPrefix(slashed, "\\") || filepath.IsAbs(p) || isWindowsDriveRelativePath(slashed) {
return "", errors.New("absolute paths are not allowed")
}
cleaned := path.Clean(slashed)
if cleaned == "." || cleaned == ".." || strings.HasPrefix(cleaned, "../") {
return "", errors.New("path traversal outside the root is not allowed")
}
return cleaned, nil

@github-actions github-actions Bot left a comment

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.

Ponytail review: mostly lean, well-tested addition. One duplication spotted.

net: -6 lines possible.

Generated by ✂️ Ponytail Reviewer for #53698 · auto · 74.9 AIC · ⌖ 6.89 AIC · ⊞ 7.3K
Comment /ponytail to run again


// isWindowsDriveRelativePath reports whether p starts with a Windows drive letter prefix
// (e.g. "C:/payload"). filepath.IsAbs does not detect these on non-Windows hosts.
func isWindowsDriveRelativePath(p string) bool {

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.

L591: yagni: isWindowsDriveRelativePath reimplements the same drive-letter check as isWindowsDrivePath in docker_args_validation.go. Reuse/extend that helper instead of a second copy.

@github-actions github-actions Bot left a comment

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.

Skills-Based Review 🧠

Applied /diagnosing-bugs and /tdd — requesting changes on one correctness gap and three test coverage issues.

📋 Key Themes & Highlights

Key Themes

  • Missing validator call in compile path (compile_repository_manifest.go): validateUniqueManifestInstallDestinations is called in the add and update paths but not in gh aw compile, so a manifest with two mapping entries that share a destination compiles cleanly on the distribution side and only fails at consumer install time. This is the highest-impact issue.
  • Test coverage gaps: The duplicate-destination test for .md fires validateUniqueManifestWorkflowFilenames (a pre-existing check) rather than the new validateUniqueManifestInstallDestinations, leaving the new validator un-exercised for that file type. A files+mapping cross-field duplicate scenario is also untested.

Positive Highlights

  • ✅ The resolvedPackageInstallable type is a clean and well-named abstraction that unifies source and destination paths.
  • ✅ The separation between validateUniqueManifestWorkflowFilenames (existing, .md-only, basename-stem keyed) and validateUniqueManifestInstallDestinations (new, full-path keyed) is sound.
  • cleanManifestRelativePath handles Windows drive-letter prefixes on non-Windows hosts — good cross-platform defensive coding.
  • ✅ Error messages consistently include an actionable example with the correct path.
  • ✅ The new test file covers the full validation matrix thoroughly for the happy and rejection paths.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · sonnet46 · 101 AIC · ⌖ 11.5 AIC · ⊞ 7.8K
Comment /matt to run again

installationSources = packageInstallablesFromSourcePaths(scanned)
}

return validateManifestInstallableWorkflowPrivacy(manifestPath, installationSources, func(sourcePath string) ([]byte, error) {

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.

[/diagnosing-bugs] validateUniqueManifestInstallDestinations is never called in the compile path, so duplicate-destination mappings pass validation during gh aw compile even though they are rejected by gh aw add.

💡 Suggested fix

Add the call right after validateUniqueManifestWorkflowFilenames (mirrors the pattern in add_package_manifest.go and add_workflow_resolution.go):

if err := validateUniqueManifestWorkflowFilenames(installationSources, manifestPath); err != nil {
    return err
}
if err := validateUniqueManifestInstallDestinations(installationSources, manifestPath); err != nil {
    return err
}
return validateManifestInstallableWorkflowPrivacy(...)

Without this, a manifest with two mapping entries that share a destination will compile cleanly on the distribution side but fail at install time in the consumer's repository.

@copilot please address this.

}
seen[path] = struct{}{}
normalized = append(normalized, path)
seen[sourcePath] = struct{}{}

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.

[/tdd] The normalizePackageInstallablePaths deduplication uses source path as the key, meaning two entries with different sources but the same destination are both emitted. The subsequent validateUniqueManifestInstallDestinations catches this — but only in the add/update paths. Combined with the missing call in compile_repository_manifest.go, a duplicate-destination manifest distributes successfully.

💡 Why this matters

The dedup-by-source here is intentional (avoid re-fetching the same remote file twice), but it means duplicate-destination detection is entirely delegated to validateUniqueManifestInstallDestinations. Once that validator is also added to the compile path, both protections work together as intended.

Consider adding a test in compile_repository_manifest that exercises a manifest with two mapping entries sharing a destination, to pin the compile-time rejection.

@copilot please address this.

{SourcePath: "factory/payload/workflows/controller.yml", DestinationPath: ".github/workflows/controller.yml"},
})
assert.Equal(t, map[string]string{
"code-reviewer": "factory/payload/workflows/reviewer.md",

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.

[/tdd] The test at line 243 (rejects duplicate markdown destinations) asserts "duplicate workflow filename" — this fires validateUniqueManifestWorkflowFilenames, which runs before validateUniqueManifestInstallDestinations. The test therefore never exercises the new validateUniqueManifestInstallDestinations code path for .md files. A test specifically asserting "both install to" for a .md duplicate would pin the new validator.

💡 Suggested addition

Add a sub-case to invalidCases in TestResolveRepositoryPackage_IncludeMappings:

{
    name: "rejects duplicate md destinations via install destination check",
    includes: `  - source: payload/a/reviewer.md
    destination: .github/workflows/reviewer.md
  - source: payload/b/other.md
    destination: .github/workflows/reviewer.md`,
    contains: "both install to \".github/workflows/reviewer.md\"",
},

Or alternatively, make the existing rejects duplicate markdown destinations sub-test assert the validateUniqueManifestInstallDestinations error message rather than the filename-dedup one, since duplicate destinations are the root concept being tested.

@copilot please address this.

func resolveRepositoryPackageInstallablePaths(ctx context.Context, owner, repo, packagePath, ref, host string, manifest *repositoryPackageManifest, manifestPath string) ([]resolvedPackageInstallable, []string, []string, error) {
includeInstallablePaths, includeSkillDirs, includeAgentFiles := splitManifestIncludePaths(manifest.Includes)
includeInstallablePaths = append(includeInstallablePaths, manifest.Files...)
includeInstallablePaths = append(includeInstallablePaths, manifestIncludesFromPaths(manifest.Files)...)

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.

[/tdd] There is no test covering the case where a files entry and a mapping entry resolve to the same install destination. The files entries are wrapped as string-form includes with an empty Destination (so defaultPackageInstallDestination is used), which could conflict with a mapping entry pointing at the same basename. This cross-field duplicate scenario isn't exercised by the new test file.

💡 Suggested test scenario
name: Factory
files:
  - payload/reviewer.md   # installs to .github/workflows/reviewer.md
includes:
  - source: payload/other/reviewer.md
    destination: .github/workflows/reviewer.md

This should produce a duplicate-destination error. A test verifying this keeps the semantics explicit and prevents regressions when the files/includes merge logic changes.

@copilot please address this.

Documents the architectural decision to extend the `includes` manifest
field with object-form entries that pair a package-relative source path
with a consumer-repository-root-relative destination path.
@github-actions

This comment has been minimized.

@github-actions

Copy link
Copy Markdown
Contributor

🏗️ Design Decision Gate — ADR Required

This PR makes significant changes to core business logic (786 new lines in pkg/) but does not have a linked Architecture Decision Record (ADR).

📄 Draft ADR committed: docs/adr/53698-source-to-destination-mappings-in-includes.md — review and complete it before merging.

🔒 This PR cannot merge until an ADR is linked in the PR body.

📋 What to do next
  1. Review the draft ADR committed to your branch — it was generated from the PR diff
  2. Complete the missing sections — add context the AI couldn't infer, refine the decision rationale, and list real alternatives you considered
  3. Commit the finalized ADR to docs/adr/ on your branch
  4. Reference the ADR in this PR body by adding a line such as:

    ADR: ADR-53698: Source-to-Destination Mappings in aw.yml includes

Once an ADR is linked in the PR body, this gate will re-run and verify the implementation matches the decision.

❓ Why ADRs Matter

"AI made me procrastinate on key design decisions. Because refactoring was cheap, I could always say 'I'll deal with this later.' Deferring decisions corroded my ability to think clearly."

ADRs create a searchable, permanent record of why the codebase looks the way it does. Future contributors (and your future self) will thank you.

📋 Michael Nygard ADR Format Reference

An ADR must contain these four sections to be considered complete:

  • Context — What is the problem? What forces are at play?
  • Decision — What did you decide? Why?
  • Alternatives Considered — What else could have been done?
  • Consequences — What are the trade-offs (positive and negative)?

All ADRs are stored in docs/adr/ as Markdown files numbered by PR number (e.g., 0042-use-postgresql.md for PR #42).

🏗️ ADR gate enforced by Design Decision Gate 🏗️ · sonnet46 · 116.6 AIC · ⌖ 30.3 AIC · ⊞ 9.1K ·
Comment /review to run again

@pelikhan

Copy link
Copy Markdown
Collaborator

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

Copilot AI commented Aug 18, 2026

Copy link
Copy Markdown
Contributor Author

@copilot run pr-finisher skill

fix https://github.com/github/gh-aw/actions/runs/32150579681/job/95794792893?pr=53698

Fixed in 42c1eef: add_package_manifest_mapping_test.go was missing the //go:build !integration tag, so the integration build couldn't see the test helpers (createRepositoryPackageNotFoundError, setupMinimalGitRepo) defined in the other !integration-tagged test files. Added the tag; go build -tags=integration ./... and go test ./pkg/cli/... now pass. The TestWasmGolden_AllEngines failure in that same run is unrelated to this PR (no changes touch pkg/workflow, and the test passes locally).

@github-actions

Copy link
Copy Markdown
Contributor

PR Triage

  • Category: feature
  • Risk: high
  • Priority score: 78/100 (impact 40, urgency 20, quality 18)
  • Recommended action: fast_track

Largest and highest-risk PR in this batch (13 files, 900+ lines) adding source-to-destination mappings for aw.yml includes, with ADR and spec docs. CI passing, 5 reviews already — recommend prioritizing human review given the blast radius on the package manifest system.

Generated by 🔧 PR Triage Agent · auto · 45 AIC · ⌖ 2.09 AIC · ⊞ 8.3K ·

@pelikhan
pelikhan merged commit f37be36 into main Aug 18, 2026
30 checks passed
@pelikhan
pelikhan deleted the copilot/support-source-to-destination-mappings branch August 18, 2026 19:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support source-to-destination mappings for inert nested packages

3 participants