Add a scoped TempDir component #189

Description

@taras

Motivation

Executable Markdown tests need isolated filesystem fixtures without JavaScript
setup. A general resource component should create a temporary working directory
for its content and clean it up through structured concurrency.

Dependency

Depends on #203, which establishes that projected content retains the caller's
lexical bindings while its live resources are owned by the component invocation.
<TempDir> relies on the ordinary component lifecycle from that story. It must
not construct private eval-scope ownership or add a name-specific branch to the
expansion algorithm.

Core component registration and override policy are tracked separately by #202.
This story may use the smallest private mechanism needed to make <TempDir>
automatically available from core.

Authoring contract

<TempDir>
<Content />
</TempDir>
  • <TempDir> is available in regular and testing documents.
  • It creates a unique temporary directory before expanding its content.
  • It applies that directory as contextual Env.cwd for everything expanded
    inside it.
  • Nested components such as <File>, <Glob>, agents, and processes inherit
    that working directory without receiving a path prop.
  • It renders its content normally.
  • When its content finishes, fails, or is cancelled, it restores the previous
    Env.cwd and removes the temporary directory.
  • Nested and sibling <TempDir> instances remain isolated.

Cleanup

Cleanup is unconditional in the initial contract. There is no retain prop and
no automatic retention after failure. A future execution-level inspection
policy may retain scoped resources without changing individual component APIs.

Cleanup participates in structured shutdown and must finish before the
component scope exits. Resources created by projected content stop first under
the component-lifecycle contract established by #203. Cleanup must not use
fire-and-forget filesystem operations.

Testing

Add a colocated TempDir.test.md that verifies the component expands and
renders its child content under xmd test. The first story does not use
JavaScript in the Markdown test.

Add lower-level automated tests that verify:

  • Env.cwd is the created directory while content expands;
  • the previous Env.cwd is restored afterward;
  • sibling and nested temporary directories are distinct;
  • the directory is removed after success;
  • the directory is removed after a child error;
  • the directory is removed after cancellation or halt; and
  • a resource created by projected content stops before the directory is removed,
    relying on the generic lifecycle from Bind projected content resources to the component invocation scope #203 rather than TempDir-specific scope
    management.

The following <File> story adds a Markdown integration test that writes and
reads a relative file inside <TempDir>, proving that filesystem components
inherit its contextual working directory without JavaScript.

Documentation

  • Specify <TempDir> in the Executable Markdown component reference.
  • Add a website example showing isolated filesystem setup.
  • Describe automatic cleanup and the absence of per-component retention.

Acceptance criteria

  • Bind projected content resources to the component invocation scope #203 is complete before this story is implemented.
  • <TempDir> is a core-owned ordinary component, not a special expansion
    directive.
  • A regular document can render content inside <TempDir>.
  • All descendants observe the temporary directory through Env.cwd.
  • Previous working-directory context is restored after the component exits.
  • Projected resources finish before temporary-directory cleanup through the
    shared component lifecycle.
  • Cleanup completes on success, error, and cancellation.
  • Nested and sibling instances do not share directories.
  • The colocated Markdown smoke test passes through xmd test.
  • Runtime lifecycle tests pass on Deno, Node, and Bun where the package test
    matrix applies.
  • Specification and website documentation ship in the same PR.

