@geekbeer/minion 2.57.0 → 2.59.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.
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Sudoers endpoint
3
+ *
4
+ * Endpoints:
5
+ * - GET /api/sudoers - List sudo permissions for the current user
6
+ */
7
+
8
+ const { exec } = require('child_process')
9
+ const { promisify } = require('util')
10
+ const execAsync = promisify(exec)
11
+
12
+ const { verifyToken } = require('../lib/auth')
13
+
14
+ /**
15
+ * Parse `sudo -l` output into structured permission entries
16
+ * @param {string} output - Raw output from `sudo -l`
17
+ * @returns {string[]} List of allowed commands
18
+ */
19
+ function parseSudoList(output) {
20
+ const lines = output.split('\n')
21
+ const commands = []
22
+
23
+ for (const line of lines) {
24
+ const trimmed = line.trim()
25
+ // Lines starting with (root) contain permission entries
26
+ if (trimmed.startsWith('(root)') || trimmed.startsWith('(ALL)')) {
27
+ // Extract the command part after NOPASSWD: or the run-as spec
28
+ const match = trimmed.match(/(?:NOPASSWD:\s*)(.+)$/)
29
+ if (match) {
30
+ commands.push(match[1].trim())
31
+ }
32
+ }
33
+ }
34
+
35
+ return commands
36
+ }
37
+
38
+ /**
39
+ * Register sudoers routes as Fastify plugin
40
+ * @param {import('fastify').FastifyInstance} fastify
41
+ */
42
+ async function sudoersRoutes(fastify) {
43
+ fastify.get('/api/sudoers', async (request, reply) => {
44
+ if (!verifyToken(request)) {
45
+ reply.code(401)
46
+ return { success: false, error: 'Unauthorized' }
47
+ }
48
+
49
+ try {
50
+ const { stdout } = await execAsync('sudo -n -l 2>/dev/null', { timeout: 5000 })
51
+ const commands = parseSudoList(stdout)
52
+
53
+ return {
54
+ success: true,
55
+ commands,
56
+ raw: stdout.trim(),
57
+ }
58
+ } catch (error) {
59
+ // sudo -l may fail if sudo is not configured at all
60
+ return {
61
+ success: true,
62
+ commands: [],
63
+ raw: '',
64
+ note: 'sudo is not configured or no permissions granted',
65
+ }
66
+ }
67
+ })
68
+ }
69
+
70
+ module.exports = { sudoersRoutes }
@@ -320,6 +320,9 @@ do_setup() {
320
320
  local SUDOERS_FILE="/etc/sudoers.d/minion-agent"
321
321
 
322
322
  {
323
+ # Fail immediately instead of prompting for password (safety net for LLM agents)
324
+ echo "Defaults:${TARGET_USER} passwd_tries=0"
325
+ echo ""
323
326
  echo "${TARGET_USER} ALL=(root) NOPASSWD: ${NPM_BIN} install -g @geekbeer/minion@latest"
324
327
  echo "${TARGET_USER} ALL=(root) NOPASSWD: ${NPM_BIN} install -g @geekbeer/minion@latest --registry *"
325
328
  echo "${TARGET_USER} ALL=(root) NOPASSWD: /usr/bin/apt-get install *"
package/linux/server.js CHANGED
@@ -20,6 +20,7 @@
20
20
  * Secrets: GET /api/secrets, PUT/DELETE /api/secrets/:key
21
21
  * Config: GET /api/config/backup, GET/PUT /api/config/env
22
22
  * Executions: GET /api/executions, GET /api/executions/:id, etc.
23
+ * Sudoers: GET /api/sudoers
23
24
  * ─────────────────────────────────────────────────────────────────────────────
24
25
  */
25
26
 
@@ -65,6 +66,7 @@ const { authRoutes } = require('../core/routes/auth')
65
66
  const { variableRoutes } = require('../core/routes/variables')
66
67
  const { memoryRoutes } = require('../core/routes/memory')
67
68
  const { dailyLogRoutes } = require('../core/routes/daily-logs')
69
+ const { sudoersRoutes } = require('../core/routes/sudoers')
68
70
 
69
71
  // Linux-specific routes
70
72
  const { commandRoutes, getProcessManager, getAllowedCommands } = require('./routes/commands')
@@ -265,6 +267,7 @@ async function registerAllRoutes(app) {
265
267
  await app.register(variableRoutes)
266
268
  await app.register(memoryRoutes)
267
269
  await app.register(dailyLogRoutes)
270
+ await app.register(sudoersRoutes)
268
271
 
269
272
  // Linux-specific routes
270
273
  await app.register(commandRoutes)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geekbeer/minion",
3
- "version": "2.57.0",
3
+ "version": "2.59.0",
4
4
  "description": "AI Agent runtime for Minion - manages status and skill deployment on VPS",
5
5
  "main": "linux/server.js",
6
6
  "bin": {
package/rules/core.md CHANGED
@@ -7,6 +7,7 @@ You are an AI agent running on a Minion VPS, managed by @geekbeer/minion.
7
7
  - **HQサーバーのソースコードを読みに行く必要はありません。** 必要なAPI仕様はすべてドキュメントに記載されています。
8
8
  - API の詳細仕様が必要な場合は `~/.minion/docs/api-reference.md` を参照してください。
9
9
  - タスクの手順が不明な場合は `~/.minion/docs/task-guides.md` を参照してください。
10
+ - **`sudo` を使用しないこと。** 必要なツール・ライブラリはすべてセットアップ済みです。`sudo` はパスワード未設定のため実行できません。パッケージのインストールや環境構築が必要に見える場合でも、既にインストール済みであることを前提に作業を進めてください。
10
11
 
11
12
  ## Architecture
12
13