Skip to content

Preserve <Dir> working directory through <Content /> #985

Closed

Description

@taras

Story

A Markdown component can select a working directory for the caller content it
projects. For example, a reusable repository or workspace wrapper puts
<Content /> inside <Dir> so the caller's commands run there:

Create components/InDirectory.md:

---
props:
  type: object
  properties:
    path: {type: string}
  required: [path]
---

<Dir path={props.path}>
  <Content />
</Dir>
<InDirectory path="target">
```bash exec
pwd -P
```
</InDirectory>

The shell command runs in target, and the surrounding document resumes in its
original directory. The projected content still has access to the caller's
bindings.

Current gap

The pattern executes, but the projected command sees the caller's original cwd
instead of the directory installed around <Content />. A direct <Dir>
containing the same command changes cwd and restores it correctly.

This is a bug, not an intended consequence of preserving caller bindings. The
local workflow harness currently works around it by placing Dir and the nested
Execution together in an execution-owning helper.

Acceptance

  • The wrapper above applies its selected directory to projected commands and
    other operations that consume the contextual working directory.
  • Caller binding lookup remains correct while that directory applies.
  • A direct Dir control and the wrapper choose the same directory for the same
    path. Leaving the wrapper restores the enclosing directory; existing failure
    and cancellation restoration behavior remains intact.
  • The regression does not require moving the caller's commands into the
    component definition or supplying a different component API.
  • Preserve content-scope lifetime, invocation/source ownership, existing
    permissions and completed-operation replay. Fixing cwd propagation does not
    justify broad copying of arbitrary caller or component service state.

Reproduction and evidence

Confirmed on the unchanged PR983 candidate
09c06f1a98d9282c86a538be1ca4c74812a4da1f using its prepared source CLI:

deno run --allow-all --frozen --cached-only --node-modules-dir=manual \
  --config /Users/tarasmankovski/.codex/worktrees/xmd-sidekick-components-896/executable.md/deno.json \
  /Users/tarasmankovski/.codex/worktrees/xmd-sidekick-components-896/executable.md/packages/cli/src/deno.ts \
  test /private/tmp/xmd-dir-content-projection-evidence/reproduce.test.md \
  --include /private/tmp/xmd-dir-content-projection-evidence/components

The two focused tests report one passed, one failed, exit 1. The direct Dir
control passes its change/restoration assertions. The wrapper's observed cwd is
/private/tmp/xmd-dir-content-projection-evidence; the expected cwd is the
invocation's temporary target directory. No provider call or product source
edit is involved.

The complete reproduction, Wrapper.md and first output are preserved in
/private/tmp/xmd-dir-content-projection-evidence/, including
current-delivery-first.log. Add the focused regression alongside the existing
Dir/content cases in packages/core/tests/expand.test.ts; run that file for
implementation feedback and retain applicable content/ownership regressions.

Related closed issue #328 fixed nested Content substitution. This report differs:
the projected content executes, but loses the enclosing Dir's cwd. No cause or
regression-introduction commit has been established.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions