Add OpenCode (opencode) permissions support, docs, and tests#1462
Merged
dyoshikawa merged 1 commit intomainfrom Apr 12, 2026
Merged
Add OpenCode (opencode) permissions support, docs, and tests#1462dyoshikawa merged 1 commit intomainfrom
dyoshikawa merged 1 commit intomainfrom
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Adds OpenCode (opencode) as a supported target for the permissions feature so rulesync can generate/import the permission object into opencode.json / opencode.jsonc in both project and global modes, and updates docs/tests accordingly.
Changes:
- Introduces
OpencodePermissionsand registersopencodein the permissions processing pipeline (including global-mode targeting). - Updates
generate/importflows to passglobalthrough permissions target resolution and processor construction. - Adds unit + e2e coverage and updates supported-tools/file-format documentation to reflect OpenCode permissions support.
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/lib/import.ts | Enables permissions import target resolution in global mode and passes global into PermissionsProcessor. |
| src/lib/import.test.ts | Updates mocks/expectations around permissions import target resolution with global. |
| src/lib/generate.ts | Enables permissions generation in global mode by selecting supported targets and passing global into PermissionsProcessor. |
| src/lib/generate.test.ts | Updates mocks/expectations for permissions generation target selection with global. |
| src/features/permissions/tool-permissions.ts | Extends permissions-related param types and getSettablePaths signature to accept global. |
| src/features/permissions/permissions-processor.ts | Registers opencode permissions, adds global-aware target filtering, and propagates global through load/convert flows. |
| src/features/permissions/permissions-processor.test.ts | Expands target expectations and adds a load test for opencode.jsonc. |
| src/features/permissions/opencode-permissions.ts | New implementation to read/emit OpenCode permission while preserving other config fields. |
| src/features/permissions/opencode-permissions.test.ts | Unit tests for path resolution, config merge behavior, and global-mode normalization. |
| src/e2e/e2e-permissions.spec.ts | E2E tests for opencode permissions generation/import, plus global-mode generation. |
| skills/rulesync/supported-tools.md | Marks OpenCode as supporting permissions. |
| skills/rulesync/file-formats.md | Documents where OpenCode permissions are generated in project/global modes. |
| README.md | Marks OpenCode as supporting permissions. |
| docs/reference/supported-tools.md | Marks OpenCode as supporting permissions. |
| docs/reference/file-formats.md | Documents where OpenCode permissions are generated in project/global modes. |
Comments suppressed due to low confidence (2)
src/lib/generate.test.ts:589
- This test name is now misleading: in global mode permissions generation isn’t inherently skipped anymore (opencode supports it); this case is specifically “skip because the selected target(s) aren’t supported in global mode”. Consider renaming the test (or adding an additional assertion that covers global opencode generation) to match the new behavior.
it("should skip permissions generation in global mode", async () => {
mockConfig.getFeatures.mockReturnValue(["permissions"]);
mockConfig.getGlobal.mockReturnValue(true);
vi.mocked(PermissionsProcessor.getToolTargets).mockImplementation((params) =>
params?.global ? ["opencode"] : ["claudecode"],
);
const result = await generate({ logger, config: mockConfig as never });
expect(result.permissionsCount).toBe(0);
expect(PermissionsProcessor).not.toHaveBeenCalled();
});
src/lib/import.test.ts:699
- This test name is now misleading: global-mode permissions import is no longer globally disabled; this case is specifically “skip because claudecode isn’t a supported permissions target in global mode”. Consider renaming the test (and optionally add a new test for importing
opencodein global mode).
it("should skip permissions import in global mode", async () => {
mockConfig.getFeatures.mockReturnValue(["permissions"]);
mockConfig.getGlobal.mockReturnValue(true);
vi.mocked(PermissionsProcessor.getToolTargets).mockImplementation((params) =>
params?.global ? ["opencode"] : ["claudecode"],
);
const result = await importFromTool({
logger,
config: mockConfig as never,
tool: "claudecode",
});
expect(result.permissionsCount).toBe(0);
expect(PermissionsProcessor).not.toHaveBeenCalled();
});
Comment on lines
+76
to
+83
| const parsed = parseJsonc(fileContent ?? "{}"); | ||
| const nextJson = { ...parsed, permission: parsed.permission ?? {} }; | ||
|
|
||
| return new OpencodePermissions({ | ||
| baseDir, | ||
| relativeDirPath: basePaths.relativeDirPath, | ||
| relativeFilePath, | ||
| fileContent: JSON.stringify(nextJson, null, 2), |
Comment on lines
+110
to
+111
| const nextJson = { | ||
| ...parsed, |
| ); | ||
| expect(generated.permission.bash["git status *"]).toBe("allow"); | ||
| }); | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
opencode) so rulesync can generate and import thepermissionobject intoopencode.json/opencode.jsoncin both project and global modes.Description
OpencodePermissionsimplementation to parse, validate, normalize, merge from.rulesync/permissions.json, and emitpermissionintoopencode.json/opencode.jsoncwhile preserving other OpenCode config fields.opencodeinto the permissions processing pipeline by registering it inpermissions-processor, propagating aglobalflag, and updatingToolPermissionstypes to acceptglobaloptions.generate.tsandimport.tsto consult supported targets perglobalmode and to passglobaltoPermissionsProcessor.permissionsand to document where the permissions are generated (opencode.json/.config/opencode/opencode.json).OpencodePermissions, updatedPermissionsProcessorbehavior, and end-to-end generate/import scenarios (src/features/permissions/opencode-permissions.test.ts,src/features/permissions/permissions-processor.test.ts, andsrc/e2e/e2e-permissions.spec.ts).Testing
opencode-permissionsand updatedpermissions-processorspecs, and they completed successfully.src/e2e/e2e-permissions.spec.ts) covering project and global generate/import scenarios, and they passed.generate/importunit tests to account foropencodetarget behavior and verified the test suite succeeds.Codex Task