Skip to content

[FEATURE]: workspace folders — explicit multi-directory support #19515

Closed as not planned

Description

@msangals

Feature hasn't been suggested before.

  • I have verified this feature I'm about to request hasn't been suggested before.

Note: #1543 requests the same concept. This issue adds a concrete implementation proposal and references the broader set of related symlink issues.

Describe the enhancement you want to request

When working across multiple projects (e.g., a frontend and backend in separate repos, or a shared library), OpenCode can only see files in the directory it was launched from. Files in other directories aren't indexed for @ file search, and reading/writing them triggers permission prompts every time.

This is a common workflow. VS Code and Cursor solve it with "Add Folder to Workspace", which lets you bring additional directories into your current session. OpenCode doesn't have an equivalent.

Related issues:

Multiple PRs (#10366, #11351, #12992, #18291) have tried fixing symlink following, but none have landed. PR #18291 showed that global --follow causes Windows CI timeout due to junction loops. The symlink approach is fundamentally fragile.

Proposed solution: add a workspace field to opencode.jsonc:

{
  "workspace": ["../backend", "~/src/shared-lib"]
}

Directories listed here would be:

  • Indexed for @ file search (visible in fuzzy picker)
  • Accessible without external directory permission prompts
  • Watched for file changes

They would not affect snapshots, git operations, project identity, or the existing desktop "workspace" feature (git worktrees). Workspace folders are independent trusted directories that don't participate in branching or undo/redo.

Why this approach:

  • Explicit over implicit: no surprise expansion from symlinks or junctions
  • Cross-platform: works on Windows, macOS, Linux without junction/symlink issues
  • Small surface area: the main change is extending Instance.containsPath() and File.scan() (~50 lines)
  • Familiar pattern: similar to Cursor/VS Code's workspace folders concept

Longer term, workspace folders could be managed directly through the UI (desktop, web, TUI), e.g. an "Add Folder" action that updates the config without manual editing.

Happy to implement this if the approach sounds reasonable.

Activity

  1. added
    coreAnything pertaining to core functionality of the application (opencode server stuff)
    needs:complianceThis means the issue will auto-close after 2 hours.
    on Mar 28, 2026
  2. changed the title [-]feat: workspace folders — explicit multi-directory support[/-] [+][FEATURE]: workspace folders — explicit multi-directory support[/+] on Mar 28, 2026
  3. github-actions commented on Mar 28, 2026

    @github-actions
    Contributor

    Thanks for updating the issue! It now meets our contributing guidelines. We appreciate you taking the time to improve the submission.

  4. jeroenev commented on Apr 2, 2026

    @jeroenev

    Looks good, I had a PR that makes following Symlinks opt-in, which means you can just symlink the required folders in your project and start working
    but this way also makes a lot of sense

  5. paul-vd commented on Apr 23, 2026

    @paul-vd

    Use case: umbrella coordination repo with 15+ nested git repos

    We use a coordination repo for cross-repo planning (OpenSpec artifacts, specs, tasks) with 15 independent product repos cloned into a gitignored projects/ directory. Agent sessions routinely span the umbrella and 2-3 project repos in a single session.

    File search is already solved, we work around the indexing limitation by adding !projects/* to a .ignore file (docs), which makes ripgrep include project files for @ search. This works well.

    The remaining gap is git diff visibility. When the agent edits files inside projects/acme-backend/, OpenCode Desktop's diff panel shows nothing, because OpenCode resolves the git root by walking up from cwd to the nearest .git, and never scans for nested git repositories within the workspace. Each project has its own .git that OpenCode doesn't detect.

    This means:

    • No diff review for agent changes in nested repos
    • No change tracking across multi-repo sessions
    • No visibility into uncommitted work across projects

    Request: When workspace folders land, they should also register additional git roots for the diff panel, not just file indexing and permission scoping. VS Code handles this via git.autoRepositoryDetection, which scans for nested .git directories and adds each as a separate Source Control provider.

    For the workspace folders feature, git awareness would mean:

    • Detecting .git in each workspace folder (or its children)
    • Showing each as a separate diff provider in the Desktop diff panel
    • Aggregated change indicators (e.g., "acme-backend: 3 changes, acme-notifications: 1 change")

    This is currently the biggest workflow friction for multi-repo development in OpenCode Desktop. File search and permissions are solvable with .ignore, diff blindness is not.

  6. assigned and unassigned on Apr 26, 2026
  7. removed
    coreAnything pertaining to core functionality of the application (opencode server stuff)
    on May 3, 2026
  8. msangals commented on May 27, 2026

    @msangals
    Author

    Hey @kitlangton, I saw this issue is assigned to you, so I wanted to check in directly.

    There seems to be strong interest in solving this properly: this issue already has 31 👍 reactions, #1543 has 131 👍, and there are several related issues/PRs around symlinks and multi-directory workflows that never quite landed.

    I’d really appreciate your view on whether this is aligned with how you’d like to see this solved. If the direction makes sense, I’m happy to discuss this further.

  9. oeholmen commented on Jun 3, 2026

    @oeholmen

    One major use case is having an api in one repo, and multiple front ends consuming the api. It is very useful to be able to work across API+affected front ends for a single, focused change.

  10. treddington4 commented on Jul 17, 2026

    @treddington4

    Use case: Yocto/OpenBMC multi-repo workspaces

    I work on embedded firmware with Yocto/OpenBMC. A dev workspace has 5–15 independent git repos that are all related but don't share a common git root:

    workspace/
      src/
        openbmc/              ← upstream distro
        meta-vendor/          ← BSP layer (recipes, machine configs)
        linux/                ← kernel, pulled in via devtool modify
        u-boot/               ← bootloader, same
        validation-suite/     ← hardware test framework
        kernel-modules/       ← out-of-tree drivers
      .opencode/              ← workspace-level skills, agents, commands
      scripts/                ← provisioning, dep loading
      debugging/              ← per-ticket logs, traces, artifacts
    

    Repos get pulled in through devtool modify, provisioning scripts, or just cloning. Most are git worktrees off a central clone. The workspace root is not a git repo — it's just the directory that ties everything together, with its own config and scripts.

    Fixing a bug or adding a feature usually touches 3–4 of these repos at once. A new sensor means changes in the meta-layer recipe, the kernel driver, the userspace daemon, and the test suite. Splitting that across separate OpenCode sessions kills the context that makes the agent useful in the first place.

    What works fine: the agent can read/write files everywhere, and I can have it run git diff or git status inside any sub-repo via bash.

    What's broken: the Changes panel in the TUI and desktop app is completely empty. OpenCode walks up from cwd looking for a .git, doesn't find one, and disables all git integration. No diff view, no change tracking, no undo/snapshots across the workspace.

    I dug into the source to understand the scope:

    • packages/core/src/git.ts — discover() finds one .git by walking upward. Returns one repo or nothing.
    • packages/opencode/src/project/project.ts — calls discover, sets git mode on or off for the whole session.
    • packages/opencode/src/project/vcs.ts — every diff/status operation checks ctx.project.vcs !== "git" and bails if it's not set. All operations target a single directory.
    • The HTTP API just delegates to the above. The TUI/desktop renders whatever the API returns.

    So the change is pretty contained. A discoverAll() that scans workspace folder children for .git entries, plus making the diff/status functions iterate over multiple repos with path prefixes, would cover it. The UI doesn't need to change — it already renders a list of file diffs.

    This lines up with @paul-vd's comment. The "workspace" config proposed here is the right hook — it just needs to also register git roots for the diff panel, not only file indexing and permissions.

    I put together a minimal patch that adds child-repo discovery to the existing git integration. It's working for us — the Changes panel now shows diffs from all nested repos when the workspace root has no .git of its own.

    Two files touched:

    • packages/core/src/project.ts — when discover() finds no .git at the root, scans immediate children and one level deeper for child repos. If any are found, sets vcs: "git" so the rest of the pipeline doesn't bail out.
    • packages/opencode/src/project/vcs.ts — status(), diff(), and diffRaw() now also scan for child repos and aggregate their results with path prefixes. Existing single-repo behavior is untouched — the child-repo scan runs in addition to, not instead of, the root repo path.

    No changes to types, schemas, snapshots, undo, or the UI. Tested against a workspace with 9 independent git worktrees under src/.

    Not proposing this as a PR — just sharing what's working for us in case it's useful as a reference for whoever picks this up. Aware that #24589 is a full multi-root implementation.

    git format-patch (2 files, +257 -42) — apply with git am
    From cf8025fc35d78b42d3539f42412ac03664ca640e Mon Sep 17 00:00:00 2001
    From: Tom Reddington <[email protected]>
    Date: Fri, 17 Jul 2026 13:00:55 +0000
    Subject: [PATCH] feat(core): discover child git repos in multi-repo workspaces
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    
    When the workspace root has no .git, scan immediate children and one
    level deeper for independent git repos. Aggregate their status and
    diff output in the Changes panel with path prefixes.
    
    Single-repo workspaces are unaffected — child discovery runs in
    addition to, not instead of, the existing root repo path.
    
    Ref: https://github.com/anomalyco/opencode/issues/19515
    ---
     packages/core/src/project.ts         |  37 +++-
     packages/opencode/src/project/vcs.ts | 262 ++++++++++++++++++++++-----
     2 files changed, 257 insertions(+), 42 deletions(-)
    
    diff --git a/packages/core/src/project.ts b/packages/core/src/project.ts
    index 49e054d..c891a58 100644
    --- a/packages/core/src/project.ts
    +++ b/packages/core/src/project.ts
    @@ -1,6 +1,7 @@
     export * as ProjectV2 from "./project"
     export * as Project from "./project"
     
    +import { readdirSync, existsSync, statSync } from "fs"
     import { Context, Effect, Layer, Schema } from "effect"
     import path from "path"
     import { AbsolutePath } from "./schema"
    @@ -107,9 +108,43 @@ const layer = Layer.effect(
           return root ? ID.make(root) : undefined
         })
     
    +    // Scan for child git repos in a non-git workspace root.
    +    // Checks immediate children and one level deeper (e.g. src/*/).
    +    function scanForChildGit(rootDir: string): boolean {
    +      const IGNORE = new Set(["node_modules", "__pycache__", "build", "dist", "tmp", "temp", "downloads", "deploy"])
    +      const checkDir = (dir: string) => {
    +        try {
    +          for (const entry of readdirSync(dir, { withFileTypes: true })) {
    +            if (entry.name.startsWith(".") || IGNORE.has(entry.name)) continue
    +            if (existsSync(path.join(dir, entry.name, ".git"))) return true
    +          }
    +        } catch { /* permission errors */ }
    +        return false
    +      }
    +      if (checkDir(rootDir)) return true
    +      try {
    +        for (const entry of readdirSync(rootDir, { withFileTypes: true })) {
    +          if (entry.name.startsWith(".") || IGNORE.has(entry.name)) continue
    +          const full = path.join(rootDir, entry.name)
    +          try {
    +            if (statSync(full).isDirectory() && checkDir(full)) return true
    +          } catch { /* skip */ }
    +        }
    +      } catch { /* skip */ }
    +      return false
    +    }
    +
         const resolve = Effect.fn("Project.resolve")(function* (input: AbsolutePath) {
           const repo = yield* git.repo.discover(input)
    -      if (!repo) return { id: ID.global, directory: AbsolutePath.make(path.parse(input).root), vcs: undefined }
    +      if (!repo) {
    +        // No git repo at the root. Check if child directories contain git repos.
    +        // If so, treat this as a multi-repo workspace with synthetic git mode.
    +        const hasChildRepos = scanForChildGit(input)
    +        if (hasChildRepos) {
    +          return { id: ID.global, directory: AbsolutePath.make(input), vcs: { type: "git" as const, store: AbsolutePath.make(input) } }
    +        }
    +        return { id: ID.global, directory: AbsolutePath.make(path.parse(input).root), vcs: undefined }
    +      }
     
           const previous = yield* cached(repo.commonDirectory)
           const id = (yield* remote(repo)) ?? previous ?? (yield* root(repo))
    diff --git a/packages/opencode/src/project/vcs.ts b/packages/opencode/src/project/vcs.ts
    index eca56c0..62bdee1 100644
    --- a/packages/opencode/src/project/vcs.ts
    +++ b/packages/opencode/src/project/vcs.ts
    @@ -7,6 +7,8 @@ import { Git } from "@/git"
     import { EventV2Bridge } from "@/event-v2-bridge"
     import { EventV2 } from "@opencode-ai/core/event"
     import { VcsEvent } from "@opencode-ai/schema/vcs-event"
    +import { readdirSync, statSync, existsSync } from "fs"
    +import path from "path"
     
     const PATCH_CONTEXT_LINES = 2_147_483_647
     const MAX_PATCH_BYTES = 10_000_000
    @@ -232,6 +234,150 @@ const track = Effect.fnUntraced(function* (
       return yield* diffAgainstRef(git, cwd, ref, options)
     })
     
    +// --- Multi-repo support for non-git workspace roots ---
    +
    +interface ChildRepo {
    +  readonly dir: string      // absolute path to the repo worktree
    +  readonly prefix: string   // relative path from workspace root (e.g. "src/openbmc")
    +}
    +
    +// Cached per workspace root so we only scan once per session.
    +const childRepoCache = new Map<string, ChildRepo[]>()
    +
    +function discoverChildRepos(rootDir: string): ChildRepo[] {
    +  const cached = childRepoCache.get(rootDir)
    +  if (cached) return cached
    +
    +  // Directories to skip when scanning for child repos
    +  const SCAN_IGNORE = new Set([
    +    "node_modules",
    +    "__pycache__",
    +    "build",
    +    "dist",
    +    "tmp",
    +    "temp",
    +    "downloads",
    +    "deploy",
    +  ])
    +
    +  const repos: ChildRepo[] = []
    +  const scanDir = (dir: string) => {
    +    try {
    +      for (const entry of readdirSync(dir, { withFileTypes: true })) {
    +        if (entry.name.startsWith(".") || SCAN_IGNORE.has(entry.name)) continue
    +        const full = path.join(dir, entry.name)
    +        const dotgit = path.join(full, ".git")
    +        if (existsSync(dotgit)) {
    +          repos.push({
    +            dir: full,
    +            prefix: path.relative(rootDir, full),
    +          })
    +        }
    +      }
    +    } catch { /* permission errors, etc */ }
    +  }
    +
    +  // Scan immediate children and one level deeper (e.g. src/*/)
    +  // The root dir's own .git is skipped by the "." prefix filter
    +  scanDir(rootDir)
    +  try {
    +    for (const entry of readdirSync(rootDir, { withFileTypes: true })) {
    +      if (entry.name.startsWith(".") || SCAN_IGNORE.has(entry.name)) continue
    +      const full = path.join(rootDir, entry.name)
    +      try {
    +        if (statSync(full).isDirectory()) scanDir(full)
    +      } catch { /* skip */ }
    +    }
    +  } catch { /* skip */ }
    +
    +  childRepoCache.set(rootDir, repos)
    +  return repos
    +}
    +
    +// Prefix all file paths in a status/diff result with the repo's relative path
    +const prefixFile = (prefix: string, file: string) =>
    +  prefix ? `${prefix}/${file}` : file
    +
    +// Run status() across all child repos and aggregate
    +const multiRepoStatus = Effect.fnUntraced(function* (
    +  git: Git.Interface,
    +  rootDir: string,
    +) {
    +  const repos = discoverChildRepos(rootDir)
    +  if (repos.length === 0) return []
    +
    +  const results: FileStatus[] = []
    +  for (const repo of repos) {
    +    const hasHead = yield* git.hasHead(repo.dir)
    +    const ref = hasHead ? "HEAD" : undefined
    +    const [list, stats] = yield* Effect.all(
    +      [git.status(repo.dir), ref ? git.stats(repo.dir, ref) : Effect.succeed([])],
    +      { concurrency: 2 },
    +    )
    +    const map = nums(stats)
    +    for (const item of list.toSorted((a, b) => a.file.localeCompare(b.file))) {
    +      const stat =
    +        map.get(item.file) ??
    +        (item.status === "added" ? yield* git.statUntracked(repo.dir, item.file) : undefined)
    +      results.push({
    +        file: prefixFile(repo.prefix, item.file),
    +        additions: stat?.additions ?? 0,
    +        deletions: stat?.deletions ?? 0,
    +        status: item.status,
    +      })
    +    }
    +  }
    +  return results.toSorted((a, b) => a.file.localeCompare(b.file))
    +})
    +
    +// Run diff() across all child repos and aggregate
    +const multiRepoDiff = Effect.fnUntraced(function* (
    +  git: Git.Interface,
    +  rootDir: string,
    +  options?: DiffOptions,
    +) {
    +  const repos = discoverChildRepos(rootDir)
    +  if (repos.length === 0) return []
    +
    +  const results: FileDiff[] = []
    +  for (const repo of repos) {
    +    const hasHead = yield* git.hasHead(repo.dir)
    +    const ref = hasHead ? "HEAD" : undefined
    +    const diffs = yield* track(git, repo.dir, ref, options)
    +    for (const d of diffs) {
    +      results.push({
    +        ...d,
    +        file: prefixFile(repo.prefix, d.file),
    +      })
    +    }
    +  }
    +  return results.toSorted((a, b) => a.file.localeCompare(b.file))
    +})
    +
    +// Run diffRaw() across all child repos and aggregate
    +const multiRepoDiffRaw = Effect.fnUntraced(function* (
    +  git: Git.Interface,
    +  rootDir: string,
    +) {
    +  const repos = discoverChildRepos(rootDir)
    +  if (repos.length === 0) return ""
    +
    +  const parts: string[] = []
    +  for (const repo of repos) {
    +    const [hasHead, status] = yield* Effect.all(
    +      [git.hasHead(repo.dir), git.status(repo.dir)],
    +      { concurrency: 2 },
    +    )
    +    const tracked = hasHead ? (yield* git.patchAll(repo.dir, "HEAD")).text : ""
    +    const untracked = yield* Effect.forEach(
    +      status.filter((item) => item.code === "??"),
    +      (item) => git.patchUntracked(repo.dir, item.file).pipe(Effect.map((patch) => patch.text)),
    +    )
    +    parts.push(...[tracked, ...untracked].filter(Boolean))
    +  }
    +  return parts.join("\n")
    +})
    +
     export const Mode = Schema.Literals(["git", "branch"])
     export type Mode = Schema.Schema.Type<typeof Mode>
     
    @@ -347,55 +493,89 @@ const layer: Layer.Layer<Service, never, Git.Service | EventV2Bridge.Service> =
           }),
           status: Effect.fn("Vcs.status")(function* () {
             const ctx = yield* InstanceState.context
    -        if (ctx.project.vcs !== "git") return []
    -        const ref = (yield* git.hasHead(ctx.directory)) ? "HEAD" : undefined
    -        const [list, stats] = yield* Effect.all(
    -          [git.status(ctx.directory), ref ? git.stats(ctx.directory, ref) : Effect.succeed([])],
    -          { concurrency: 2 },
    -        )
    -        const map = nums(stats)
    -        return yield* Effect.forEach(
    -          list.toSorted((a, b) => a.file.localeCompare(b.file)),
    -          (item) =>
    -            Effect.gen(function* () {
    -              const stat =
    -                map.get(item.file) ??
    -                (item.status === "added" ? yield* git.statUntracked(ctx.worktree, item.file) : undefined)
    -              return {
    -                file: item.file,
    -                additions: stat?.additions ?? 0,
    -                deletions: stat?.deletions ?? 0,
    -                status: item.status,
    -              } satisfies FileStatus
    -            }),
    -        )
    +        const results: FileStatus[] = []
    +        if (ctx.project.vcs === "git") {
    +          // Root repo changes
    +          const ref = (yield* git.hasHead(ctx.directory)) ? "HEAD" : undefined
    +          const [list, stats] = yield* Effect.all(
    +            [git.status(ctx.directory), ref ? git.stats(ctx.directory, ref) : Effect.succeed([])],
    +            { concurrency: 2 },
    +          )
    +          const map = nums(stats)
    +          const rootResults = yield* Effect.forEach(
    +            list.toSorted((a, b) => a.file.localeCompare(b.file)),
    +            (item) =>
    +              Effect.gen(function* () {
    +                const stat =
    +                  map.get(item.file) ??
    +                  (item.status === "added" ? yield* git.statUntracked(ctx.worktree, item.file) : undefined)
    +                return {
    +                  file: item.file,
    +                  additions: stat?.additions ?? 0,
    +                  deletions: stat?.deletions ?? 0,
    +                  status: item.status,
    +                } satisfies FileStatus
    +              }),
    +          )
    +          results.push(...rootResults)
    +        }
    +        // Also discover child repos and aggregate their changes
    +        const workspaceDir = ctx.project.vcs === "git" ? ctx.directory : (ctx.directory !== "/" ? ctx.directory : ctx.worktree)
    +        if (workspaceDir && workspaceDir !== "/") {
    +          const childResults = yield* multiRepoStatus(git, workspaceDir)
    +          results.push(...childResults)
    +        }
    +        return results.toSorted((a, b) => a.file.localeCompare(b.file))
           }),
           diff: Effect.fn("Vcs.diff")(function* (mode: Mode, options?: DiffOptions) {
             const value = yield* InstanceState.get(state)
             const ctx = yield* InstanceState.context
    -        if (ctx.project.vcs !== "git") return []
    -        if (mode === "git") {
    -          return yield* track(git, ctx.directory, (yield* git.hasHead(ctx.directory)) ? "HEAD" : undefined, options)
    +        const results: FileDiff[] = []
    +        if (ctx.project.vcs === "git") {
    +          // Root repo changes
    +          if (mode === "git") {
    +            const rootDiffs = yield* track(git, ctx.directory, (yield* git.hasHead(ctx.directory)) ? "HEAD" : undefined, options)
    +            results.push(...rootDiffs)
    +          } else {
    +            if (value.root && !(value.current && value.current === value.root.name)) {
    +              const ref = yield* git.mergeBase(ctx.directory, value.root.ref)
    +              if (ref) {
    +                const rootDiffs = yield* diffAgainstRef(git, ctx.directory, ref, options)
    +                results.push(...rootDiffs)
    +              }
    +            }
    +          }
             }
    -
    -        if (!value.root) return []
    -        if (value.current && value.current === value.root.name) return []
    -        const ref = yield* git.mergeBase(ctx.directory, value.root.ref)
    -        if (!ref) return []
    -        return yield* diffAgainstRef(git, ctx.directory, ref, options)
    +        // Also discover child repos and aggregate their changes
    +        const workspaceDir = ctx.project.vcs === "git" ? ctx.directory : (ctx.directory !== "/" ? ctx.directory : ctx.worktree)
    +        if (workspaceDir && workspaceDir !== "/") {
    +          const childDiffs = yield* multiRepoDiff(git, workspaceDir, options)
    +          results.push(...childDiffs)
    +        }
    +        return results.toSorted((a, b) => a.file.localeCompare(b.file))
           }),
           diffRaw: Effect.fn("Vcs.diffRaw")(function* () {
             const ctx = yield* InstanceState.context
    -        if (ctx.project.vcs !== "git") return ""
    -        const [hasHead, status] = yield* Effect.all([git.hasHead(ctx.directory), git.status(ctx.directory)], {
    -          concurrency: 2,
    -        })
    -        const tracked = hasHead ? (yield* git.patchAll(ctx.directory, "HEAD")).text : ""
    -        const untracked = yield* Effect.forEach(
    -          status.filter((item) => item.code === "??"),
    -          (item) => git.patchUntracked(ctx.directory, item.file).pipe(Effect.map((patch) => patch.text)),
    -        )
    -        return [tracked, ...untracked].filter(Boolean).join("\n")
    +        const parts: string[] = []
    +        if (ctx.project.vcs === "git") {
    +          // Root repo changes
    +          const [hasHead, status] = yield* Effect.all([git.hasHead(ctx.directory), git.status(ctx.directory)], {
    +            concurrency: 2,
    +          })
    +          const tracked = hasHead ? (yield* git.patchAll(ctx.directory, "HEAD")).text : ""
    +          const untracked = yield* Effect.forEach(
    +            status.filter((item) => item.code === "??"),
    +            (item) => git.patchUntracked(ctx.directory, item.file).pipe(Effect.map((patch) => patch.text)),
    +          )
    +          parts.push(...[tracked, ...untracked].filter(Boolean))
    +        }
    +        // Also discover child repos and aggregate their changes
    +        const workspaceDir = ctx.project.vcs === "git" ? ctx.directory : (ctx.directory !== "/" ? ctx.directory : ctx.worktree)
    +        if (workspaceDir && workspaceDir !== "/") {
    +          const childRaw = yield* multiRepoDiffRaw(git, workspaceDir)
    +          if (childRaw) parts.push(childRaw)
    +        }
    +        return parts.join("\n")
           }),
           apply: Effect.fn("Vcs.apply")(function* (input: ApplyInput) {
             const ctx = yield* InstanceState.context
  11. github-actions commented on Sep 17, 2026

    @github-actions
    Contributor

    To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions