openwork-server 0.1.1 → 0.11.38

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/dist/mcp.js DELETED
@@ -1,50 +0,0 @@
1
- import { minimatch } from "minimatch";
2
- import { readJsoncFile, updateJsoncTopLevel } from "./jsonc.js";
3
- import { opencodeConfigPath } from "./workspace-files.js";
4
- import { validateMcpConfig, validateMcpName } from "./validators.js";
5
- function getMcpConfig(config) {
6
- const mcp = config.mcp;
7
- if (!mcp || typeof mcp !== "object")
8
- return {};
9
- return mcp;
10
- }
11
- function getDeniedToolPatterns(config) {
12
- const tools = config.tools;
13
- if (!tools || typeof tools !== "object")
14
- return [];
15
- const deny = tools.deny;
16
- if (!Array.isArray(deny))
17
- return [];
18
- return deny.filter((item) => typeof item === "string");
19
- }
20
- function isMcpDisabledByTools(config, name) {
21
- const patterns = getDeniedToolPatterns(config);
22
- if (patterns.length === 0)
23
- return false;
24
- const candidates = [`mcp.${name}`, `mcp.${name}.*`, `mcp:${name}`, `mcp:${name}:*`, "mcp.*", "mcp:*"];
25
- return patterns.some((pattern) => candidates.some((candidate) => minimatch(candidate, pattern)));
26
- }
27
- export async function listMcp(workspaceRoot) {
28
- const { data: config } = await readJsoncFile(opencodeConfigPath(workspaceRoot), {});
29
- const mcpMap = getMcpConfig(config);
30
- return Object.entries(mcpMap).map(([name, entry]) => ({
31
- name,
32
- config: entry,
33
- source: "config.project",
34
- disabledByTools: isMcpDisabledByTools(config, name) || undefined,
35
- }));
36
- }
37
- export async function addMcp(workspaceRoot, name, config) {
38
- validateMcpName(name);
39
- validateMcpConfig(config);
40
- const { data } = await readJsoncFile(opencodeConfigPath(workspaceRoot), {});
41
- const mcpMap = getMcpConfig(data);
42
- mcpMap[name] = config;
43
- await updateJsoncTopLevel(opencodeConfigPath(workspaceRoot), { mcp: mcpMap });
44
- }
45
- export async function removeMcp(workspaceRoot, name) {
46
- const { data } = await readJsoncFile(opencodeConfigPath(workspaceRoot), {});
47
- const mcpMap = getMcpConfig(data);
48
- delete mcpMap[name];
49
- await updateJsoncTopLevel(opencodeConfigPath(workspaceRoot), { mcp: mcpMap });
50
- }
package/dist/paths.js DELETED
@@ -1,19 +0,0 @@
1
- import { realpath } from "node:fs/promises";
2
- import { isAbsolute, resolve, sep } from "node:path";
3
- import { ApiError } from "./errors.js";
4
- export function assertAbsolute(path) {
5
- if (!isAbsolute(path)) {
6
- throw new ApiError(400, "invalid_path", "Path must be absolute");
7
- }
8
- }
9
- export async function resolveWithinRoot(root, ...segments) {
10
- const resolvedRoot = await realpath(root);
11
- const candidate = resolve(resolvedRoot, ...segments);
12
- const resolvedCandidate = await realpath(candidate).catch(() => candidate);
13
- if (resolvedCandidate === resolvedRoot)
14
- return candidate;
15
- if (!resolvedCandidate.startsWith(resolvedRoot + sep)) {
16
- throw new ApiError(400, "path_escape", "Path escapes workspace root");
17
- }
18
- return candidate;
19
- }
package/dist/plugins.js DELETED
@@ -1,88 +0,0 @@
1
- import { homedir } from "node:os";
2
- import { join, relative } from "node:path";
3
- import { readdir } from "node:fs/promises";
4
- import { readJsoncFile, updateJsoncTopLevel } from "./jsonc.js";
5
- import { opencodeConfigPath, projectPluginsDir } from "./workspace-files.js";
6
- import { exists } from "./utils.js";
7
- import { validatePluginSpec } from "./validators.js";
8
- function normalizePluginSpec(spec) {
9
- const trimmed = spec.trim();
10
- if (trimmed.startsWith("file:") || trimmed.startsWith("http:") || trimmed.startsWith("https:") || trimmed.startsWith("git:")) {
11
- return trimmed;
12
- }
13
- if (trimmed.startsWith("/")) {
14
- return trimmed;
15
- }
16
- if (trimmed.startsWith("@")) {
17
- const atIndex = trimmed.indexOf("@", 1);
18
- return atIndex > 0 ? trimmed.slice(0, atIndex) : trimmed;
19
- }
20
- const atIndex = trimmed.indexOf("@");
21
- return atIndex > 0 ? trimmed.slice(0, atIndex) : trimmed;
22
- }
23
- function pluginListFromConfig(config) {
24
- const plugin = config.plugin;
25
- if (typeof plugin === "string")
26
- return [plugin];
27
- if (Array.isArray(plugin))
28
- return plugin.filter((item) => typeof item === "string");
29
- return [];
30
- }
31
- async function listPluginFiles(dir, scope, workspaceRoot) {
32
- if (!(await exists(dir)))
33
- return [];
34
- const entries = await readdir(dir, { withFileTypes: true });
35
- const items = [];
36
- for (const entry of entries) {
37
- if (!entry.isFile())
38
- continue;
39
- if (!entry.name.endsWith(".js") && !entry.name.endsWith(".ts"))
40
- continue;
41
- const absolutePath = join(dir, entry.name);
42
- const relativePath = workspaceRoot ? relative(workspaceRoot, absolutePath) : absolutePath;
43
- items.push({
44
- spec: `file://${absolutePath}`,
45
- source: scope === "project" ? "dir.project" : "dir.global",
46
- scope,
47
- path: relativePath,
48
- });
49
- }
50
- return items;
51
- }
52
- export async function listPlugins(workspaceRoot, includeGlobal) {
53
- const { data: config } = await readJsoncFile(opencodeConfigPath(workspaceRoot), {});
54
- const pluginSpecs = pluginListFromConfig(config);
55
- const items = pluginSpecs.map((spec) => ({
56
- spec,
57
- source: "config",
58
- scope: "project",
59
- }));
60
- const projectDir = projectPluginsDir(workspaceRoot);
61
- items.push(...(await listPluginFiles(projectDir, "project", workspaceRoot)));
62
- if (includeGlobal) {
63
- const globalDir = join(homedir(), ".config", "opencode", "plugins");
64
- items.push(...(await listPluginFiles(globalDir, "global")));
65
- }
66
- return {
67
- items,
68
- loadOrder: ["config.global", "config.project", "dir.global", "dir.project"],
69
- };
70
- }
71
- export async function addPlugin(workspaceRoot, spec) {
72
- validatePluginSpec(spec);
73
- const { data: config } = await readJsoncFile(opencodeConfigPath(workspaceRoot), {});
74
- const pluginSpecs = pluginListFromConfig(config);
75
- const normalized = normalizePluginSpec(spec);
76
- const existing = pluginSpecs.find((item) => normalizePluginSpec(item) === normalized);
77
- if (existing)
78
- return;
79
- pluginSpecs.push(spec);
80
- await updateJsoncTopLevel(opencodeConfigPath(workspaceRoot), { plugin: pluginSpecs });
81
- }
82
- export async function removePlugin(workspaceRoot, name) {
83
- const { data: config } = await readJsoncFile(opencodeConfigPath(workspaceRoot), {});
84
- const pluginSpecs = pluginListFromConfig(config);
85
- const normalized = normalizePluginSpec(name);
86
- const filtered = pluginSpecs.filter((item) => normalizePluginSpec(item) !== normalized);
87
- await updateJsoncTopLevel(opencodeConfigPath(workspaceRoot), { plugin: filtered });
88
- }