Not included

  • A retain prop or retain-on-failure behavior.
  • Exposing the generated path as a component prop. The self-closing form
    renders its canonical path and as captures it through the generic capture
    mechanism, so a document can pass the path onward itself.
  • Restricting the component to testing mode.
  • <File> or <Glob> behavior.
  • A public core component registry or general override policy (Register function components and migrate legacy component handlers #202).

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

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all \u003cpre\u003e\u003ccode\u003e blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks"); } } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); } })(); (function(){ try { var __m = "github.com"; var __re = new RegExp('^' + "github\\.com" + '
      Skip to content

      Add a scoped TempDir component #189

      Description

      @taras

      Motivation

      Executable Markdown tests need isolated filesystem fixtures without JavaScript
      setup. A general resource component should create a temporary working directory
      for its content and clean it up through structured concurrency.

      Dependency

      Depends on #203, which establishes that projected content retains the caller's
      lexical bindings while its live resources are owned by the component invocation.
      <TempDir> relies on the ordinary component lifecycle from that story. It must
      not construct private eval-scope ownership or add a name-specific branch to the
      expansion algorithm.

      Core component registration and override policy are tracked separately by #202.
      This story may use the smallest private mechanism needed to make <TempDir>
      automatically available from core.

      Authoring contract

      <TempDir>
      <Content />
      </TempDir>
      • <TempDir> is available in regular and testing documents.
      • It creates a unique temporary directory before expanding its content.
      • It applies that directory as contextual Env.cwd for everything expanded
        inside it.
      • Nested components such as <File>, <Glob>, agents, and processes inherit
        that working directory without receiving a path prop.
      • It renders its content normally.
      • When its content finishes, fails, or is cancelled, it restores the previous
        Env.cwd and removes the temporary directory.
      • Nested and sibling <TempDir> instances remain isolated.

      Cleanup

      Cleanup is unconditional in the initial contract. There is no retain prop and
      no automatic retention after failure. A future execution-level inspection
      policy may retain scoped resources without changing individual component APIs.

      Cleanup participates in structured shutdown and must finish before the
      component scope exits. Resources created by projected content stop first under
      the component-lifecycle contract established by #203. Cleanup must not use
      fire-and-forget filesystem operations.

      Testing

      Add a colocated TempDir.test.md that verifies the component expands and
      renders its child content under xmd test. The first story does not use
      JavaScript in the Markdown test.

      Add lower-level automated tests that verify:

      • Env.cwd is the created directory while content expands;
      • the previous Env.cwd is restored afterward;
      • sibling and nested temporary directories are distinct;
      • the directory is removed after success;
      • the directory is removed after a child error;
      • the directory is removed after cancellation or halt; and
      • a resource created by projected content stops before the directory is removed,
        relying on the generic lifecycle from Bind projected content resources to the component invocation scope #203 rather than TempDir-specific scope
        management.

      The following <File> story adds a Markdown integration test that writes and
      reads a relative file inside <TempDir>, proving that filesystem components
      inherit its contextual working directory without JavaScript.

      Documentation

      • Specify <TempDir> in the Executable Markdown component reference.
      • Add a website example showing isolated filesystem setup.
      • Describe automatic cleanup and the absence of per-component retention.

      Acceptance criteria

      • Bind projected content resources to the component invocation scope #203 is complete before this story is implemented.
      • <TempDir> is a core-owned ordinary component, not a special expansion
        directive.
      • A regular document can render content inside <TempDir>.
      • All descendants observe the temporary directory through Env.cwd.
      • Previous working-directory context is restored after the component exits.
      • Projected resources finish before temporary-directory cleanup through the
        shared component lifecycle.
      • Cleanup completes on success, error, and cancellation.
      • Nested and sibling instances do not share directories.
      • The colocated Markdown smoke test passes through xmd test.
      • Runtime lifecycle tests pass on Deno, Node, and Bun where the package test
        matrix applies.
      • Specification and website documentation ship in the same PR.

      Not included

      • A retain prop or retain-on-failure behavior.
      • Exposing the generated path as a component prop. The self-closing form
        renders its canonical path and as captures it through the generic capture
        mechanism, so a document can pass the path onward itself.
      • Restricting the component to testing mode.
      • <File> or <Glob> behavior.
      • A public core component registry or general override policy (Register function components and migrate legacy component handlers #202).

      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

        No labels
        No labels

        Projects

        No projects

          Milestone

          No milestone

          Relationships

          None yet

          Development

          No branches or pull requests

          Issue actions

          , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
          Skip to content

          Add a scoped TempDir component #189

          Description

          @taras

          Motivation

          Executable Markdown tests need isolated filesystem fixtures without JavaScript
          setup. A general resource component should create a temporary working directory
          for its content and clean it up through structured concurrency.

          Dependency

          Depends on #203, which establishes that projected content retains the caller's
          lexical bindings while its live resources are owned by the component invocation.
          <TempDir> relies on the ordinary component lifecycle from that story. It must
          not construct private eval-scope ownership or add a name-specific branch to the
          expansion algorithm.

          Core component registration and override policy are tracked separately by #202.
          This story may use the smallest private mechanism needed to make <TempDir>
          automatically available from core.

          Authoring contract

          <TempDir>
          <Content />
          </TempDir>
          • <TempDir> is available in regular and testing documents.
          • It creates a unique temporary directory before expanding its content.
          • It applies that directory as contextual Env.cwd for everything expanded
            inside it.
          • Nested components such as <File>, <Glob>, agents, and processes inherit
            that working directory without receiving a path prop.
          • It renders its content normally.
          • When its content finishes, fails, or is cancelled, it restores the previous
            Env.cwd and removes the temporary directory.
          • Nested and sibling <TempDir> instances remain isolated.

          Cleanup

          Cleanup is unconditional in the initial contract. There is no retain prop and
          no automatic retention after failure. A future execution-level inspection
          policy may retain scoped resources without changing individual component APIs.

          Cleanup participates in structured shutdown and must finish before the
          component scope exits. Resources created by projected content stop first under
          the component-lifecycle contract established by #203. Cleanup must not use
          fire-and-forget filesystem operations.

          Testing

          Add a colocated TempDir.test.md that verifies the component expands and
          renders its child content under xmd test. The first story does not use
          JavaScript in the Markdown test.

          Add lower-level automated tests that verify:

          • Env.cwd is the created directory while content expands;
          • the previous Env.cwd is restored afterward;
          • sibling and nested temporary directories are distinct;
          • the directory is removed after success;
          • the directory is removed after a child error;
          • the directory is removed after cancellation or halt; and
          • a resource created by projected content stops before the directory is removed,
            relying on the generic lifecycle from Bind projected content resources to the component invocation scope #203 rather than TempDir-specific scope
            management.

          The following <File> story adds a Markdown integration test that writes and
          reads a relative file inside <TempDir>, proving that filesystem components
          inherit its contextual working directory without JavaScript.

          Documentation

          • Specify <TempDir> in the Executable Markdown component reference.
          • Add a website example showing isolated filesystem setup.
          • Describe automatic cleanup and the absence of per-component retention.

          Acceptance criteria

          • Bind projected content resources to the component invocation scope #203 is complete before this story is implemented.
          • <TempDir> is a core-owned ordinary component, not a special expansion
            directive.
          • A regular document can render content inside <TempDir>.
          • All descendants observe the temporary directory through Env.cwd.
          • Previous working-directory context is restored after the component exits.
          • Projected resources finish before temporary-directory cleanup through the
            shared component lifecycle.
          • Cleanup completes on success, error, and cancellation.
          • Nested and sibling instances do not share directories.
          • The colocated Markdown smoke test passes through xmd test.
          • Runtime lifecycle tests pass on Deno, Node, and Bun where the package test
            matrix applies.
          • Specification and website documentation ship in the same PR.

          Not included

          • A retain prop or retain-on-failure behavior.
          • Exposing the generated path as a component prop. The self-closing form
            renders its canonical path and as captures it through the generic capture
            mechanism, so a document can pass the path onward itself.
          • Restricting the component to testing mode.
          • <File> or <Glob> behavior.
          • A public core component registry or general override policy (Register function components and migrate legacy component handlers #202).

          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

            No labels
            No labels

            Projects

            No projects

              Milestone

              No milestone

              Relationships

              None yet

              Development

              No branches or pull requests

              Issue actions

              , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length \u003e 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
              Skip to content

              Add a scoped TempDir component #189

              Description

              @taras

              Motivation

              Executable Markdown tests need isolated filesystem fixtures without JavaScript
              setup. A general resource component should create a temporary working directory
              for its content and clean it up through structured concurrency.

              Dependency

              Depends on #203, which establishes that projected content retains the caller's
              lexical bindings while its live resources are owned by the component invocation.
              <TempDir> relies on the ordinary component lifecycle from that story. It must
              not construct private eval-scope ownership or add a name-specific branch to the
              expansion algorithm.

              Core component registration and override policy are tracked separately by #202.
              This story may use the smallest private mechanism needed to make <TempDir>
              automatically available from core.

              Authoring contract

              <TempDir>
              <Content />
              </TempDir>
              • <TempDir> is available in regular and testing documents.
              • It creates a unique temporary directory before expanding its content.
              • It applies that directory as contextual Env.cwd for everything expanded
                inside it.
              • Nested components such as <File>, <Glob>, agents, and processes inherit
                that working directory without receiving a path prop.
              • It renders its content normally.
              • When its content finishes, fails, or is cancelled, it restores the previous
                Env.cwd and removes the temporary directory.
              • Nested and sibling <TempDir> instances remain isolated.

              Cleanup

              Cleanup is unconditional in the initial contract. There is no retain prop and
              no automatic retention after failure. A future execution-level inspection
              policy may retain scoped resources without changing individual component APIs.

              Cleanup participates in structured shutdown and must finish before the
              component scope exits. Resources created by projected content stop first under
              the component-lifecycle contract established by #203. Cleanup must not use
              fire-and-forget filesystem operations.

              Testing

              Add a colocated TempDir.test.md that verifies the component expands and
              renders its child content under xmd test. The first story does not use
              JavaScript in the Markdown test.

              Add lower-level automated tests that verify:

              • Env.cwd is the created directory while content expands;
              • the previous Env.cwd is restored afterward;
              • sibling and nested temporary directories are distinct;
              • the directory is removed after success;
              • the directory is removed after a child error;
              • the directory is removed after cancellation or halt; and
              • a resource created by projected content stops before the directory is removed,
                relying on the generic lifecycle from Bind projected content resources to the component invocation scope #203 rather than TempDir-specific scope
                management.

              The following <File> story adds a Markdown integration test that writes and
              reads a relative file inside <TempDir>, proving that filesystem components
              inherit its contextual working directory without JavaScript.

              Documentation

              • Specify <TempDir> in the Executable Markdown component reference.
              • Add a website example showing isolated filesystem setup.
              • Describe automatic cleanup and the absence of per-component retention.

              Acceptance criteria

              • Bind projected content resources to the component invocation scope #203 is complete before this story is implemented.
              • <TempDir> is a core-owned ordinary component, not a special expansion
                directive.
              • A regular document can render content inside <TempDir>.
              • All descendants observe the temporary directory through Env.cwd.
              • Previous working-directory context is restored after the component exits.
              • Projected resources finish before temporary-directory cleanup through the
                shared component lifecycle.
              • Cleanup completes on success, error, and cancellation.
              • Nested and sibling instances do not share directories.
              • The colocated Markdown smoke test passes through xmd test.
              • Runtime lifecycle tests pass on Deno, Node, and Bun where the package test
                matrix applies.
              • Specification and website documentation ship in the same PR.

              Not included

              • A retain prop or retain-on-failure behavior.
              • Exposing the generated path as a component prop. The self-closing form
                renders its canonical path and as captures it through the generic capture
                mechanism, so a document can pass the path onward itself.
              • Restricting the component to testing mode.
              • <File> or <Glob> behavior.
              • A public core component registry or general override policy (Register function components and migrate legacy component handlers #202).

              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

                No labels
                No labels

                Projects

                No projects

                  Milestone

                  No milestone

                  Relationships

                  None yet

                  Development

                  No branches or pull requests

                  Issue actions

                  , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
                  Skip to content

                  Add a scoped TempDir component #189

                  Description

                  @taras

                  Motivation

                  Executable Markdown tests need isolated filesystem fixtures without JavaScript
                  setup. A general resource component should create a temporary working directory
                  for its content and clean it up through structured concurrency.

                  Dependency

                  Depends on #203, which establishes that projected content retains the caller's
                  lexical bindings while its live resources are owned by the component invocation.
                  <TempDir> relies on the ordinary component lifecycle from that story. It must
                  not construct private eval-scope ownership or add a name-specific branch to the
                  expansion algorithm.

                  Core component registration and override policy are tracked separately by #202.
                  This story may use the smallest private mechanism needed to make <TempDir>
                  automatically available from core.

                  Authoring contract

                  <TempDir>
                  <Content />
                  </TempDir>
                  • <TempDir> is available in regular and testing documents.
                  • It creates a unique temporary directory before expanding its content.
                  • It applies that directory as contextual Env.cwd for everything expanded
                    inside it.
                  • Nested components such as <File>, <Glob>, agents, and processes inherit
                    that working directory without receiving a path prop.
                  • It renders its content normally.
                  • When its content finishes, fails, or is cancelled, it restores the previous
                    Env.cwd and removes the temporary directory.
                  • Nested and sibling <TempDir> instances remain isolated.

                  Cleanup

                  Cleanup is unconditional in the initial contract. There is no retain prop and
                  no automatic retention after failure. A future execution-level inspection
                  policy may retain scoped resources without changing individual component APIs.

                  Cleanup participates in structured shutdown and must finish before the
                  component scope exits. Resources created by projected content stop first under
                  the component-lifecycle contract established by #203. Cleanup must not use
                  fire-and-forget filesystem operations.

                  Testing

                  Add a colocated TempDir.test.md that verifies the component expands and
                  renders its child content under xmd test. The first story does not use
                  JavaScript in the Markdown test.

                  Add lower-level automated tests that verify:

                  • Env.cwd is the created directory while content expands;
                  • the previous Env.cwd is restored afterward;
                  • sibling and nested temporary directories are distinct;
                  • the directory is removed after success;
                  • the directory is removed after a child error;
                  • the directory is removed after cancellation or halt; and
                  • a resource created by projected content stops before the directory is removed,
                    relying on the generic lifecycle from Bind projected content resources to the component invocation scope #203 rather than TempDir-specific scope
                    management.

                  The following <File> story adds a Markdown integration test that writes and
                  reads a relative file inside <TempDir>, proving that filesystem components
                  inherit its contextual working directory without JavaScript.

                  Documentation

                  • Specify <TempDir> in the Executable Markdown component reference.
                  • Add a website example showing isolated filesystem setup.
                  • Describe automatic cleanup and the absence of per-component retention.

                  Acceptance criteria

                  • Bind projected content resources to the component invocation scope #203 is complete before this story is implemented.
                  • <TempDir> is a core-owned ordinary component, not a special expansion
                    directive.
                  • A regular document can render content inside <TempDir>.
                  • All descendants observe the temporary directory through Env.cwd.
                  • Previous working-directory context is restored after the component exits.
                  • Projected resources finish before temporary-directory cleanup through the
                    shared component lifecycle.
                  • Cleanup completes on success, error, and cancellation.
                  • Nested and sibling instances do not share directories.
                  • The colocated Markdown smoke test passes through xmd test.
                  • Runtime lifecycle tests pass on Deno, Node, and Bun where the package test
                    matrix applies.
                  • Specification and website documentation ship in the same PR.

                  Not included

                  • A retain prop or retain-on-failure behavior.
                  • Exposing the generated path as a component prop. The self-closing form
                    renders its canonical path and as captures it through the generic capture
                    mechanism, so a document can pass the path onward itself.
                  • Restricting the component to testing mode.
                  • <File> or <Glob> behavior.
                  • A public core component registry or general override policy (Register function components and migrate legacy component handlers #202).

                  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

                    No labels
                    No labels

                    Projects

                    No projects

                      Milestone

                      No milestone

                      Relationships

                      None yet

                      Development

                      No branches or pull requests

                      Issue actions

                      , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
                      Skip to content

                      Add a scoped TempDir component #189

                      Description

                      @taras

                      Motivation

                      Executable Markdown tests need isolated filesystem fixtures without JavaScript
                      setup. A general resource component should create a temporary working directory
                      for its content and clean it up through structured concurrency.

                      Dependency

                      Depends on #203, which establishes that projected content retains the caller's
                      lexical bindings while its live resources are owned by the component invocation.
                      <TempDir> relies on the ordinary component lifecycle from that story. It must
                      not construct private eval-scope ownership or add a name-specific branch to the
                      expansion algorithm.

                      Core component registration and override policy are tracked separately by #202.
                      This story may use the smallest private mechanism needed to make <TempDir>
                      automatically available from core.

                      Authoring contract

                      <TempDir>
                      <Content />
                      </TempDir>
                      • <TempDir> is available in regular and testing documents.
                      • It creates a unique temporary directory before expanding its content.
                      • It applies that directory as contextual Env.cwd for everything expanded
                        inside it.
                      • Nested components such as <File>, <Glob>, agents, and processes inherit
                        that working directory without receiving a path prop.
                      • It renders its content normally.
                      • When its content finishes, fails, or is cancelled, it restores the previous
                        Env.cwd and removes the temporary directory.
                      • Nested and sibling <TempDir> instances remain isolated.

                      Cleanup

                      Cleanup is unconditional in the initial contract. There is no retain prop and
                      no automatic retention after failure. A future execution-level inspection
                      policy may retain scoped resources without changing individual component APIs.

                      Cleanup participates in structured shutdown and must finish before the
                      component scope exits. Resources created by projected content stop first under
                      the component-lifecycle contract established by #203. Cleanup must not use
                      fire-and-forget filesystem operations.

                      Testing

                      Add a colocated TempDir.test.md that verifies the component expands and
                      renders its child content under xmd test. The first story does not use
                      JavaScript in the Markdown test.

                      Add lower-level automated tests that verify:

                      • Env.cwd is the created directory while content expands;
                      • the previous Env.cwd is restored afterward;
                      • sibling and nested temporary directories are distinct;
                      • the directory is removed after success;
                      • the directory is removed after a child error;
                      • the directory is removed after cancellation or halt; and
                      • a resource created by projected content stops before the directory is removed,
                        relying on the generic lifecycle from Bind projected content resources to the component invocation scope #203 rather than TempDir-specific scope
                        management.

                      The following <File> story adds a Markdown integration test that writes and
                      reads a relative file inside <TempDir>, proving that filesystem components
                      inherit its contextual working directory without JavaScript.

                      Documentation

                      • Specify <TempDir> in the Executable Markdown component reference.
                      • Add a website example showing isolated filesystem setup.
                      • Describe automatic cleanup and the absence of per-component retention.

                      Acceptance criteria

                      • Bind projected content resources to the component invocation scope #203 is complete before this story is implemented.
                      • <TempDir> is a core-owned ordinary component, not a special expansion
                        directive.
                      • A regular document can render content inside <TempDir>.
                      • All descendants observe the temporary directory through Env.cwd.
                      • Previous working-directory context is restored after the component exits.
                      • Projected resources finish before temporary-directory cleanup through the
                        shared component lifecycle.
                      • Cleanup completes on success, error, and cancellation.
                      • Nested and sibling instances do not share directories.
                      • The colocated Markdown smoke test passes through xmd test.
                      • Runtime lifecycle tests pass on Deno, Node, and Bun where the package test
                        matrix applies.
                      • Specification and website documentation ship in the same PR.

                      Not included

                      • A retain prop or retain-on-failure behavior.
                      • Exposing the generated path as a component prop. The self-closing form
                        renders its canonical path and as captures it through the generic capture
                        mechanism, so a document can pass the path onward itself.
                      • Restricting the component to testing mode.
                      • <File> or <Glob> behavior.
                      • A public core component registry or general override policy (Register function components and migrate legacy component handlers #202).

                      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

                        No labels
                        No labels

                        Projects

                        No projects

                          Milestone

                          No milestone

                          Relationships

                          None yet

                          Development

                          No branches or pull requests

                          Issue actions

                          , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
                          Skip to content

                          Add a scoped TempDir component #189

                          Description

                          @taras

                          Motivation

                          Executable Markdown tests need isolated filesystem fixtures without JavaScript
                          setup. A general resource component should create a temporary working directory
                          for its content and clean it up through structured concurrency.

                          Dependency

                          Depends on #203, which establishes that projected content retains the caller's
                          lexical bindings while its live resources are owned by the component invocation.
                          <TempDir> relies on the ordinary component lifecycle from that story. It must
                          not construct private eval-scope ownership or add a name-specific branch to the
                          expansion algorithm.

                          Core component registration and override policy are tracked separately by #202.
                          This story may use the smallest private mechanism needed to make <TempDir>
                          automatically available from core.

                          Authoring contract

                          <TempDir>
                          <Content />
                          </TempDir>
                          • <TempDir> is available in regular and testing documents.
                          • It creates a unique temporary directory before expanding its content.
                          • It applies that directory as contextual Env.cwd for everything expanded
                            inside it.
                          • Nested components such as <File>, <Glob>, agents, and processes inherit
                            that working directory without receiving a path prop.
                          • It renders its content normally.
                          • When its content finishes, fails, or is cancelled, it restores the previous
                            Env.cwd and removes the temporary directory.
                          • Nested and sibling <TempDir> instances remain isolated.

                          Cleanup

                          Cleanup is unconditional in the initial contract. There is no retain prop and
                          no automatic retention after failure. A future execution-level inspection
                          policy may retain scoped resources without changing individual component APIs.

                          Cleanup participates in structured shutdown and must finish before the
                          component scope exits. Resources created by projected content stop first under
                          the component-lifecycle contract established by #203. Cleanup must not use
                          fire-and-forget filesystem operations.

                          Testing

                          Add a colocated TempDir.test.md that verifies the component expands and
                          renders its child content under xmd test. The first story does not use
                          JavaScript in the Markdown test.

                          Add lower-level automated tests that verify:

                          • Env.cwd is the created directory while content expands;
                          • the previous Env.cwd is restored afterward;
                          • sibling and nested temporary directories are distinct;
                          • the directory is removed after success;
                          • the directory is removed after a child error;
                          • the directory is removed after cancellation or halt; and
                          • a resource created by projected content stops before the directory is removed,
                            relying on the generic lifecycle from Bind projected content resources to the component invocation scope #203 rather than TempDir-specific scope
                            management.

                          The following <File> story adds a Markdown integration test that writes and
                          reads a relative file inside <TempDir>, proving that filesystem components
                          inherit its contextual working directory without JavaScript.

                          Documentation

                          • Specify <TempDir> in the Executable Markdown component reference.
                          • Add a website example showing isolated filesystem setup.
                          • Describe automatic cleanup and the absence of per-component retention.

                          Acceptance criteria

                          • Bind projected content resources to the component invocation scope #203 is complete before this story is implemented.
                          • <TempDir> is a core-owned ordinary component, not a special expansion
                            directive.
                          • A regular document can render content inside <TempDir>.
                          • All descendants observe the temporary directory through Env.cwd.
                          • Previous working-directory context is restored after the component exits.
                          • Projected resources finish before temporary-directory cleanup through the
                            shared component lifecycle.
                          • Cleanup completes on success, error, and cancellation.
                          • Nested and sibling instances do not share directories.
                          • The colocated Markdown smoke test passes through xmd test.
                          • Runtime lifecycle tests pass on Deno, Node, and Bun where the package test
                            matrix applies.
                          • Specification and website documentation ship in the same PR.

                          Not included

                          • A retain prop or retain-on-failure behavior.
                          • Exposing the generated path as a component prop. The self-closing form
                            renders its canonical path and as captures it through the generic capture
                            mechanism, so a document can pass the path onward itself.
                          • Restricting the component to testing mode.
                          • <File> or <Glob> behavior.
                          • A public core component registry or general override policy (Register function components and migrate legacy component handlers #202).

                          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

                            No labels
                            No labels

                            Projects

                            No projects

                              Milestone

                              No milestone

                              Relationships

                              None yet

                              Development

                              No branches or pull requests

                              Issue actions

                              , 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
                              Skip to content

                              Add a scoped TempDir component #189

                              Description

                              @taras

                              Motivation

                              Executable Markdown tests need isolated filesystem fixtures without JavaScript
                              setup. A general resource component should create a temporary working directory
                              for its content and clean it up through structured concurrency.

                              Dependency

                              Depends on #203, which establishes that projected content retains the caller's
                              lexical bindings while its live resources are owned by the component invocation.
                              <TempDir> relies on the ordinary component lifecycle from that story. It must
                              not construct private eval-scope ownership or add a name-specific branch to the
                              expansion algorithm.

                              Core component registration and override policy are tracked separately by #202.
                              This story may use the smallest private mechanism needed to make <TempDir>
                              automatically available from core.

                              Authoring contract

                              <TempDir>
                              <Content />
                              </TempDir>
                              • <TempDir> is available in regular and testing documents.
                              • It creates a unique temporary directory before expanding its content.
                              • It applies that directory as contextual Env.cwd for everything expanded
                                inside it.
                              • Nested components such as <File>, <Glob>, agents, and processes inherit
                                that working directory without receiving a path prop.
                              • It renders its content normally.
                              • When its content finishes, fails, or is cancelled, it restores the previous
                                Env.cwd and removes the temporary directory.
                              • Nested and sibling <TempDir> instances remain isolated.

                              Cleanup

                              Cleanup is unconditional in the initial contract. There is no retain prop and
                              no automatic retention after failure. A future execution-level inspection
                              policy may retain scoped resources without changing individual component APIs.

                              Cleanup participates in structured shutdown and must finish before the
                              component scope exits. Resources created by projected content stop first under
                              the component-lifecycle contract established by #203. Cleanup must not use
                              fire-and-forget filesystem operations.

                              Testing

                              Add a colocated TempDir.test.md that verifies the component expands and
                              renders its child content under xmd test. The first story does not use
                              JavaScript in the Markdown test.

                              Add lower-level automated tests that verify:

                              • Env.cwd is the created directory while content expands;
                              • the previous Env.cwd is restored afterward;
                              • sibling and nested temporary directories are distinct;
                              • the directory is removed after success;
                              • the directory is removed after a child error;
                              • the directory is removed after cancellation or halt; and
                              • a resource created by projected content stops before the directory is removed,
                                relying on the generic lifecycle from Bind projected content resources to the component invocation scope #203 rather than TempDir-specific scope
                                management.

                              The following <File> story adds a Markdown integration test that writes and
                              reads a relative file inside <TempDir>, proving that filesystem components
                              inherit its contextual working directory without JavaScript.

                              Documentation

                              • Specify <TempDir> in the Executable Markdown component reference.
                              • Add a website example showing isolated filesystem setup.
                              • Describe automatic cleanup and the absence of per-component retention.

                              Acceptance criteria

                              • Bind projected content resources to the component invocation scope #203 is complete before this story is implemented.
                              • <TempDir> is a core-owned ordinary component, not a special expansion
                                directive.
                              • A regular document can render content inside <TempDir>.
                              • All descendants observe the temporary directory through Env.cwd.
                              • Previous working-directory context is restored after the component exits.
                              • Projected resources finish before temporary-directory cleanup through the
                                shared component lifecycle.
                              • Cleanup completes on success, error, and cancellation.
                              • Nested and sibling instances do not share directories.
                              • The colocated Markdown smoke test passes through xmd test.
                              • Runtime lifecycle tests pass on Deno, Node, and Bun where the package test
                                matrix applies.
                              • Specification and website documentation ship in the same PR.

                              Not included

                              • A retain prop or retain-on-failure behavior.
                              • Exposing the generated path as a component prop. The self-closing form
                                renders its canonical path and as captures it through the generic capture
                                mechanism, so a document can pass the path onward itself.
                              • Restricting the component to testing mode.
                              • <File> or <Glob> behavior.
                              • A public core component registry or general override policy (Register function components and migrate legacy component handlers #202).

                              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

                                No labels
                                No labels

                                Projects

                                No projects

                                  Milestone

                                  No milestone

                                  Relationships

                                  None yet

                                  Development

                                  No branches or pull requests

                                  Issue actions