Skip to content

Add OpenCode (opencode) permissions support, docs, and tests#1462

Merged
dyoshikawa merged 1 commit intomainfrom
codex/work-on-issue-1416
Apr 12, 2026
Merged

Add OpenCode (opencode) permissions support, docs, and tests#1462
dyoshikawa merged 1 commit intomainfrom
codex/work-on-issue-1416

Conversation

@dyoshikawa
Copy link
Copy Markdown
Owner

Motivation

  • Add support for managing permissions for OpenCode (opencode) so rulesync can generate and import the permission object into opencode.json/opencode.jsonc in both project and global modes.

Description

  • Add OpencodePermissions implementation to parse, validate, normalize, merge from .rulesync/permissions.json, and emit permission into opencode.json/opencode.jsonc while preserving other OpenCode config fields.
  • Integrate opencode into the permissions processing pipeline by registering it in permissions-processor, propagating a global flag, and updating ToolPermissions types to accept global options.
  • Update generation/import flows in generate.ts and import.ts to consult supported targets per global mode and to pass global to PermissionsProcessor.
  • Update documentation and README to mark OpenCode as supporting permissions and to document where the permissions are generated (opencode.json / .config/opencode/opencode.json).
  • Add unit and e2e tests covering OpencodePermissions, updated PermissionsProcessor behavior, and end-to-end generate/import scenarios (src/features/permissions/opencode-permissions.test.ts, src/features/permissions/permissions-processor.test.ts, and src/e2e/e2e-permissions.spec.ts).

Testing

  • Ran unit tests with Vitest including the new opencode-permissions and updated permissions-processor specs, and they completed successfully.
  • Ran end-to-end permissions tests (src/e2e/e2e-permissions.spec.ts) covering project and global generate/import scenarios, and they passed.
  • Updated existing generate/import unit tests to account for opencode target behavior and verified the test suite succeeds.

Codex Task

Copilot AI review requested due to automatic review settings April 12, 2026 13:16
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 OpencodePermissions and registers opencode in the permissions processing pipeline (including global-mode targeting).
  • Updates generate/import flows to pass global through 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 opencode in 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");
});
});
@dyoshikawa dyoshikawa merged commit 332f857 into main Apr 12, 2026
14 checks passed
@dyoshikawa dyoshikawa deleted the codex/work-on-issue-1416 branch April 12, 2026 14:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants