@judaharagao/opencode-ssh 1.0.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.
Files changed (67) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +184 -0
  3. package/dist/config/defaults.d.ts +11 -0
  4. package/dist/config/defaults.d.ts.map +1 -0
  5. package/dist/config/defaults.js +23 -0
  6. package/dist/config/defaults.js.map +1 -0
  7. package/dist/config/schema.d.ts +51 -0
  8. package/dist/config/schema.d.ts.map +1 -0
  9. package/dist/config/schema.js +41 -0
  10. package/dist/config/schema.js.map +1 -0
  11. package/dist/display/formatter.d.ts +41 -0
  12. package/dist/display/formatter.d.ts.map +1 -0
  13. package/dist/display/formatter.js +179 -0
  14. package/dist/display/formatter.js.map +1 -0
  15. package/dist/display/stream.d.ts +38 -0
  16. package/dist/display/stream.d.ts.map +1 -0
  17. package/dist/display/stream.js +102 -0
  18. package/dist/display/stream.js.map +1 -0
  19. package/dist/hooks.d.ts +13 -0
  20. package/dist/hooks.d.ts.map +1 -0
  21. package/dist/hooks.js +151 -0
  22. package/dist/hooks.js.map +1 -0
  23. package/dist/index.d.ts +7 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +19 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/security/allowlist.d.ts +23 -0
  28. package/dist/security/allowlist.d.ts.map +1 -0
  29. package/dist/security/allowlist.js +105 -0
  30. package/dist/security/allowlist.js.map +1 -0
  31. package/dist/security/blocklist.d.ts +35 -0
  32. package/dist/security/blocklist.d.ts.map +1 -0
  33. package/dist/security/blocklist.js +351 -0
  34. package/dist/security/blocklist.js.map +1 -0
  35. package/dist/security/policy.d.ts +40 -0
  36. package/dist/security/policy.d.ts.map +1 -0
  37. package/dist/security/policy.js +133 -0
  38. package/dist/security/policy.js.map +1 -0
  39. package/dist/security/validator.d.ts +32 -0
  40. package/dist/security/validator.d.ts.map +1 -0
  41. package/dist/security/validator.js +152 -0
  42. package/dist/security/validator.js.map +1 -0
  43. package/dist/ssh/audit.d.ts +47 -0
  44. package/dist/ssh/audit.d.ts.map +1 -0
  45. package/dist/ssh/audit.js +126 -0
  46. package/dist/ssh/audit.js.map +1 -0
  47. package/dist/ssh/connection.d.ts +73 -0
  48. package/dist/ssh/connection.d.ts.map +1 -0
  49. package/dist/ssh/connection.js +210 -0
  50. package/dist/ssh/connection.js.map +1 -0
  51. package/dist/ssh/executor.d.ts +49 -0
  52. package/dist/ssh/executor.d.ts.map +1 -0
  53. package/dist/ssh/executor.js +275 -0
  54. package/dist/ssh/executor.js.map +1 -0
  55. package/dist/ssh/manager.d.ts +43 -0
  56. package/dist/ssh/manager.d.ts.map +1 -0
  57. package/dist/ssh/manager.js +98 -0
  58. package/dist/ssh/manager.js.map +1 -0
  59. package/dist/ssh/sanitizer.d.ts +41 -0
  60. package/dist/ssh/sanitizer.d.ts.map +1 -0
  61. package/dist/ssh/sanitizer.js +108 -0
  62. package/dist/ssh/sanitizer.js.map +1 -0
  63. package/dist/tools.d.ts +7 -0
  64. package/dist/tools.d.ts.map +1 -0
  65. package/dist/tools.js +584 -0
  66. package/dist/tools.js.map +1 -0
  67. package/package.json +64 -0
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Real-time SSH output stream handler.
3
+ * Formats and prepares output chunks for display as they arrive.
4
+ */
5
+ /**
6
+ * Create a stream handler that collects and formats output chunks.
7
+ */
8
+ export function createStreamHandler(sessionId) {
9
+ const chunks = [];
10
+ let stdout = "";
11
+ let stderr = "";
12
+ return {
13
+ chunks,
14
+ onStdout: (data) => {
15
+ chunks.push({
16
+ type: "stdout",
17
+ data,
18
+ timestamp: Date.now(),
19
+ sessionId,
20
+ });
21
+ stdout += data;
22
+ },
23
+ onStderr: (data) => {
24
+ chunks.push({
25
+ type: "stderr",
26
+ data,
27
+ timestamp: Date.now(),
28
+ sessionId,
29
+ });
30
+ stderr += data;
31
+ },
32
+ onInfo: (data) => {
33
+ chunks.push({
34
+ type: "info",
35
+ data,
36
+ timestamp: Date.now(),
37
+ sessionId,
38
+ });
39
+ },
40
+ onError: (data) => {
41
+ chunks.push({
42
+ type: "error",
43
+ data,
44
+ timestamp: Date.now(),
45
+ sessionId,
46
+ });
47
+ stderr += data;
48
+ },
49
+ getOutput: () => ({
50
+ stdout,
51
+ stderr,
52
+ }),
53
+ formatOutput: () => {
54
+ const lines = [];
55
+ for (const chunk of chunks) {
56
+ switch (chunk.type) {
57
+ case "stdout":
58
+ case "stderr":
59
+ // Output is collected and shown as a whole
60
+ break;
61
+ case "info":
62
+ lines.push(`ℹ️ ${chunk.data}`);
63
+ break;
64
+ case "error":
65
+ lines.push(`❌ ${chunk.data}`);
66
+ break;
67
+ }
68
+ }
69
+ if (stdout.trim()) {
70
+ lines.push(stdout.trim());
71
+ }
72
+ if (stderr.trim()) {
73
+ lines.push(`\`\`\`\n${stderr.trim()}\n\`\`\``);
74
+ }
75
+ return lines.join("\n");
76
+ },
77
+ };
78
+ }
79
+ /**
80
+ * Format a progress indicator for long-running commands.
81
+ */
82
+ export function formatProgress(sessionId, command, elapsed) {
83
+ const elapsedStr = elapsed < 1000
84
+ ? `${elapsed}ms`
85
+ : `${(elapsed / 1000).toFixed(1)}s`;
86
+ return `⏳ [${sessionId}] \`${command}\` — running for ${elapsedStr}...`;
87
+ }
88
+ /**
89
+ * Format a timeout warning.
90
+ */
91
+ export function formatTimeout(sessionId, command, timeout) {
92
+ return [
93
+ `⏰ **Command timed out**`,
94
+ "",
95
+ `- Session: \`${sessionId}\``,
96
+ `- Command: \`${command}\``,
97
+ `- Timeout: ${timeout}s`,
98
+ "",
99
+ "The command was terminated after exceeding the timeout limit.",
100
+ ].join("\n");
101
+ }
102
+ //# sourceMappingURL=stream.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream.js","sourceRoot":"","sources":["../../src/display/stream.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { Hooks } from "@opencode-ai/plugin";
2
+ import type { SecurityMode } from "./config/schema.js";
3
+ /**
4
+ * Create the SSH plugin hooks.
5
+ *
6
+ * Hooks behavior:
7
+ * - system.transform: Injects SSH availability info into the system prompt
8
+ * - permission.ask: Handles permission responses for SSH commands
9
+ * - tool.execute.before: Pre-execution validation (additional safety net)
10
+ * - tool.execute.after: Post-execution audit metadata
11
+ */
12
+ export declare function createSshHooks(mode?: SecurityMode, extraBlocklist?: string[]): Hooks;
13
+ //# sourceMappingURL=hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAEhD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAEtD;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAC5B,IAAI,GAAE,YAAqB,EAC3B,cAAc,GAAE,MAAM,EAAO,GAC5B,KAAK,CAiKP"}
package/dist/hooks.js ADDED
@@ -0,0 +1,151 @@
1
+ import { validateCommand } from "./security/validator.js";
2
+ /**
3
+ * Create the SSH plugin hooks.
4
+ *
5
+ * Hooks behavior:
6
+ * - system.transform: Injects SSH availability info into the system prompt
7
+ * - permission.ask: Handles permission responses for SSH commands
8
+ * - tool.execute.before: Pre-execution validation (additional safety net)
9
+ * - tool.execute.after: Post-execution audit metadata
10
+ */
11
+ export function createSshHooks(mode = "full", extraBlocklist = []) {
12
+ let systemInjected = false;
13
+ return {
14
+ // ═══════════════════════════════════════════════════════════════
15
+ // System prompt injection
16
+ // ═══════════════════════════════════════════════════════════════
17
+ "experimental.chat.system.transform": async (_input, output) => {
18
+ if (systemInjected)
19
+ return;
20
+ output.system.push([
21
+ "## SSH Access Plugin (opencode-ssh)",
22
+ "",
23
+ "You have SSH access to remote servers via the opencode-ssh plugin.",
24
+ "",
25
+ "### Available Tools",
26
+ "- `ssh.connect` — Establish SSH connection to a remote server",
27
+ "- `ssh.disconnect` — Close an SSH session",
28
+ "- `ssh.list_sessions` — List active SSH sessions",
29
+ "- `ssh.exec` — Execute a command on a remote server",
30
+ "- `ssh.exec_batch` — Execute multiple commands in sequence",
31
+ "- `ssh.upload` — Upload a file via SCP/SFTP",
32
+ "- `ssh.download` — Download a file via SCP/SFTP",
33
+ "- `ssh.check_command` — Check command safety without executing",
34
+ "- `ssh.security_policy` — View/modify security policy",
35
+ "- `ssh.audit_log` — View command execution audit trail",
36
+ "",
37
+ "### Security Rules",
38
+ `**Mode:** ${mode}`,
39
+ "",
40
+ "1. **Destructive commands are BLOCKED with no exceptions.**",
41
+ " Commands like \`rm -rf /\`, \`mkfs\`, \`dd\`, fork bombs, etc.",
42
+ " are permanently blocked and cannot be overridden.",
43
+ "",
44
+ "2. **Risky commands require your approval EVERY time.**",
45
+ " Commands like \`DROP TABLE\`, \`sudo su\`, \`systemctl stop\`, etc.",
46
+ " will prompt you for approval each time they are executed.",
47
+ "",
48
+ "3. **NEVER store credentials in chat messages.**",
49
+ " Use \`ssh.connect\` with key-based authentication when possible.",
50
+ "",
51
+ "4. **Always use \`ssh.check_command\` to preview command safety**",
52
+ " before running potentially dangerous operations.",
53
+ "",
54
+ "5. **All commands are logged in the audit trail.**",
55
+ " Use \`ssh.audit_log\` to review execution history.",
56
+ "",
57
+ mode === "restricted"
58
+ ? "**RESTRICTED MODE:** Only commands in the allowlist are permitted."
59
+ : mode === "read_only"
60
+ ? "**READ-ONLY MODE:** Only read-only commands are permitted."
61
+ : "**FULL MODE:** All non-blocked commands are permitted.",
62
+ ].join("\n"));
63
+ systemInjected = true;
64
+ },
65
+ // ═══════════════════════════════════════════════════════════════
66
+ // Permission handling
67
+ // ═══════════════════════════════════════════════════════════════
68
+ "permission.ask": async (input, output) => {
69
+ const pattern = typeof input.pattern === "string" ? input.pattern : "";
70
+ // Auto-approve read-only operations
71
+ if (pattern.includes("ssh.list_sessions") ||
72
+ pattern.includes("ssh.check_command") ||
73
+ pattern.includes("ssh.audit_log")) {
74
+ output.status = "allow";
75
+ return;
76
+ }
77
+ // For risky SSH commands: always ask (never auto-allow)
78
+ // This ensures the user is prompted every time for risky operations
79
+ if (pattern.includes("ssh.exec.risky") || pattern.includes("ssh.exec_batch.risky")) {
80
+ output.status = "ask";
81
+ return;
82
+ }
83
+ // For safe SSH operations: allow with user confirmation
84
+ // (the ctx.ask already showed the prompt)
85
+ if (pattern.includes("ssh.connect") ||
86
+ pattern.includes("ssh.disconnect") ||
87
+ pattern.includes("ssh.exec") ||
88
+ pattern.includes("ssh.exec_batch") ||
89
+ pattern.includes("ssh.upload") ||
90
+ pattern.includes("ssh.download") ||
91
+ pattern.includes("ssh.security_policy")) {
92
+ // Let the user decide (the prompt is shown)
93
+ output.status = "ask";
94
+ return;
95
+ }
96
+ },
97
+ // ═══════════════════════════════════════════════════════════════
98
+ // Pre-execution validation (additional safety net)
99
+ // ═══════════════════════════════════════════════════════════════
100
+ "tool.execute.before": async (input, output) => {
101
+ // Only intercept ssh.exec calls
102
+ if (input.tool !== "ssh.exec" && input.tool !== "ssh.exec_batch")
103
+ return;
104
+ const args = output.args;
105
+ const command = args.command;
106
+ if (!command)
107
+ return;
108
+ // Final safety check: validate the command one more time
109
+ const validation = validateCommand(command, mode, extraBlocklist);
110
+ if (validation.level === "destructive") {
111
+ throw new Error([
112
+ `🚫 DESTRUCTIVE COMMAND BLOCKED: ${command}`,
113
+ "",
114
+ `Reason: ${validation.reason}`,
115
+ `Rule: ${validation.matched_rule}`,
116
+ "",
117
+ "This command is permanently blocked and cannot be executed.",
118
+ ].join("\n"));
119
+ }
120
+ if (validation.level === "not_in_allowlist") {
121
+ throw new Error([
122
+ `🔒 COMMAND NOT ALLOWED: ${command}`,
123
+ "",
124
+ `Reason: ${validation.reason}`,
125
+ "",
126
+ "This command is not permitted in the current security mode.",
127
+ ].join("\n"));
128
+ }
129
+ },
130
+ // ═══════════════════════════════════════════════════════════════
131
+ // Post-execution metadata
132
+ // ═══════════════════════════════════════════════════════════════
133
+ "tool.execute.after": async (input, output) => {
134
+ if (!input.tool.startsWith("ssh."))
135
+ return;
136
+ const timestamp = new Date().toISOString();
137
+ if (output.metadata) {
138
+ output.metadata.ssh_plugin = true;
139
+ output.metadata.ssh_timestamp = timestamp;
140
+ }
141
+ },
142
+ // ═══════════════════════════════════════════════════════════════
143
+ // Cleanup on dispose
144
+ // ═══════════════════════════════════════════════════════════════
145
+ dispose: async () => {
146
+ systemInjected = false;
147
+ // Session cleanup is handled by the manager
148
+ },
149
+ };
150
+ }
151
+ //# sourceMappingURL=hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AAGzD;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc,CAC5B,OAAqB,MAAM,EAC3B,iBAA2B,EAAE;IAE7B,IAAI,cAAc,GAAG,KAAK,CAAA;IAE1B,OAAO;QACL,kEAAkE;QAClE,0BAA0B;QAC1B,kEAAkE;QAClE,oCAAoC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;YAC7D,IAAI,cAAc;gBAAE,OAAM;YAE1B,MAAM,CAAC,MAAM,CAAC,IAAI,CAChB;gBACE,qCAAqC;gBACrC,EAAE;gBACF,oEAAoE;gBACpE,EAAE;gBACF,qBAAqB;gBACrB,+DAA+D;gBAC/D,2CAA2C;gBAC3C,kDAAkD;gBAClD,qDAAqD;gBACrD,4DAA4D;gBAC5D,6CAA6C;gBAC7C,iDAAiD;gBACjD,gEAAgE;gBAChE,uDAAuD;gBACvD,wDAAwD;gBACxD,EAAE;gBACF,oBAAoB;gBACpB,aAAa,IAAI,EAAE;gBACnB,EAAE;gBACF,6DAA6D;gBAC7D,mEAAmE;gBACnE,sDAAsD;gBACtD,EAAE;gBACF,yDAAyD;gBACzD,wEAAwE;gBACxE,8DAA8D;gBAC9D,EAAE;gBACF,kDAAkD;gBAClD,qEAAqE;gBACrE,EAAE;gBACF,mEAAmE;gBACnE,qDAAqD;gBACrD,EAAE;gBACF,oDAAoD;gBACpD,uDAAuD;gBACvD,EAAE;gBACF,IAAI,KAAK,YAAY;oBACnB,CAAC,CAAC,oEAAoE;oBACtE,CAAC,CAAC,IAAI,KAAK,WAAW;wBACpB,CAAC,CAAC,4DAA4D;wBAC9D,CAAC,CAAC,wDAAwD;aAC/D,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAA;YAED,cAAc,GAAG,IAAI,CAAA;QACvB,CAAC;QAED,kEAAkE;QAClE,sBAAsB;QACtB,kEAAkE;QAClE,gBAAgB,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YACxC,MAAM,OAAO,GAAG,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAA;YAEtE,oCAAoC;YACpC,IACE,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAC;gBACrC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAC;gBACrC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,EACjC,CAAC;gBACD,MAAM,CAAC,MAAM,GAAG,OAAO,CAAA;gBACvB,OAAM;YACR,CAAC;YAED,wDAAwD;YACxD,oEAAoE;YACpE,IAAI,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAC,EAAE,CAAC;gBACnF,MAAM,CAAC,MAAM,GAAG,KAAK,CAAA;gBACrB,OAAM;YACR,CAAC;YAED,wDAAwD;YACxD,0CAA0C;YAC1C,IACE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC;gBAC/B,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC;gBAClC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC;gBAC5B,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC;gBAClC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC;gBAC9B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC;gBAChC,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAC,EACvC,CAAC;gBACD,4CAA4C;gBAC5C,MAAM,CAAC,MAAM,GAAG,KAAK,CAAA;gBACrB,OAAM;YACR,CAAC;QACH,CAAC;QAED,kEAAkE;QAClE,mDAAmD;QACnD,kEAAkE;QAClE,qBAAqB,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YAC7C,gCAAgC;YAChC,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB;gBAAE,OAAM;YAExE,MAAM,IAAI,GAAG,MAAM,CAAC,IAA+B,CAAA;YACnD,MAAM,OAAO,GAAG,IAAI,CAAC,OAA6B,CAAA;YAElD,IAAI,CAAC,OAAO;gBAAE,OAAM;YAEpB,yDAAyD;YACzD,MAAM,UAAU,GAAG,eAAe,CAAC,OAAO,EAAE,IAAI,EAAE,cAAc,CAAC,CAAA;YAEjE,IAAI,UAAU,CAAC,KAAK,KAAK,aAAa,EAAE,CAAC;gBACvC,MAAM,IAAI,KAAK,CACb;oBACE,mCAAmC,OAAO,EAAE;oBAC5C,EAAE;oBACF,WAAW,UAAU,CAAC,MAAM,EAAE;oBAC9B,SAAS,UAAU,CAAC,YAAY,EAAE;oBAClC,EAAE;oBACF,6DAA6D;iBAC9D,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAA;YACH,CAAC;YAED,IAAI,UAAU,CAAC,KAAK,KAAK,kBAAkB,EAAE,CAAC;gBAC5C,MAAM,IAAI,KAAK,CACb;oBACE,2BAA2B,OAAO,EAAE;oBACpC,EAAE;oBACF,WAAW,UAAU,CAAC,MAAM,EAAE;oBAC9B,EAAE;oBACF,6DAA6D;iBAC9D,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAA;YACH,CAAC;QACH,CAAC;QAED,kEAAkE;QAClE,0BAA0B;QAC1B,kEAAkE;QAClE,oBAAoB,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YAC5C,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;gBAAE,OAAM;YAE1C,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;YAC1C,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;gBACpB,MAAM,CAAC,QAAQ,CAAC,UAAU,GAAG,IAAI,CAAA;gBACjC,MAAM,CAAC,QAAQ,CAAC,aAAa,GAAG,SAAS,CAAA;YAC3C,CAAC;QACH,CAAC;QAED,kEAAkE;QAClE,qBAAqB;QACrB,kEAAkE;QAClE,OAAO,EAAE,KAAK,IAAI,EAAE;YAClB,cAAc,GAAG,KAAK,CAAA;YACtB,4CAA4C;QAC9C,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { Plugin } from "@opencode-ai/plugin";
2
+ declare const _default: {
3
+ id: string;
4
+ server: Plugin;
5
+ };
6
+ export default _default;
7
+ //# 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;;;;;AAyBjD,wBAGC"}
package/dist/index.js ADDED
@@ -0,0 +1,19 @@
1
+ import { createSshTools } from "./tools.js";
2
+ import { createSshHooks } from "./hooks.js";
3
+ import { resolveConfig } from "./config/defaults.js";
4
+ const SshPlugin = async (_ctx, options) => {
5
+ // ── Resolve configuration ──
6
+ const config = resolveConfig(options);
7
+ // ── Create tools and hooks with resolved config ──
8
+ const tools = createSshTools(config.mode, config.max_sessions, config.default_timeout, config.blocklist_extra);
9
+ const hooks = createSshHooks(config.mode, config.blocklist_extra);
10
+ return {
11
+ tool: tools,
12
+ ...hooks,
13
+ };
14
+ };
15
+ export default {
16
+ id: "opencode-ssh",
17
+ server: SshPlugin,
18
+ };
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAGpD,MAAM,SAAS,GAAW,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE;IAChD,8BAA8B;IAC9B,MAAM,MAAM,GAAG,aAAa,CAAC,OAAkC,CAAC,CAAA;IAEhE,oDAAoD;IACpD,MAAM,KAAK,GAAG,cAAc,CAC1B,MAAM,CAAC,IAAI,EACX,MAAM,CAAC,YAAY,EACnB,MAAM,CAAC,eAAe,EACtB,MAAM,CAAC,eAAe,CACvB,CAAA;IACD,MAAM,KAAK,GAAG,cAAc,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,eAAe,CAAC,CAAA;IAEjE,OAAO;QACL,IAAI,EAAE,KAAK;QACX,GAAG,KAAK;KACT,CAAA;AACH,CAAC,CAAA;AAED,eAAe;IACb,EAAE,EAAE,cAAc;IAClB,MAAM,EAAE,SAAS;CAClB,CAAA"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Allowlist for SSH command execution.
3
+ * Used in "restricted" and "read_only" security modes.
4
+ */
5
+ export interface AllowlistEntry {
6
+ /** Regex pattern to match */
7
+ pattern: RegExp;
8
+ /** Description of the allowed command */
9
+ description: string;
10
+ }
11
+ /**
12
+ * Get read-only allowed commands.
13
+ */
14
+ export declare function getReadOnlyCommands(): AllowlistEntry[];
15
+ /**
16
+ * Get safe write commands (used in "restricted" mode).
17
+ */
18
+ export declare function getSafeWriteCommands(): AllowlistEntry[];
19
+ /**
20
+ * Get all allowed commands for a given mode.
21
+ */
22
+ export declare function getAllowedCommands(mode: "full" | "restricted" | "read_only"): AllowlistEntry[];
23
+ //# sourceMappingURL=allowlist.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"allowlist.d.ts","sourceRoot":"","sources":["../../src/security/allowlist.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,cAAc;IAC7B,6BAA6B;IAC7B,OAAO,EAAE,MAAM,CAAA;IACf,yCAAyC;IACzC,WAAW,EAAE,MAAM,CAAA;CACpB;AA+ED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,cAAc,EAAE,CAEtD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,cAAc,EAAE,CAEvD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,WAAW,GAAG,cAAc,EAAE,CAS9F"}
@@ -0,0 +1,105 @@
1
+ /**
2
+ * Allowlist for SSH command execution.
3
+ * Used in "restricted" and "read_only" security modes.
4
+ */
5
+ // ─── READ-ONLY COMMANDS (always allowed) ───────────────────────────
6
+ const READ_ONLY_COMMANDS = [
7
+ { pattern: /^ls\b/, description: "List directory contents" },
8
+ { pattern: /^ll\b/, description: "List directory contents (long)" },
9
+ { pattern: /^la\b/, description: "List all files including hidden" },
10
+ { pattern: /^cat\b/, description: "Display file contents" },
11
+ { pattern: /^head\b/, description: "Display first lines of a file" },
12
+ { pattern: /^tail\b/, description: "Display last lines of a file" },
13
+ { pattern: /^less\b/, description: "View file contents pager" },
14
+ { pattern: /^more\b/, description: "View file contents" },
15
+ { pattern: /^grep\b/, description: "Search text patterns" },
16
+ { pattern: /^rg\b/, description: "Ripgrep search" },
17
+ { pattern: /^find\b/, description: "Find files" },
18
+ { pattern: /^which\b/, description: "Locate a command" },
19
+ { pattern: /^whereis\b/, description: "Locate binary, source, man" },
20
+ { pattern: /^whoami\b/, description: "Print current user" },
21
+ { pattern: /^id\b/, description: "Print user/group IDs" },
22
+ { pattern: /^pwd\b/, description: "Print working directory" },
23
+ { pattern: /^echo\b/, description: "Print text" },
24
+ { pattern: /^date\b/, description: "Print date and time" },
25
+ { pattern: /^uptime\b/, description: "System uptime" },
26
+ { pattern: /^uname\b/, description: "System information" },
27
+ { pattern: /^hostname\b/, description: "Print hostname" },
28
+ { pattern: /^df\b/, description: "Disk space usage" },
29
+ { pattern: /^du\b/, description: "Directory space usage" },
30
+ { pattern: /^free\b/, description: "Memory usage" },
31
+ { pattern: /^ps\b/, description: "Process status" },
32
+ { pattern: /^top\b/, description: "Process monitor (read-only)" },
33
+ { pattern: /^htop\b/, description: "Process monitor (enhanced)" },
34
+ { pattern: /^wc\b/, description: "Word/line/byte count" },
35
+ { pattern: /^file\b/, description: "Determine file type" },
36
+ { pattern: /^stat\b/, description: "Display file status" },
37
+ { pattern: /^tree\b/, description: "Directory tree display" },
38
+ { pattern: /^du\b/, description: "Disk usage" },
39
+ { pattern: /^diff\b/, description: "Compare files" },
40
+ { pattern: /^md5sum\b/, description: "MD5 checksum" },
41
+ { pattern: /^sha256sum\b/, description: "SHA256 checksum" },
42
+ { pattern: /^env\b/, description: "Print environment variables" },
43
+ { pattern: /^printenv\b/, description: "Print environment variable" },
44
+ { pattern: /^history\b/, description: "Command history" },
45
+ { pattern: /^man\b/, description: "Manual pages" },
46
+ { pattern: /^tldr\b/, description: "Simplified man pages" },
47
+ { pattern: /^ping\b/, description: "Network connectivity test" },
48
+ { pattern: /^dig\b/, description: "DNS lookup" },
49
+ { pattern: /^nslookup\b/, description: "DNS lookup" },
50
+ { pattern: /^host\b/, description: "DNS lookup" },
51
+ { pattern: /^curl\s+.*\s+-I\b/, description: "HTTP HEAD request via curl" },
52
+ { pattern: /^git\s+(status|log|diff|show|branch|remote)\b/, description: "Git read-only commands" },
53
+ { pattern: /^docker\s+ps\b/, description: "List Docker containers" },
54
+ { pattern: /^docker\s+images\b/, description: "List Docker images" },
55
+ { pattern: /^docker\s+logs\b/, description: "View Docker container logs" },
56
+ { pattern: /^docker\s+inspect\b/, description: "Inspect Docker object" },
57
+ { pattern: /^kubectl\s+get\b/, description: "Kubernetes get resources" },
58
+ { pattern: /^kubectl\s+describe\b/, description: "Kubernetes describe resource" },
59
+ { pattern: /^kubectl\s+logs\b/, description: "Kubernetes pod logs" },
60
+ { pattern: /^kubectl\s+top\b/, description: "Kubernetes resource usage" },
61
+ { pattern: /^systemctl\s+status\b/, description: "Service status" },
62
+ { pattern: /^systemctl\s+list\b/, description: "List services" },
63
+ { pattern: /^journalctl\b/, description: "View systemd journal" },
64
+ ];
65
+ // ─── SAFE WRITE COMMANDS (allowed in "restricted" mode) ────────────
66
+ const SAFE_WRITE_COMMANDS = [
67
+ { pattern: /^mkdir\b/, description: "Create directory" },
68
+ { pattern: /^touch\b/, description: "Create empty file" },
69
+ { pattern: /^cp\b/, description: "Copy files" },
70
+ { pattern: /^mv\b/, description: "Move/rename files" },
71
+ { pattern: /^nano\b/, description: "Text editor" },
72
+ { pattern: /^vim\b/, description: "Text editor" },
73
+ { pattern: /^vi\b/, description: "Text editor" },
74
+ { pattern: /^git\s+(add|commit|push|pull|checkout|merge|stash)\b/, description: "Git write commands" },
75
+ { pattern: /^npm\s+(install|run|test|build)\b/, description: "NPM commands" },
76
+ { pattern: /^yarn\s+(add|run|test|build)\b/, description: "Yarn commands" },
77
+ { pattern: /^pnpm\s+(add|run|test|build)\b/, description: "PNPM commands" },
78
+ { pattern: /^bun\s+(install|run|test|build)\b/, description: "Bun commands" },
79
+ ];
80
+ /**
81
+ * Get read-only allowed commands.
82
+ */
83
+ export function getReadOnlyCommands() {
84
+ return [...READ_ONLY_COMMANDS];
85
+ }
86
+ /**
87
+ * Get safe write commands (used in "restricted" mode).
88
+ */
89
+ export function getSafeWriteCommands() {
90
+ return [...SAFE_WRITE_COMMANDS];
91
+ }
92
+ /**
93
+ * Get all allowed commands for a given mode.
94
+ */
95
+ export function getAllowedCommands(mode) {
96
+ switch (mode) {
97
+ case "read_only":
98
+ return getReadOnlyCommands();
99
+ case "restricted":
100
+ return [...getReadOnlyCommands(), ...getSafeWriteCommands()];
101
+ case "full":
102
+ return []; // Only blocklist applies in full mode
103
+ }
104
+ }
105
+ //# sourceMappingURL=allowlist.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"allowlist.js","sourceRoot":"","sources":["../../src/security/allowlist.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,sEAAsE;AACtE,MAAM,kBAAkB,GAAqB;IAC3C,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,yBAAyB,EAAE;IAC5D,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,gCAAgC,EAAE;IACnE,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,iCAAiC,EAAE;IACpE,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,uBAAuB,EAAE;IAC3D,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,+BAA+B,EAAE;IACpE,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,8BAA8B,EAAE;IACnE,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,0BAA0B,EAAE;IAC/D,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,oBAAoB,EAAE;IACzD,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,sBAAsB,EAAE;IAC3D,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE;IACnD,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE;IACjD,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,kBAAkB,EAAE;IACxD,EAAE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,4BAA4B,EAAE;IACpE,EAAE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,oBAAoB,EAAE;IAC3D,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,sBAAsB,EAAE;IACzD,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,yBAAyB,EAAE;IAC7D,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE;IACjD,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,qBAAqB,EAAE;IAC1D,EAAE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,eAAe,EAAE;IACtD,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,oBAAoB,EAAE;IAC1D,EAAE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,gBAAgB,EAAE;IACzD,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE;IACrD,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,uBAAuB,EAAE;IAC1D,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,cAAc,EAAE;IACnD,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE;IACnD,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,6BAA6B,EAAE;IACjE,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,4BAA4B,EAAE;IACjE,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,sBAAsB,EAAE;IACzD,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,qBAAqB,EAAE;IAC1D,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,qBAAqB,EAAE;IAC1D,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,wBAAwB,EAAE;IAC7D,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE;IAC/C,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,eAAe,EAAE;IACpD,EAAE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE;IACrD,EAAE,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,iBAAiB,EAAE;IAC3D,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,6BAA6B,EAAE;IACjE,EAAE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,4BAA4B,EAAE;IACrE,EAAE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE;IACzD,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,cAAc,EAAE;IAClD,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,sBAAsB,EAAE;IAC3D,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,2BAA2B,EAAE;IAChE,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,YAAY,EAAE;IAChD,EAAE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE;IACrD,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,EAAE;IACjD,EAAE,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,4BAA4B,EAAE;IAC3E,EAAE,OAAO,EAAE,+CAA+C,EAAE,WAAW,EAAE,wBAAwB,EAAE;IACnG,EAAE,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,wBAAwB,EAAE;IACpE,EAAE,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,oBAAoB,EAAE;IACpE,EAAE,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,4BAA4B,EAAE;IAC1E,EAAE,OAAO,EAAE,qBAAqB,EAAE,WAAW,EAAE,uBAAuB,EAAE;IACxE,EAAE,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,0BAA0B,EAAE;IACxE,EAAE,OAAO,EAAE,uBAAuB,EAAE,WAAW,EAAE,8BAA8B,EAAE;IACjF,EAAE,OAAO,EAAE,mBAAmB,EAAE,WAAW,EAAE,qBAAqB,EAAE;IACpE,EAAE,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,2BAA2B,EAAE;IACzE,EAAE,OAAO,EAAE,uBAAuB,EAAE,WAAW,EAAE,gBAAgB,EAAE;IACnE,EAAE,OAAO,EAAE,qBAAqB,EAAE,WAAW,EAAE,eAAe,EAAE;IAChE,EAAE,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,sBAAsB,EAAE;CAClE,CAAA;AAED,sEAAsE;AACtE,MAAM,mBAAmB,GAAqB;IAC5C,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,kBAAkB,EAAE;IACxD,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,mBAAmB,EAAE;IACzD,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE;IAC/C,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE;IACtD,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE;IAClD,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,aAAa,EAAE;IACjD,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE;IAChD,EAAE,OAAO,EAAE,sDAAsD,EAAE,WAAW,EAAE,oBAAoB,EAAE;IACtG,EAAE,OAAO,EAAE,mCAAmC,EAAE,WAAW,EAAE,cAAc,EAAE;IAC7E,EAAE,OAAO,EAAE,gCAAgC,EAAE,WAAW,EAAE,eAAe,EAAE;IAC3E,EAAE,OAAO,EAAE,gCAAgC,EAAE,WAAW,EAAE,eAAe,EAAE;IAC3E,EAAE,OAAO,EAAE,mCAAmC,EAAE,WAAW,EAAE,cAAc,EAAE;CAC9E,CAAA;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB;IACjC,OAAO,CAAC,GAAG,kBAAkB,CAAC,CAAA;AAChC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB;IAClC,OAAO,CAAC,GAAG,mBAAmB,CAAC,CAAA;AACjC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAyC;IAC1E,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,WAAW;YACd,OAAO,mBAAmB,EAAE,CAAA;QAC9B,KAAK,YAAY;YACf,OAAO,CAAC,GAAG,mBAAmB,EAAE,EAAE,GAAG,oBAAoB,EAAE,CAAC,CAAA;QAC9D,KAAK,MAAM;YACT,OAAO,EAAE,CAAA,CAAC,sCAAsC;IACpD,CAAC;AACH,CAAC"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Command Blocklist for SSH plugin.
3
+ *
4
+ * Commands are categorized into two levels:
5
+ * - DESTRUCTIVE: 100% blocked, no exceptions, no override possible
6
+ * - RISKY: Blocked by default, requires user approval via permission prompt every time
7
+ */
8
+ export type CommandLevel = "destructive" | "risky" | "safe";
9
+ export interface BlocklistEntry {
10
+ /** Regex pattern to match against the command */
11
+ pattern: RegExp;
12
+ /** Human-readable description of why this is blocked */
13
+ reason: string;
14
+ /** Level of danger */
15
+ level: CommandLevel;
16
+ /** Unique rule ID for audit logging */
17
+ id: string;
18
+ }
19
+ /**
20
+ * Get all built-in blocklist entries.
21
+ */
22
+ export declare function getBuiltinBlocklist(): BlocklistEntry[];
23
+ /**
24
+ * Get only destructive commands.
25
+ */
26
+ export declare function getDestructiveCommands(): BlocklistEntry[];
27
+ /**
28
+ * Get only risky commands.
29
+ */
30
+ export declare function getRiskyCommands(): BlocklistEntry[];
31
+ /**
32
+ * Create custom blocklist entries from user-provided regex patterns.
33
+ */
34
+ export declare function createCustomEntries(patterns: string[], level?: CommandLevel): BlocklistEntry[];
35
+ //# sourceMappingURL=blocklist.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blocklist.d.ts","sourceRoot":"","sources":["../../src/security/blocklist.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,YAAY,GAAG,aAAa,GAAG,OAAO,GAAG,MAAM,CAAA;AAE3D,MAAM,WAAW,cAAc;IAC7B,iDAAiD;IACjD,OAAO,EAAE,MAAM,CAAA;IACf,wDAAwD;IACxD,MAAM,EAAE,MAAM,CAAA;IACd,sBAAsB;IACtB,KAAK,EAAE,YAAY,CAAA;IACnB,uCAAuC;IACvC,EAAE,EAAE,MAAM,CAAA;CACX;AAgUD;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,cAAc,EAAE,CAEtD;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,cAAc,EAAE,CAEzD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,cAAc,EAAE,CAEnD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAAE,EAClB,KAAK,GAAE,YAAsB,GAC5B,cAAc,EAAE,CAOlB"}