opencode-polkit 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 opencode-polkit contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,43 @@
1
+ # opencode-polkit
2
+
3
+ Redirect `sudo`/`doas` to `pkexec` in [OpenCode](https://opencode.ai).
4
+ Triggers the system's native polkit authentication dialog (KDE, GNOME, etc.)
5
+ instead of requiring a terminal for password input.
6
+
7
+ When polkit is unavailable, privilege escalation commands are blocked with a
8
+ clear error message.
9
+
10
+ ## Install
11
+
12
+ ```sh
13
+ opencode plugin opencode-polkit
14
+ ```
15
+
16
+ Or add to `opencode.json` / `~/.config/opencode/opencode.jsonc`:
17
+
18
+ ```json
19
+ {
20
+ "plugin": ["opencode-polkit"]
21
+ }
22
+ ```
23
+
24
+ ## Behavior
25
+
26
+ | Command | polkit available | polkit unavailable |
27
+ |-----------------|--------------------------------|----------------------|
28
+ | `sudo xxx` | redirects to `pkexec xxx` | blocked with error |
29
+ | `doas xxx` | redirects to `pkexec xxx` | blocked with error |
30
+ | `pkexec xxx` | passes through | blocked with error |
31
+ | `sudoedit` | blocked | blocked |
32
+ | `visudo` | blocked | blocked |
33
+
34
+ ## i18n
35
+
36
+ Messages adapt to `$LC_MESSAGES` / `$LANG`. Currently supports:
37
+ en, zh, ja, ko, de, fr, es, pt, ru, tr, uk.
38
+
39
+ PRs welcome for additional translations.
40
+
41
+ ## License
42
+
43
+ MIT
@@ -0,0 +1,3 @@
1
+ import type { Plugin } from "@opencode-ai/plugin";
2
+ export declare const PolkitPlugin: Plugin;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAe,MAAM,qBAAqB,CAAA;AA+G9D,eAAO,MAAM,YAAY,EAAE,MA0B1B,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,123 @@
1
+ const MATCH = /(?<![-\/.\w])(sudo|pkexec|doas|sudoedit|visudo)(?![-\/.\w])/i;
2
+ const POLKIT_AGENTS = [
3
+ "polkit-kde-authentication-agent-1",
4
+ "polkit-gnome-authentication-agent-1",
5
+ "lxqt-policykit-agent",
6
+ "mate-polkit",
7
+ "xfce-polkit",
8
+ "dde-polkit-agent",
9
+ ];
10
+ const translations = {
11
+ en: {
12
+ blocked: "Privilege escalation command blocked by plugin",
13
+ noPolkit: "sudo/doas blocked: no polkit agent detected, cannot escalate safely",
14
+ noPolkitPkexec: "pkexec unavailable: no polkit agent detected",
15
+ },
16
+ zh: {
17
+ blocked: "权限提升命令已被插件拦截",
18
+ noPolkit: "sudo/doas 已被拦截:未检测到 polkit agent,无法安全提权",
19
+ noPolkitPkexec: "pkexec 不可用:未检测到 polkit agent",
20
+ },
21
+ ja: {
22
+ blocked: "特権昇格コマンドはプラグインによりブロックされました",
23
+ noPolkit: "sudo/doas がブロックされました:polkit エージェントが見つからないため、安全に昇格できません",
24
+ noPolkitPkexec: "pkexec は利用できません:polkit エージェントが見つかりません",
25
+ },
26
+ ko: {
27
+ blocked: "권한 상승 명령이 플러그인에 의해 차단되었습니다",
28
+ noPolkit: "sudo/doas 차단됨: polkit 에이전트가 감지되지 않아 안전하게 권한 상승할 수 없습니다",
29
+ noPolkitPkexec: "pkexec 사용 불가: polkit 에이전트가 감지되지 않았습니다",
30
+ },
31
+ de: {
32
+ blocked: "Berechtigungseskalation vom Plugin blockiert",
33
+ noPolkit: "sudo/doas blockiert: kein polkit-Agent erkannt, sichere Eskalation nicht möglich",
34
+ noPolkitPkexec: "pkexec nicht verfügbar: kein polkit-Agent erkannt",
35
+ },
36
+ fr: {
37
+ blocked: "Commande d'élévation de privilèges bloquée par le plugin",
38
+ noPolkit: "sudo/doas bloqué : aucun agent polkit détecté, élévation impossible",
39
+ noPolkitPkexec: "pkexec indisponible : aucun agent polkit détecté",
40
+ },
41
+ es: {
42
+ blocked: "Comando de elevación de privilegios bloqueado por el plugin",
43
+ noPolkit: "sudo/doas bloqueado: no se detectó agente polkit, no se puede elevar de forma segura",
44
+ noPolkitPkexec: "pkexec no disponible: no se detectó agente polkit",
45
+ },
46
+ pt: {
47
+ blocked: "Comando de elevação de privilégios bloqueado pelo plugin",
48
+ noPolkit: "sudo/doas bloqueado: nenhum agente polkit detectado, não é possível elevar com segurança",
49
+ noPolkitPkexec: "pkexec indisponível: nenhum agente polkit detectado",
50
+ },
51
+ ru: {
52
+ blocked: "Команда повышения привилегий заблокирована плагином",
53
+ noPolkit: "sudo/doas заблокирован: не обнаружен polkit-агент, невозможно безопасно повысить привилегии",
54
+ noPolkitPkexec: "pkexec недоступен: не обнаружен polkit-агент",
55
+ },
56
+ tr: {
57
+ blocked: "Yetki yükseltme komutu eklenti tarafından engellendi",
58
+ noPolkit: "sudo/doas engellendi: polkit aracısı algılanmadı, güvenli şekilde yetki yükseltilemez",
59
+ noPolkitPkexec: "pkexec kullanılamıyor: polkit aracısı algılanmadı",
60
+ },
61
+ uk: {
62
+ blocked: "Команду підвищення привілеїв заблоковано плагіном",
63
+ noPolkit: "sudo/doas заблоковано: не виявлено агента polkit, неможливо безпечно підвищити привілеї",
64
+ noPolkitPkexec: "pkexec недоступний: не виявлено агента polkit",
65
+ },
66
+ };
67
+ function detectLocale() {
68
+ const raw = process.env.LC_MESSAGES || process.env.LANG || "en";
69
+ const tag = raw.split(".")[0].replace(/_/g, "-").toLowerCase();
70
+ for (const prefix of ["zh", "ja", "ko", "de", "fr", "es", "pt", "ru", "tr", "uk"]) {
71
+ if (tag.startsWith(prefix))
72
+ return prefix;
73
+ }
74
+ return "en";
75
+ }
76
+ const MSG = translations[detectLocale()] ?? translations.en;
77
+ function polkitAvailable() {
78
+ try {
79
+ if (process.env.DBUS_SESSION_BUS_ADDRESS) {
80
+ const proc = Bun.spawnSync(["busctl", "--user", "list"], {
81
+ stdio: ["ignore", "pipe", "pipe"],
82
+ });
83
+ if (proc.exitCode === 0 && /\bpolkit\b/i.test(new TextDecoder().decode(proc.stdout))) {
84
+ return true;
85
+ }
86
+ }
87
+ }
88
+ catch { /* fall through */ }
89
+ try {
90
+ const proc = Bun.spawnSync(["pgrep", "-x", ...POLKIT_AGENTS], {
91
+ stdio: ["ignore", "pipe", "pipe"],
92
+ });
93
+ return proc.exitCode === 0;
94
+ }
95
+ catch {
96
+ return false;
97
+ }
98
+ }
99
+ const hasPolkit = polkitAvailable();
100
+ export const PolkitPlugin = async (_input) => {
101
+ return {
102
+ "tool.execute.before": async (hookInput, hookOutput) => {
103
+ if (hookInput.tool !== "bash")
104
+ return;
105
+ const command = hookOutput?.args?.command ?? "";
106
+ if (!MATCH.test(command))
107
+ return;
108
+ if (/^pkexec(?![-\/.\w])/.test(command.trim())) {
109
+ if (!hasPolkit)
110
+ throw new Error(MSG.noPolkitPkexec);
111
+ return;
112
+ }
113
+ if (/(?<![-\/.\w])(sudoedit|visudo)(?![-\/.\w])/.test(command)) {
114
+ throw new Error(MSG.blocked);
115
+ }
116
+ if (!hasPolkit) {
117
+ throw new Error(MSG.noPolkit);
118
+ }
119
+ hookOutput.args.command = command.replace(/(?<![-\/.\w])(sudo|doas)(?![-\/.\w])/, "pkexec");
120
+ },
121
+ };
122
+ };
123
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "opencode-polkit",
3
+ "version": "0.1.0",
4
+ "description": "Redirect sudo/doas to pkexec in OpenCode — uses system polkit agent for native auth dialogs",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist",
16
+ "README.md",
17
+ "LICENSE"
18
+ ],
19
+ "scripts": {
20
+ "build": "tsc",
21
+ "prepublishOnly": "npm run build"
22
+ },
23
+ "engines": {
24
+ "opencode": ">=1.0.0"
25
+ },
26
+ "peerDependencies": {
27
+ "@opencode-ai/plugin": ">=1.0.0"
28
+ },
29
+ "devDependencies": {
30
+ "@opencode-ai/plugin": "^1.0.0",
31
+ "bun-types": "^1.2.0",
32
+ "typescript": "^5.5.0"
33
+ },
34
+ "keywords": ["opencode-plugin", "sudo", "pkexec", "polkit", "security"],
35
+ "license": "MIT",
36
+ "repository": {
37
+ "type": "git",
38
+ "url": "git+https://github.com/lenitain/opencode-polkit.git"
39
+ },
40
+ "bugs": {
41
+ "url": "https://github.com/lenitain/opencode-polkit/issues"
42
+ }
43
+ }