fix: scope auth env for workspace adaptors#186
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (4)
📜 Recent review details⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
🧰 Additional context used📓 Path-based instructions (2)packages/opencode/**/*.ts📄 CodeRabbit inference engine (packages/opencode/AGENTS.md)
Files:
packages/opencode/test/**/*.test.{ts,tsx}📄 CodeRabbit inference engine (packages/opencode/test/AGENTS.md)
Files:
🧠 Learnings (29)📓 Common learnings📚 Learning: 2026-04-22T09:32:52.535ZApplied to files:
📚 Learning: 2026-04-20T14:36:21.274ZApplied to files:
📚 Learning: 2026-04-20T14:36:31.017ZApplied to files:
📚 Learning: 2026-04-20T14:36:21.274ZApplied to files:
📚 Learning: 2026-04-20T14:36:31.017ZApplied to files:
📚 Learning: 2026-04-20T14:36:21.274ZApplied to files:
📚 Learning: 2026-04-20T14:36:21.274ZApplied to files:
📚 Learning: 2026-04-20T14:36:21.274ZApplied to files:
📚 Learning: 2026-04-20T14:36:21.274ZApplied to files:
📚 Learning: 2026-04-20T14:36:31.017ZApplied to files:
📚 Learning: 2026-04-20T14:36:21.274ZApplied to files:
📚 Learning: 2026-04-23T08:51:00.819ZApplied to files:
📚 Learning: 2026-04-20T14:36:31.017ZApplied to files:
📚 Learning: 2026-04-20T14:36:31.017ZApplied to files:
📚 Learning: 2026-04-20T14:36:31.017ZApplied to files:
📚 Learning: 2026-04-20T14:36:31.017ZApplied to files:
📚 Learning: 2026-04-20T14:36:31.017ZApplied to files:
📚 Learning: 2026-04-20T14:36:31.017ZApplied to files:
📚 Learning: 2026-04-22T09:32:52.806ZApplied to files:
📚 Learning: 2026-04-20T14:36:04.099ZApplied to files:
📚 Learning: 2026-04-22T08:49:44.563ZApplied to files:
📚 Learning: 2026-04-20T14:36:04.099ZApplied to files:
📚 Learning: 2026-04-20T14:36:04.099ZApplied to files:
📚 Learning: 2026-04-21T16:57:22.813ZApplied to files:
📚 Learning: 2026-04-20T17:03:37.710ZApplied to files:
📚 Learning: 2026-04-20T14:21:51.047ZApplied to files:
📚 Learning: 2026-04-21T13:45:41.773ZApplied to files:
📚 Learning: 2026-04-21T16:57:20.257ZApplied to files:
🔇 Additional comments (6)
📝 WalkthroughWalkthroughWorkspace adaptors may opt into scoped auth forwarding via an optional Changes
Sequence Diagram(s)sequenceDiagram
participant Core as Core (workspace.create)
participant Auth as Auth Service (auth.all / auth.json)
participant Adaptor as Workspace Adaptor (plugin)
participant Env as Env (child process)
Core->>Auth: read full auth store (auth.all)
Core->>Core: read adaptor.auth.providers (optional)
alt providers declared
Core->>Core: filter auth store to requested providers
else no providers
Core->>Core: do not prepare auth content
end
alt scoped auth non-empty
Core->>Env: set OPENCODE_AUTH_CONTENT with scoped JSON
else scoped auth empty
Core->>Env: do not set OPENCODE_AUTH_CONTENT
end
Core->>Adaptor: spawn adaptor process with env
Adaptor->>Env: receives env (may include OPENCODE_AUTH_CONTENT)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Suggested labels
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Code Review
This pull request implements scoped authentication for workspace adaptors, allowing them to specify a list of required auth providers. The core logic now filters the OPENCODE_AUTH_CONTENT environment variable to only include these requested providers, enhancing security by not exposing the full auth store by default. Feedback was provided regarding the withAuthFile test helper, which modifies global state and could lead to race conditions; it is recommended to use dependency injection or mocks for the authentication service instead.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/opencode/test/plugin/workspace-adaptor.test.ts`:
- Around line 133-138: The test cleanup mixes Filesystem.write with
node:fs/promises.unlink; update the teardown to use the same API for
deletion—replace the unlink(authPath).catch(...) call with
Filesystem.remove(authPath) (or Filesystem.unlink/remove equivalent) so both
write and delete use the Filesystem helper; reference the Filesystem.write call
and the unlink(authPath) usage around authPath in the finally block and ensure
the new call preserves the existing error-swallowing behavior (e.g.,
catch/ignore any errors).
- Around line 122-140: The empty catch in withAuthFile swallows all errors from
Filesystem.readText; change it to only ignore a "file not found" case by
catching the specific error (e.g., check error.code or use
Filesystem.isNotFound) while rethrowing other errors so real failures
(permission/disk) surface; update the try/catch around Filesystem.readText in
withAuthFile to inspect the thrown error and only treat missing-file as
non-fatal, preserving original behavior for unlink and write operations
(references: function withAuthFile, Filesystem.readText, Filesystem.write,
unlink, authPath).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 3d68b5d9-5921-463a-81dd-5a62293ae6f1
📒 Files selected for processing (4)
packages/opencode/src/control-plane/types.tspackages/opencode/src/control-plane/workspace.tspackages/opencode/test/plugin/workspace-adaptor.test.tspackages/plugin/src/index.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (12)
- GitHub Check: unit-windows-desktop
- GitHub Check: typecheck
- GitHub Check: unit-windows-opencode-config-project
- GitHub Check: unit-windows-opencode-session
- GitHub Check: unit-windows-opencode-server-tools
- GitHub Check: unit-opencode
- GitHub Check: unit-windows-app
- GitHub Check: unit-app
- GitHub Check: unit-desktop
- GitHub Check: smoke-macos-arm64
- GitHub Check: e2e-artifacts
- GitHub Check: analyze-js-ts
🧰 Additional context used
📓 Path-based instructions (2)
packages/opencode/**/*.ts
📄 CodeRabbit inference engine (packages/opencode/AGENTS.md)
packages/opencode/**/*.ts: UseEffect.gen(function* () { ... })for Effect composition
UseEffect.fn("Domain.method")for named/traced effects andEffect.fnUntracedfor internal helpers; these accept pipeable operators as extra arguments to avoid unnecessary outer.pipe()wrappers
UseEffect.callbackfor callback-based APIs
PreferDateTime.nowAsDateovernew Date(yield* Clock.currentTimeMillis)when you need aDatein Effect code
UseSchema.Classfor multi-field data in Effect schemas
Use branded schemas (Schema.brand) for single-value types in Effect
UseSchema.TaggedErrorClassfor typed errors in Effect schemas
UseSchema.Defectinstead ofunknownfor defect-like causes in Effect code
InEffect.gen/Effect.fn, preferyield* new MyError(...)overyield* Effect.fail(new MyError(...))for direct early-failure branches
UsemakeRuntimefromsrc/effect/run-service.tsfor all services; it returns{ runPromise, runFork, runCallback }backed by a sharedmemoMapthat deduplicates layers
UseInstanceStatefromsrc/effect/instance-state.tsfor per-directory or per-project state that needs per-instance cleanup; do work directly in theInstanceState.makeclosure whereScopedCachehandles run-once semantics
UseEffect.addFinalizerorEffect.acquireReleaseinside theInstanceState.makeclosure for cleanup (subscriptions, process teardown, etc.)
UseEffect.forkScopedinside theInstanceState.makeclosure for background stream consumers — the fiber is interrupted when the instance is disposed
PreferFileSystem.FileSysteminstead of rawfs/promisesfor effectful file I/O in Effect services
PreferChildProcessSpawner.ChildProcessSpawnerwithChildProcess.make(...)instead of custom process wrappers in Effect services
PreferHttpClient.HttpClientinstead of rawfetchin Effect services
PreferPath.Path,Config,Clock, andDateTimeservices when those concerns are already inside Effect code
For backgroun...
Files:
packages/opencode/src/control-plane/types.tspackages/opencode/src/control-plane/workspace.tspackages/opencode/test/plugin/workspace-adaptor.test.ts
packages/opencode/test/**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (packages/opencode/test/AGENTS.md)
packages/opencode/test/**/*.test.{ts,tsx}: Use thetmpdirfunction fromfixture/fixture.tsto create temporary directories for tests with automatic cleanup. Useawait usingsyntax to ensure automatic cleanup when the variable goes out of scope.
When using thetmpdirfunction with git repository support, pass thegit: trueoption to initialize a git repo with a root commit.
Use theconfigoption intmpdirto write anopencode.jsonconfig file during test setup by passing a partial Config.Info object.
Use theinitoption intmpdirto define custom setup functions that can return extra data accessible viatmp.extra, and use thedisposeoption for custom cleanup logic.
UsetestEffect(...)fromtest/lib/effect.tsfor tests that exercise Effect services or Effect-based workflows.
Useit.effect(...)when the test should run withTestClockandTestConsole. Useit.live(...)when the test depends on real time, filesystem mtimes, child processes, git, locks, or other live OS behavior.
Prefer Effect-aware helpers fromfixture/fixture.tsover building manual runtimes in tests: usetmpdirScoped()for scoped temp directories,provideInstance(dir)(effect)for low-level binding without directory creation,provideTmpdirInstance(...)for single temp instance binding, orprovideTmpdirServer(...)for tests that also need the test LLM server.
Defineconst it = testEffect(...)near the top of the test file and keep the test body insideEffect.gen(function* () { ... }). Yield services directly withyield* MyService.Serviceoryield* MyTool.
Avoid customManagedRuntime,attach(...), or ad hocrun(...)wrappers in Effect tests whentestEffect(...)already provides the runtime.
When a test needs instance-local state, preferprovideTmpdirInstance(...)orprovideInstance(...)over manualInstance.provide(...)inside Promise-style tests.
Files:
packages/opencode/test/plugin/workspace-adaptor.test.ts
🧠 Learnings (24)
📓 Common learnings
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 126
File: packages/ui/src/theme/context.tsx:11-16
Timestamp: 2026-04-22T09:32:52.535Z
Learning: In Astro-Han/pawwork (`packages/ui/src/theme/context.tsx` and related files), the renaming of localStorage theme keys from `opencode-*` to `pawwork-*` (THEME_ID, COLOR_SCHEME, THEME_CSS_LIGHT, THEME_CSS_DARK) is intentional and should NOT include a migration path from the old keys. Migrating would re-couple PawWork and OpenCode browser storage namespaces, which the PR is explicitly designed to avoid. A reset to the PawWork default theme on upgrade is acceptable by design.
📚 Learning: 2026-04-22T09:32:52.535Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 126
File: packages/ui/src/theme/context.tsx:11-16
Timestamp: 2026-04-22T09:32:52.535Z
Learning: In Astro-Han/pawwork (`packages/ui/src/theme/context.tsx` and related files), the renaming of localStorage theme keys from `opencode-*` to `pawwork-*` (THEME_ID, COLOR_SCHEME, THEME_CSS_LIGHT, THEME_CSS_DARK) is intentional and should NOT include a migration path from the old keys. Migrating would re-couple PawWork and OpenCode browser storage namespaces, which the PR is explicitly designed to avoid. A reset to the PawWork default theme on upgrade is acceptable by design.
Applied to files:
packages/opencode/src/control-plane/workspace.ts
📚 Learning: 2026-04-20T14:36:21.274Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:21.274Z
Learning: Applies to packages/opencode/**/*.ts : Use `Effect.cached` when multiple concurrent callers should share a single in-flight computation rather than storing `Fiber | undefined` or `Promise | undefined` manually
Applied to files:
packages/opencode/src/control-plane/workspace.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Use `testEffect(...)` from `test/lib/effect.ts` for tests that exercise Effect services or Effect-based workflows.
Applied to files:
packages/opencode/src/control-plane/workspace.tspackages/opencode/test/plugin/workspace-adaptor.test.ts
📚 Learning: 2026-04-20T14:36:21.274Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:21.274Z
Learning: Applies to packages/opencode/**/*.ts : Use `Effect.gen(function* () { ... })` for Effect composition
Applied to files:
packages/opencode/src/control-plane/workspace.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Define `const it = testEffect(...)` near the top of the test file and keep the test body inside `Effect.gen(function* () { ... })`. Yield services directly with `yield* MyService.Service` or `yield* MyTool`.
Applied to files:
packages/opencode/src/control-plane/workspace.tspackages/opencode/test/plugin/workspace-adaptor.test.ts
📚 Learning: 2026-04-20T14:36:21.274Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:21.274Z
Learning: Applies to packages/opencode/**/*.ts : Prefer `Path.Path`, `Config`, `Clock`, and `DateTime` services when those concerns are already inside Effect code
Applied to files:
packages/opencode/src/control-plane/workspace.ts
📚 Learning: 2026-04-20T14:36:21.274Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:21.274Z
Learning: Applies to packages/opencode/**/*.ts : Prefer `FileSystem.FileSystem` instead of raw `fs/promises` for effectful file I/O in Effect services
Applied to files:
packages/opencode/src/control-plane/workspace.tspackages/opencode/test/plugin/workspace-adaptor.test.ts
📚 Learning: 2026-04-20T14:36:21.274Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:21.274Z
Learning: Applies to packages/opencode/**/*.ts : For background loops or scheduled tasks, use `Effect.repeat` or `Effect.schedule` with `Effect.forkScoped` in the layer definition
Applied to files:
packages/opencode/src/control-plane/workspace.ts
📚 Learning: 2026-04-20T14:36:21.274Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:21.274Z
Learning: Applies to packages/opencode/**/*.ts : Use `Effect.fn("Domain.method")` for named/traced effects and `Effect.fnUntraced` for internal helpers; these accept pipeable operators as extra arguments to avoid unnecessary outer `.pipe()` wrappers
Applied to files:
packages/opencode/src/control-plane/workspace.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Use `it.effect(...)` when the test should run with `TestClock` and `TestConsole`. Use `it.live(...)` when the test depends on real time, filesystem mtimes, child processes, git, locks, or other live OS behavior.
Applied to files:
packages/opencode/src/control-plane/workspace.tspackages/opencode/test/plugin/workspace-adaptor.test.ts
📚 Learning: 2026-04-20T14:36:21.274Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:21.274Z
Learning: Applies to packages/opencode/**/*.ts : Use `Effect.callback` for callback-based APIs
Applied to files:
packages/opencode/src/control-plane/workspace.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Use the `config` option in `tmpdir` to write an `opencode.json` config file during test setup by passing a partial Config.Info object.
Applied to files:
packages/opencode/test/plugin/workspace-adaptor.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Prefer Effect-aware helpers from `fixture/fixture.ts` over building manual runtimes in tests: use `tmpdirScoped()` for scoped temp directories, `provideInstance(dir)(effect)` for low-level binding without directory creation, `provideTmpdirInstance(...)` for single temp instance binding, or `provideTmpdirServer(...)` for tests that also need the test LLM server.
Applied to files:
packages/opencode/test/plugin/workspace-adaptor.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Use the `tmpdir` function from `fixture/fixture.ts` to create temporary directories for tests with automatic cleanup. Use `await using` syntax to ensure automatic cleanup when the variable goes out of scope.
Applied to files:
packages/opencode/test/plugin/workspace-adaptor.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Use the `init` option in `tmpdir` to define custom setup functions that can return extra data accessible via `tmp.extra`, and use the `dispose` option for custom cleanup logic.
Applied to files:
packages/opencode/test/plugin/workspace-adaptor.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Use fixture-managed cleanup with `withSession(sdk, title, callback)` for temporary sessions instead of calling `sdk.session.delete(...)` directly
Applied to files:
packages/opencode/test/plugin/workspace-adaptor.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : When a test needs instance-local state, prefer `provideTmpdirInstance(...)` or `provideInstance(...)` over manual `Instance.provide(...)` inside Promise-style tests.
Applied to files:
packages/opencode/test/plugin/workspace-adaptor.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : When validating routing, assert against canonical or resolved workspace slugs using shared helpers from `../actions` to account for Windows canonicalization
Applied to files:
packages/opencode/test/plugin/workspace-adaptor.test.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Import test utilities from `../fixtures` instead of `playwright/test`
Applied to files:
packages/opencode/test/plugin/workspace-adaptor.test.ts
📚 Learning: 2026-04-22T09:32:52.806Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 126
File: packages/opencode/test/provider/provider.test.ts:64-85
Timestamp: 2026-04-22T09:32:52.806Z
Learning: In `packages/opencode/test/provider/provider.test.ts`, the file intentionally uses AppRuntime-based async helpers (`run`, `list`, `getProvider`, etc.) rather than `testEffect(...)` for all tests. Converting individual tests to `testEffect` while leaving the rest on the async pattern would create internal inconsistency. A full harness migration of this file is the right approach if the pattern needs to change, but that should be a separate PR.
Applied to files:
packages/opencode/test/plugin/workspace-adaptor.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : When using the `tmpdir` function with git repository support, pass the `git: true` option to initialize a git repo with a root commit.
Applied to files:
packages/opencode/test/plugin/workspace-adaptor.test.ts
📚 Learning: 2026-04-22T08:49:44.563Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 126
File: packages/desktop-electron/src/main/index-sidecar-source.test.ts:3-11
Timestamp: 2026-04-22T08:49:44.563Z
Learning: In `packages/desktop-electron/src/main/index-sidecar-source.test.ts` (Astro-Han/pawwork), the test intentionally uses `expect(source).toContain` / `expect(source).not.toContain` string matching against the raw `index.ts` source text as a lightweight sidecar contract guard. The maintainer has explicitly chosen not to introduce an AST parser (e.g., `babel/parser` or acorn) for this purpose. Do not flag these string-based assertions as fragile or suggest converting them to AST-based matching.
Applied to files:
packages/opencode/test/plugin/workspace-adaptor.test.ts
📚 Learning: 2026-04-20T17:03:37.710Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 73
File: packages/opencode/src/cli/cmd/tui/context/sync.tsx:486-489
Timestamp: 2026-04-20T17:03:37.710Z
Learning: In Astro-Han/pawwork (`packages/opencode/src/cli/cmd/tui/context/sync.tsx`), `sync.ready` returning `true` when `process.env.OPENCODE_FAST_BOOT` is set is intentional. The plugin-facing data properties `state.config` (initialized to `{}`) and `state.provider` (initialized to `[]`) expose safe-empty defaults, so they are safe to access before bootstrap completes. Do not flag these as needing null-guards or conditional patterns to match `vcs` — the difference is intentional because `vcs` starts as `undefined` while the others have initialized defaults. Changing this would alter the plugin API contract without a concrete failing case.
Applied to files:
packages/opencode/test/plugin/workspace-adaptor.test.ts
🔇 Additional comments (5)
packages/opencode/src/control-plane/types.ts (1)
27-36: LGTM!The optional
authfield cleanly extends theAdaptortype for explicit auth opt-in. Backward-compatible since existing adaptors (likeWorktreeAdaptor) can omit it.packages/plugin/src/index.ts (1)
48-66: LGTM!The
WorkspaceAdaptortype and documentation align with the coreAdaptortype. The JSDoc clearly communicates the opt-in mechanism and security expectations for plugin authors.packages/opencode/src/control-plane/workspace.ts (1)
208-228: LGTM - Auth scoping implementation is sound.The logic correctly:
- Deduplicates requested providers
- Skips auth fetching entirely when no providers are requested
- Filters the auth store to only requested providers
- Omits
OPENCODE_AUTH_CONTENTwhen the scoped result is emptyThis aligns with the PR objective of applying least-privilege principles to auth forwarding.
packages/opencode/test/plugin/workspace-adaptor.test.ts (2)
183-183: Good coverage for the default no-auth path.This assertion correctly verifies that
OPENCODE_AUTH_CONTENTis absent when the adaptor does not declareauth.providers, enforcing the opt-in security model.
193-280: Good test coverage for scoped auth forwarding.The test properly verifies that:
- Only requested provider credentials (
openai) are forwarded- Non-requested providers (
anthropic) are excluded fromOPENCODE_AUTH_CONTENTThis validates the least-privilege implementation in
workspace.ts.
68628d5 to
b6cf198
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/opencode/test/plugin/workspace-adaptor.test.ts`:
- Around line 199-286: Test is missing creation of the workspace directory
referenced by the plugin (tmp.extra.space), causing the workspace to end up in
"error" status; add creation of the directory inside the tmpdir init block after
computing the space path. Specifically, in the test "plugin workspace adaptor
only receives the requested auth providers" inside the tmpdir init, create the
directory referenced by the local variable space (used later as the plugin
configure return directory and asserted via tmp.extra.space) so Workspace.create
gets a real directory; update the tmpdir init to call the project/File-system
directory creation (e.g., create the path stored in space) before returning {
mark, space, type }.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: b464883e-47d3-4932-8799-0b982050e4e6
📒 Files selected for processing (4)
packages/opencode/src/control-plane/types.tspackages/opencode/src/control-plane/workspace.tspackages/opencode/test/plugin/workspace-adaptor.test.tspackages/plugin/src/index.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (12)
- GitHub Check: unit-windows-opencode-server-tools
- GitHub Check: unit-windows-app
- GitHub Check: unit-windows-desktop
- GitHub Check: unit-windows-opencode-config-project
- GitHub Check: unit-windows-opencode-session
- GitHub Check: unit-app
- GitHub Check: unit-opencode
- GitHub Check: typecheck
- GitHub Check: unit-desktop
- GitHub Check: smoke-macos-arm64
- GitHub Check: analyze-js-ts
- GitHub Check: e2e-artifacts
🧰 Additional context used
📓 Path-based instructions (2)
packages/opencode/**/*.ts
📄 CodeRabbit inference engine (packages/opencode/AGENTS.md)
packages/opencode/**/*.ts: UseEffect.gen(function* () { ... })for Effect composition
UseEffect.fn("Domain.method")for named/traced effects andEffect.fnUntracedfor internal helpers; these accept pipeable operators as extra arguments to avoid unnecessary outer.pipe()wrappers
UseEffect.callbackfor callback-based APIs
PreferDateTime.nowAsDateovernew Date(yield* Clock.currentTimeMillis)when you need aDatein Effect code
UseSchema.Classfor multi-field data in Effect schemas
Use branded schemas (Schema.brand) for single-value types in Effect
UseSchema.TaggedErrorClassfor typed errors in Effect schemas
UseSchema.Defectinstead ofunknownfor defect-like causes in Effect code
InEffect.gen/Effect.fn, preferyield* new MyError(...)overyield* Effect.fail(new MyError(...))for direct early-failure branches
UsemakeRuntimefromsrc/effect/run-service.tsfor all services; it returns{ runPromise, runFork, runCallback }backed by a sharedmemoMapthat deduplicates layers
UseInstanceStatefromsrc/effect/instance-state.tsfor per-directory or per-project state that needs per-instance cleanup; do work directly in theInstanceState.makeclosure whereScopedCachehandles run-once semantics
UseEffect.addFinalizerorEffect.acquireReleaseinside theInstanceState.makeclosure for cleanup (subscriptions, process teardown, etc.)
UseEffect.forkScopedinside theInstanceState.makeclosure for background stream consumers — the fiber is interrupted when the instance is disposed
PreferFileSystem.FileSysteminstead of rawfs/promisesfor effectful file I/O in Effect services
PreferChildProcessSpawner.ChildProcessSpawnerwithChildProcess.make(...)instead of custom process wrappers in Effect services
PreferHttpClient.HttpClientinstead of rawfetchin Effect services
PreferPath.Path,Config,Clock, andDateTimeservices when those concerns are already inside Effect code
For backgroun...
Files:
packages/opencode/src/control-plane/types.tspackages/opencode/test/plugin/workspace-adaptor.test.tspackages/opencode/src/control-plane/workspace.ts
packages/opencode/test/**/*.test.{ts,tsx}
📄 CodeRabbit inference engine (packages/opencode/test/AGENTS.md)
packages/opencode/test/**/*.test.{ts,tsx}: Use thetmpdirfunction fromfixture/fixture.tsto create temporary directories for tests with automatic cleanup. Useawait usingsyntax to ensure automatic cleanup when the variable goes out of scope.
When using thetmpdirfunction with git repository support, pass thegit: trueoption to initialize a git repo with a root commit.
Use theconfigoption intmpdirto write anopencode.jsonconfig file during test setup by passing a partial Config.Info object.
Use theinitoption intmpdirto define custom setup functions that can return extra data accessible viatmp.extra, and use thedisposeoption for custom cleanup logic.
UsetestEffect(...)fromtest/lib/effect.tsfor tests that exercise Effect services or Effect-based workflows.
Useit.effect(...)when the test should run withTestClockandTestConsole. Useit.live(...)when the test depends on real time, filesystem mtimes, child processes, git, locks, or other live OS behavior.
Prefer Effect-aware helpers fromfixture/fixture.tsover building manual runtimes in tests: usetmpdirScoped()for scoped temp directories,provideInstance(dir)(effect)for low-level binding without directory creation,provideTmpdirInstance(...)for single temp instance binding, orprovideTmpdirServer(...)for tests that also need the test LLM server.
Defineconst it = testEffect(...)near the top of the test file and keep the test body insideEffect.gen(function* () { ... }). Yield services directly withyield* MyService.Serviceoryield* MyTool.
Avoid customManagedRuntime,attach(...), or ad hocrun(...)wrappers in Effect tests whentestEffect(...)already provides the runtime.
When a test needs instance-local state, preferprovideTmpdirInstance(...)orprovideInstance(...)over manualInstance.provide(...)inside Promise-style tests.
Files:
packages/opencode/test/plugin/workspace-adaptor.test.ts
🧠 Learnings (28)
📓 Common learnings
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 126
File: packages/ui/src/theme/context.tsx:11-16
Timestamp: 2026-04-22T09:32:52.535Z
Learning: In Astro-Han/pawwork (`packages/ui/src/theme/context.tsx` and related files), the renaming of localStorage theme keys from `opencode-*` to `pawwork-*` (THEME_ID, COLOR_SCHEME, THEME_CSS_LIGHT, THEME_CSS_DARK) is intentional and should NOT include a migration path from the old keys. Migrating would re-couple PawWork and OpenCode browser storage namespaces, which the PR is explicitly designed to avoid. A reset to the PawWork default theme on upgrade is acceptable by design.
📚 Learning: 2026-04-23T08:51:00.819Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 186
File: packages/opencode/test/plugin/workspace-adaptor.test.ts:139-144
Timestamp: 2026-04-23T08:51:00.819Z
Learning: For pawwork tests under packages/opencode/test/**, auth.json teardown may intentionally combine `Filesystem.write` (from `packages/opencode/src/util/filesystem.ts`) with `node:fs/promises` `unlink` for cleanup. Do not flag this as inconsistent style; it is the established/intentional pattern because `Filesystem` does not provide a `remove`/`unlink` helper.
Applied to files:
packages/opencode/test/plugin/workspace-adaptor.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Prefer Effect-aware helpers from `fixture/fixture.ts` over building manual runtimes in tests: use `tmpdirScoped()` for scoped temp directories, `provideInstance(dir)(effect)` for low-level binding without directory creation, `provideTmpdirInstance(...)` for single temp instance binding, or `provideTmpdirServer(...)` for tests that also need the test LLM server.
Applied to files:
packages/opencode/test/plugin/workspace-adaptor.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Use the `config` option in `tmpdir` to write an `opencode.json` config file during test setup by passing a partial Config.Info object.
Applied to files:
packages/opencode/test/plugin/workspace-adaptor.test.ts
📚 Learning: 2026-04-22T09:32:52.806Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 126
File: packages/opencode/test/provider/provider.test.ts:64-85
Timestamp: 2026-04-22T09:32:52.806Z
Learning: In `packages/opencode/test/provider/provider.test.ts`, the file intentionally uses AppRuntime-based async helpers (`run`, `list`, `getProvider`, etc.) rather than `testEffect(...)` for all tests. Converting individual tests to `testEffect` while leaving the rest on the async pattern would create internal inconsistency. A full harness migration of this file is the right approach if the pattern needs to change, but that should be a separate PR.
Applied to files:
packages/opencode/test/plugin/workspace-adaptor.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Use the `tmpdir` function from `fixture/fixture.ts` to create temporary directories for tests with automatic cleanup. Use `await using` syntax to ensure automatic cleanup when the variable goes out of scope.
Applied to files:
packages/opencode/test/plugin/workspace-adaptor.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : When a test needs instance-local state, prefer `provideTmpdirInstance(...)` or `provideInstance(...)` over manual `Instance.provide(...)` inside Promise-style tests.
Applied to files:
packages/opencode/test/plugin/workspace-adaptor.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Use the `init` option in `tmpdir` to define custom setup functions that can return extra data accessible via `tmp.extra`, and use the `dispose` option for custom cleanup logic.
Applied to files:
packages/opencode/test/plugin/workspace-adaptor.test.ts
📚 Learning: 2026-04-20T17:03:37.710Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 73
File: packages/opencode/src/cli/cmd/tui/context/sync.tsx:486-489
Timestamp: 2026-04-20T17:03:37.710Z
Learning: In Astro-Han/pawwork (`packages/opencode/src/cli/cmd/tui/context/sync.tsx`), `sync.ready` returning `true` when `process.env.OPENCODE_FAST_BOOT` is set is intentional. The plugin-facing data properties `state.config` (initialized to `{}`) and `state.provider` (initialized to `[]`) expose safe-empty defaults, so they are safe to access before bootstrap completes. Do not flag these as needing null-guards or conditional patterns to match `vcs` — the difference is intentional because `vcs` starts as `undefined` while the others have initialized defaults. Changing this would alter the plugin API contract without a concrete failing case.
Applied to files:
packages/opencode/test/plugin/workspace-adaptor.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Use `testEffect(...)` from `test/lib/effect.ts` for tests that exercise Effect services or Effect-based workflows.
Applied to files:
packages/opencode/test/plugin/workspace-adaptor.test.tspackages/opencode/src/control-plane/workspace.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Import test utilities from `../fixtures` instead of `playwright/test`
Applied to files:
packages/opencode/test/plugin/workspace-adaptor.test.ts
📚 Learning: 2026-04-22T08:49:44.563Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 126
File: packages/desktop-electron/src/main/index-sidecar-source.test.ts:3-11
Timestamp: 2026-04-22T08:49:44.563Z
Learning: In `packages/desktop-electron/src/main/index-sidecar-source.test.ts` (Astro-Han/pawwork), the test intentionally uses `expect(source).toContain` / `expect(source).not.toContain` string matching against the raw `index.ts` source text as a lightweight sidecar contract guard. The maintainer has explicitly chosen not to introduce an AST parser (e.g., `babel/parser` or acorn) for this purpose. Do not flag these string-based assertions as fragile or suggest converting them to AST-based matching.
Applied to files:
packages/opencode/test/plugin/workspace-adaptor.test.ts
📚 Learning: 2026-04-20T14:36:21.274Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:21.274Z
Learning: Applies to packages/opencode/**/*.ts : Prefer `FileSystem.FileSystem` instead of raw `fs/promises` for effectful file I/O in Effect services
Applied to files:
packages/opencode/test/plugin/workspace-adaptor.test.tspackages/opencode/src/control-plane/workspace.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Use fixture-managed cleanup with `withSession(sdk, title, callback)` for temporary sessions instead of calling `sdk.session.delete(...)` directly
Applied to files:
packages/opencode/test/plugin/workspace-adaptor.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Define `const it = testEffect(...)` near the top of the test file and keep the test body inside `Effect.gen(function* () { ... })`. Yield services directly with `yield* MyService.Service` or `yield* MyTool`.
Applied to files:
packages/opencode/test/plugin/workspace-adaptor.test.tspackages/opencode/src/control-plane/workspace.ts
📚 Learning: 2026-04-20T14:36:04.099Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.099Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Prefer the `project` fixture for tests that need a dedicated project with LLM mocking
Applied to files:
packages/opencode/test/plugin/workspace-adaptor.test.ts
📚 Learning: 2026-04-22T09:32:52.535Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 126
File: packages/ui/src/theme/context.tsx:11-16
Timestamp: 2026-04-22T09:32:52.535Z
Learning: In Astro-Han/pawwork (`packages/ui/src/theme/context.tsx` and related files), the renaming of localStorage theme keys from `opencode-*` to `pawwork-*` (THEME_ID, COLOR_SCHEME, THEME_CSS_LIGHT, THEME_CSS_DARK) is intentional and should NOT include a migration path from the old keys. Migrating would re-couple PawWork and OpenCode browser storage namespaces, which the PR is explicitly designed to avoid. A reset to the PawWork default theme on upgrade is acceptable by design.
Applied to files:
packages/opencode/test/plugin/workspace-adaptor.test.ts
📚 Learning: 2026-04-21T16:57:22.813Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 102
File: packages/opencode/src/config/agent.ts:108-119
Timestamp: 2026-04-21T16:57:22.813Z
Learning: In `packages/opencode/src/config/agent.ts` (Astro-Han/pawwork), `ConfigPermission.Info` only accepts permission objects or the three action strings `"ask"`, `"allow"`, `"deny"`, and transforms those action strings into `{ "*": action }` before `normalize()` runs. By the time `normalize()` is reached, `configuredPermission` is always either `undefined` or a `Record<string, Rule>` — never a raw arbitrary string. The `Object.assign(permission, configuredPermission)` pattern is therefore safe. Do not flag it as corrupting string permission references.
Applied to files:
packages/opencode/test/plugin/workspace-adaptor.test.ts
📚 Learning: 2026-04-20T14:21:51.047Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 71
File: packages/app/src/components/session/session-status-connections.tsx:146-147
Timestamp: 2026-04-20T14:21:51.047Z
Learning: In the Astro-Han/pawwork repository (SolidJS app), `sync.data.config` is always initialized to `{}` at `packages/app/src/context/global-sync.tsx` line 71 and is never `undefined` at runtime. Non-optional property access like `sync.data.config.plugin` is intentional and consistent with the pattern used in `packages/app/src/components/status-popover-body.tsx` line 243. Do not flag `sync.data.config.plugin` as needing optional chaining.
Applied to files:
packages/opencode/test/plugin/workspace-adaptor.test.ts
📚 Learning: 2026-04-21T13:45:41.773Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 99
File: packages/desktop-electron/src/renderer/i18n/index.ts:30-35
Timestamp: 2026-04-21T13:45:41.773Z
Learning: In Astro-Han/pawwork, the locale normalization helpers in `packages/app/src/context/language.tsx` (`normalizeLocale`) and `packages/desktop-electron/src/renderer/i18n/index.ts` (`parseLocale`) are intentionally kept separate and have different fallback shapes: `normalizeLocale` always returns a concrete `Locale` (falling back to `"en"`), while `parseLocale` returns `Locale | null` so the desktop shell can decide whether to fall back to browser detection. Do not suggest extracting a shared normalization helper across these two runtimes.
Applied to files:
packages/opencode/test/plugin/workspace-adaptor.test.ts
📚 Learning: 2026-04-21T16:57:20.257Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 102
File: packages/opencode/src/config/command.ts:23-29
Timestamp: 2026-04-21T16:57:20.257Z
Learning: In Astro-Han/pawwork (`packages/opencode/src/config/`), `Schema.Struct` and `Schema.Class` are both valid and intentionally used patterns across config modules (e.g. `formatter.ts`, `provider.ts`, `permission.ts`, `lsp.ts`, `config.ts`, `keybinds.ts`, `command.ts`). Do not flag `Schema.Struct` usage in config schemas as needing conversion to `Schema.Class` — the choice is driven by upstream alignment and local context, not inconsistency.
Applied to files:
packages/opencode/test/plugin/workspace-adaptor.test.ts
📚 Learning: 2026-04-20T14:36:31.017Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/test/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:31.017Z
Learning: Applies to packages/opencode/test/**/*.test.{ts,tsx} : Use `it.effect(...)` when the test should run with `TestClock` and `TestConsole`. Use `it.live(...)` when the test depends on real time, filesystem mtimes, child processes, git, locks, or other live OS behavior.
Applied to files:
packages/opencode/test/plugin/workspace-adaptor.test.tspackages/opencode/src/control-plane/workspace.ts
📚 Learning: 2026-04-20T14:36:21.274Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:21.274Z
Learning: Applies to packages/opencode/**/*.ts : Use `Effect.cached` when multiple concurrent callers should share a single in-flight computation rather than storing `Fiber | undefined` or `Promise | undefined` manually
Applied to files:
packages/opencode/src/control-plane/workspace.ts
📚 Learning: 2026-04-20T14:36:21.274Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:21.274Z
Learning: Applies to packages/opencode/**/*.ts : Use `Effect.gen(function* () { ... })` for Effect composition
Applied to files:
packages/opencode/src/control-plane/workspace.ts
📚 Learning: 2026-04-20T14:36:21.274Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:21.274Z
Learning: Applies to packages/opencode/**/*.ts : Prefer `Path.Path`, `Config`, `Clock`, and `DateTime` services when those concerns are already inside Effect code
Applied to files:
packages/opencode/src/control-plane/workspace.ts
📚 Learning: 2026-04-20T14:36:21.274Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:21.274Z
Learning: Applies to packages/opencode/**/*.ts : For background loops or scheduled tasks, use `Effect.repeat` or `Effect.schedule` with `Effect.forkScoped` in the layer definition
Applied to files:
packages/opencode/src/control-plane/workspace.ts
📚 Learning: 2026-04-20T14:36:21.274Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:21.274Z
Learning: Applies to packages/opencode/**/*.ts : Use `Effect.fn("Domain.method")` for named/traced effects and `Effect.fnUntraced` for internal helpers; these accept pipeable operators as extra arguments to avoid unnecessary outer `.pipe()` wrappers
Applied to files:
packages/opencode/src/control-plane/workspace.ts
📚 Learning: 2026-04-20T14:36:21.274Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/opencode/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:21.274Z
Learning: Applies to packages/opencode/**/*.ts : Use `Effect.callback` for callback-based APIs
Applied to files:
packages/opencode/src/control-plane/workspace.ts
🔇 Additional comments (7)
packages/opencode/src/control-plane/types.ts (1)
28-30: LGTM!The optional
auth.providersfield correctly implements the explicit opt-in mechanism for scoped auth forwarding. The type aligns with the correspondingWorkspaceAdaptordefinition in the plugin package.packages/plugin/src/index.ts (2)
51-53: LGTM!The public
WorkspaceAdaptor.authfield mirrors the internalAdaptortype, maintaining consistency across the package boundary.
55-62: LGTM!The JSDoc clearly communicates the opt-in semantics and least-privilege behavior: adaptors must explicitly request providers, and only those entries are forwarded.
packages/opencode/src/control-plane/workspace.ts (2)
208-223: LGTM!The scoped auth implementation correctly:
- Deduplicates provider names with
new Set()- Short-circuits when no providers are requested
- Filters to only the requested providers that have auth entries
- Uses
Effect.genfor Effect composition as per coding guidelines
227-228: LGTM!The conditional correctly ensures
OPENCODE_AUTH_CONTENTis only set when both:
scopedAuthis defined (providers were requested)- At least one requested provider has an auth entry
This implements the least-privilege principle from the PR objectives.
packages/opencode/test/plugin/workspace-adaptor.test.ts (2)
122-146: LGTM!The
withAuthFilehelper correctly manages auth file state isolation for tests:
- Handles missing auth file (ENOENT) as expected
- Restores original state on cleanup
- Uses the established
Filesystem.write+node:fs/promises unlinkpattern per repository conventionBased on learnings: "For pawwork tests under packages/opencode/test/**, auth.json teardown may intentionally combine
Filesystem.writewithnode:fs/promisesunlinkfor cleanup."
189-189: LGTM!Correctly updated to assert
OPENCODE_AUTH_CONTENTis absent when the adaptor doesn't specifyauth.providers. This aligns with the new opt-in semantics.
b6cf198 to
3b17922
Compare
Summary
auth.providersopt-in on workspace adaptors before forwardingOPENCODE_AUTH_CONTENTWhy
Issue #173 tracks the follow-up from #155: third-party or remote workspace adaptors should not receive unrelated credentials by default. This change keeps the existing env bridge for adaptors that truly need auth, but narrows the boundary to an explicit provider allowlist.
Related Issue
Closes #173
How To Verify
bun test test/plugin/workspace-adaptor.test.tsbun run typecheckinpackages/opencodebun run typecheckinpackages/pluginbun turbo typecheckgit diff --checkScreenshots or Recordings
Not applicable. No visible UI changes.
Checklist
dev, and my PR title and commit messages use Conventional Commits in EnglishSummary by CodeRabbit
New Features
Documentation
Tests