opencode-polkit 0.1.1 → 0.1.3

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/README.md CHANGED
@@ -4,8 +4,10 @@ Redirect `sudo`/`doas` to `pkexec` in [OpenCode](https://opencode.ai).
4
4
  Triggers the system's native polkit authentication dialog (KDE, GNOME, etc.)
5
5
  instead of requiring a terminal for password input.
6
6
 
7
- When polkit is unavailable, privilege escalation commands are blocked with a
8
- clear error message.
7
+ Like CachyOS Hello, the plugin does not check for a polkit agent up front:
8
+ `sudo` is always redirected to `pkexec` at execution time, and polkitd routes
9
+ the request to whatever agent is currently registered. If no agent is
10
+ available, `pkexec` fails with its own clear error message.
9
11
 
10
12
  ## Install
11
13
 
@@ -21,15 +23,23 @@ Or add to `opencode.json` / `~/.config/opencode/opencode.jsonc`:
21
23
  }
22
24
  ```
23
25
 
26
+ For local development, point opencode at the project directory instead:
27
+
28
+ ```json
29
+ {
30
+ "plugin": ["/path/to/opencode-polkit"]
31
+ }
32
+ ```
33
+
24
34
  ## Behavior
25
35
 
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 |
36
+ | Command | result |
37
+ |-----------------|--------------------------------------------|
38
+ | `sudo xxx` | redirects to `pkexec xxx` |
39
+ | `doas xxx` | redirects to `pkexec xxx` |
40
+ | `pkexec xxx` | passes through |
41
+ | `sudoedit` | blocked |
42
+ | `visudo` | blocked |
33
43
 
34
44
  When a user denies the polkit authentication dialog, a clear error message is shown.
35
45
 
package/dist/index.js CHANGED
@@ -1,77 +1,47 @@
1
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
2
  const translations = {
11
3
  en: {
12
4
  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
5
  polkitDenied: "Polkit authentication denied by user",
16
6
  },
17
7
  zh: {
18
8
  blocked: "权限提升命令已被插件拦截",
19
- noPolkit: "sudo/doas 已被拦截:未检测到 polkit agent,无法安全提权",
20
- noPolkitPkexec: "pkexec 不可用:未检测到 polkit agent",
21
9
  polkitDenied: "Polkit 认证已被用户拒绝",
22
10
  },
23
11
  ja: {
24
12
  blocked: "特権昇格コマンドはプラグインによりブロックされました",
25
- noPolkit: "sudo/doas がブロックされました:polkit エージェントが見つからないため、安全に昇格できません",
26
- noPolkitPkexec: "pkexec は利用できません:polkit エージェントが見つかりません",
27
13
  polkitDenied: "Polkit 認証がユーザーによって拒否されました",
28
14
  },
29
15
  ko: {
30
16
  blocked: "권한 상승 명령이 플러그인에 의해 차단되었습니다",
31
- noPolkit: "sudo/doas 차단됨: polkit 에이전트가 감지되지 않아 안전하게 권한 상승할 수 없습니다",
32
- noPolkitPkexec: "pkexec 사용 불가: polkit 에이전트가 감지되지 않았습니다",
33
17
  polkitDenied: "Polkit 인증이 사용자에 의해 거부되었습니다",
34
18
  },
35
19
  de: {
36
20
  blocked: "Berechtigungseskalation vom Plugin blockiert",
37
- noPolkit: "sudo/doas blockiert: kein polkit-Agent erkannt, sichere Eskalation nicht möglich",
38
- noPolkitPkexec: "pkexec nicht verfügbar: kein polkit-Agent erkannt",
39
21
  polkitDenied: "Polkit-Authentifizierung vom Benutzer abgelehnt",
40
22
  },
41
23
  fr: {
42
24
  blocked: "Commande d'élévation de privilèges bloquée par le plugin",
43
- noPolkit: "sudo/doas bloqué : aucun agent polkit détecté, élévation impossible",
44
- noPolkitPkexec: "pkexec indisponible : aucun agent polkit détecté",
45
25
  polkitDenied: "Authentification polkit refusée par l'utilisateur",
46
26
  },
47
27
  es: {
48
28
  blocked: "Comando de elevación de privilegios bloqueado por el plugin",
49
- noPolkit: "sudo/doas bloqueado: no se detectó agente polkit, no se puede elevar de forma segura",
50
- noPolkitPkexec: "pkexec no disponible: no se detectó agente polkit",
51
29
  polkitDenied: "Autenticación polkit denegada por el usuario",
52
30
  },
53
31
  pt: {
54
32
  blocked: "Comando de elevação de privilégios bloqueado pelo plugin",
55
- noPolkit: "sudo/doas bloqueado: nenhum agente polkit detectado, não é possível elevar com segurança",
56
- noPolkitPkexec: "pkexec indisponível: nenhum agente polkit detectado",
57
33
  polkitDenied: "Autenticação polkit negada pelo usuário",
58
34
  },
59
35
  ru: {
60
36
  blocked: "Команда повышения привилегий заблокирована плагином",
61
- noPolkit: "sudo/doas заблокирован: не обнаружен polkit-агент, невозможно безопасно повысить привилегии",
62
- noPolkitPkexec: "pkexec недоступен: не обнаружен polkit-агент",
63
37
  polkitDenied: "Аутентификация polkit отклонена пользователем",
64
38
  },
65
39
  tr: {
66
40
  blocked: "Yetki yükseltme komutu eklenti tarafından engellendi",
67
- noPolkit: "sudo/doas engellendi: polkit aracısı algılanmadı, güvenli şekilde yetki yükseltilemez",
68
- noPolkitPkexec: "pkexec kullanılamıyor: polkit aracısı algılanmadı",
69
41
  polkitDenied: "Polkit kimlik doğrulaması kullanıcı tarafından reddedildi",
70
42
  },
71
43
  uk: {
72
44
  blocked: "Команду підвищення привілеїв заблоковано плагіном",
73
- noPolkit: "sudo/doas заблоковано: не виявлено агента polkit, неможливо безпечно підвищити привілеї",
74
- noPolkitPkexec: "pkexec недоступний: не виявлено агента polkit",
75
45
  polkitDenied: "Автентифікацію polkit відхилено користувачем",
76
46
  },
77
47
  };
@@ -85,30 +55,8 @@ function detectLocale() {
85
55
  return "en";
86
56
  }
87
57
  const MSG = translations[detectLocale()] ?? translations.en;
88
- function polkitAvailable() {
89
- try {
90
- if (process.env.DBUS_SESSION_BUS_ADDRESS) {
91
- const proc = Bun.spawnSync(["busctl", "--user", "list"], {
92
- stdio: ["ignore", "pipe", "pipe"],
93
- });
94
- if (proc.exitCode === 0 && /\bpolkit\b/i.test(new TextDecoder().decode(proc.stdout))) {
95
- return true;
96
- }
97
- }
98
- }
99
- catch { /* fall through */ }
100
- try {
101
- const proc = Bun.spawnSync(["pgrep", "-x", ...POLKIT_AGENTS], {
102
- stdio: ["ignore", "pipe", "pipe"],
103
- });
104
- return proc.exitCode === 0;
105
- }
106
- catch {
107
- return false;
108
- }
109
- }
110
- const hasPolkit = polkitAvailable();
111
58
  export const PolkitPlugin = async (_input) => {
59
+ const deniedCommands = new Set();
112
60
  return {
113
61
  "tool.execute.before": async (hookInput, hookOutput) => {
114
62
  if (hookInput.tool !== "bash")
@@ -116,17 +64,15 @@ export const PolkitPlugin = async (_input) => {
116
64
  const command = hookOutput?.args?.command ?? "";
117
65
  if (!MATCH.test(command))
118
66
  return;
67
+ if (deniedCommands.has(command)) {
68
+ throw new Error(MSG.polkitDenied);
69
+ }
119
70
  if (/^pkexec(?![-\/.\w])/.test(command.trim())) {
120
- if (!hasPolkit)
121
- throw new Error(MSG.noPolkitPkexec);
122
71
  return;
123
72
  }
124
73
  if (/(?<![-\/.\w])(sudoedit|visudo)(?![-\/.\w])/.test(command)) {
125
74
  throw new Error(MSG.blocked);
126
75
  }
127
- if (!hasPolkit) {
128
- throw new Error(MSG.noPolkit);
129
- }
130
76
  hookOutput.args.command = command.replace(/(?<![-\/.\w])(sudo|doas)(?![-\/.\w])/, "pkexec");
131
77
  },
132
78
  "tool.execute.after": async (hookInput, hookOutput) => {
@@ -135,11 +81,12 @@ export const PolkitPlugin = async (_input) => {
135
81
  const command = hookInput.args?.command ?? "";
136
82
  if (!MATCH.test(command))
137
83
  return;
84
+ const originalCommand = command.replace(/(?<![-\/.\w])pkexec(?![-\/.\w])/, "sudo");
138
85
  if (/\bNot authorized\b/.test(hookOutput.output) ||
139
86
  /\bError executing command as another user\b/.test(hookOutput.output)) {
87
+ deniedCommands.add(originalCommand);
140
88
  throw new Error(MSG.polkitDenied);
141
89
  }
142
90
  },
143
91
  };
144
92
  };
145
- //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-polkit",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Redirect sudo/doas to pkexec in OpenCode — uses system polkit agent for native auth dialogs",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -17,8 +17,8 @@
17
17
  "LICENSE"
18
18
  ],
19
19
  "scripts": {
20
- "build": "tsc",
21
- "prepublishOnly": "npm run build"
20
+ "build": "deno task build",
21
+ "check": "deno task check"
22
22
  },
23
23
  "engines": {
24
24
  "opencode": ">=1.0.0"
package/dist/index.d.ts DELETED
@@ -1,3 +0,0 @@
1
- import type { Plugin } from "@opencode-ai/plugin";
2
- export declare const PolkitPlugin: Plugin;
3
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAe,MAAM,qBAAqB,CAAA;AA2H9D,eAAO,MAAM,YAAY,EAAE,MAoC1B,CAAA"}
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}