runline 0.3.1 → 0.3.2

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.
@@ -1,11 +1,33 @@
1
1
  import type { PluginDef } from "./types.js";
2
2
  export declare function loadPluginFromPath(path: string): Promise<PluginDef>;
3
3
  export declare function loadPluginsFromConfig(configDir: string): Promise<PluginDef[]>;
4
+ export interface DiscoverOptions {
5
+ /**
6
+ * When supplied, only built-in plugins whose name is in this set
7
+ * are loaded. Plugins discovered in the project dir, `plugins.json`,
8
+ * or `~/.runline/plugins` are always loaded — users put them there
9
+ * deliberately — but the 188 bundled builtins are gated so agents
10
+ * don't see every possible action regardless of configuration.
11
+ *
12
+ * Omit to load every builtin (CLI default: `runline actions` etc.
13
+ * surfaces the full catalog).
14
+ */
15
+ builtinAllowlist?: Set<string> | null;
16
+ /**
17
+ * Override the directory where bundled plugins live. Default is
18
+ * `<loader>/../plugins`, which resolves to `dist/plugins/` at
19
+ * runtime. Tests set this so they can exercise allowlist logic
20
+ * without depending on the real bundled catalog.
21
+ */
22
+ builtinDir?: string;
23
+ }
24
+ /** Default path to the bundled plugin directory. */
25
+ export declare function defaultBuiltinDir(): string;
4
26
  /**
5
27
  * Discover and return all plugins from a config directory and global dir.
6
28
  * Does NOT mutate any global state.
7
29
  */
8
- export declare function discoverPlugins(configDir?: string | null): Promise<PluginDef[]>;
30
+ export declare function discoverPlugins(configDir?: string | null, options?: DiscoverOptions): Promise<PluginDef[]>;
9
31
  /**
10
32
  * Load all plugins and register them into the global registry.
11
33
  * Used by the CLI.
@@ -118,11 +118,15 @@ export async function loadPluginsFromConfig(configDir) {
118
118
  }
119
119
  return plugins;
120
120
  }
121
+ /** Default path to the bundled plugin directory. */
122
+ export function defaultBuiltinDir() {
123
+ return join(__dirname, "..", "plugins");
124
+ }
121
125
  /**
122
126
  * Discover and return all plugins from a config directory and global dir.
123
127
  * Does NOT mutate any global state.
124
128
  */
125
- export async function discoverPlugins(configDir) {
129
+ export async function discoverPlugins(configDir, options = {}) {
126
130
  const loaded = new Set();
127
131
  const result = [];
128
132
  function addIfNew(plugin) {
@@ -144,11 +148,14 @@ export async function discoverPlugins(configDir) {
144
148
  const globalPlugins = await loadFromDirectory(globalDir);
145
149
  for (const p of globalPlugins)
146
150
  addIfNew(p);
147
- // Built-in plugins shipped with the package
148
- const builtinDir = join(__dirname, "..", "plugins");
151
+ const builtinDir = options.builtinDir ?? defaultBuiltinDir();
149
152
  const builtinPlugins = await loadFromDirectory(builtinDir);
150
- for (const p of builtinPlugins)
153
+ for (const p of builtinPlugins) {
154
+ if (options.builtinAllowlist && !options.builtinAllowlist.has(p.name)) {
155
+ continue;
156
+ }
151
157
  addIfNew(p);
158
+ }
152
159
  return result;
153
160
  }
154
161
  /**
package/dist/sdk.d.ts CHANGED
@@ -34,8 +34,26 @@ export declare class Runline {
34
34
  connections(): ConnectionConfig[];
35
35
  /**
36
36
  * Load runline from a project directory.
37
- * Discovers .runline/ config and installed plugins, just like the CLI.
37
+ *
38
+ * Discovers the `.runline/` config and registers:
39
+ * - every plugin dropped into `.runline/plugins/`,
40
+ * - every plugin listed in `.runline/plugins.json`,
41
+ * - every plugin in `~/.runline/plugins/`,
42
+ * - and — from the 188 builtins shipped with the package — only
43
+ * the ones named in `config.connections[].plugin`.
44
+ *
45
+ * Gating the builtins keeps `runline.actions()` scoped to what the
46
+ * project actually configured. Without this, a project with a
47
+ * single connection would still expose every bundled action to an
48
+ * agent, which is both noisy and a privacy problem (the agent sees
49
+ * surface area it has no credentials for).
50
+ *
51
+ * `options.builtinDir` is a test-only hook; production callers
52
+ * should rely on the default path to the bundled plugins.
53
+ *
38
54
  * Fully self-contained — does not mutate global state.
39
55
  */
40
- static fromProject(cwd?: string): Promise<Runline | null>;
56
+ static fromProject(cwd?: string, options?: {
57
+ builtinDir?: string;
58
+ }): Promise<Runline | null>;
41
59
  }
package/dist/sdk.js CHANGED
@@ -63,16 +63,36 @@ export class Runline {
63
63
  }
64
64
  /**
65
65
  * Load runline from a project directory.
66
- * Discovers .runline/ config and installed plugins, just like the CLI.
66
+ *
67
+ * Discovers the `.runline/` config and registers:
68
+ * - every plugin dropped into `.runline/plugins/`,
69
+ * - every plugin listed in `.runline/plugins.json`,
70
+ * - every plugin in `~/.runline/plugins/`,
71
+ * - and — from the 188 builtins shipped with the package — only
72
+ * the ones named in `config.connections[].plugin`.
73
+ *
74
+ * Gating the builtins keeps `runline.actions()` scoped to what the
75
+ * project actually configured. Without this, a project with a
76
+ * single connection would still expose every bundled action to an
77
+ * agent, which is both noisy and a privacy problem (the agent sees
78
+ * surface area it has no credentials for).
79
+ *
80
+ * `options.builtinDir` is a test-only hook; production callers
81
+ * should rely on the default path to the bundled plugins.
82
+ *
67
83
  * Fully self-contained — does not mutate global state.
68
84
  */
69
- static async fromProject(cwd) {
85
+ static async fromProject(cwd, options = {}) {
70
86
  const dir = cwd ?? process.cwd();
71
87
  const configDir = findRunlineDir(dir);
72
88
  if (!configDir)
73
89
  return null;
74
90
  const config = loadConfigFrom(configDir);
75
- const plugins = await discoverPlugins(configDir);
91
+ const builtinAllowlist = new Set(config.connections.map((c) => c.plugin));
92
+ const plugins = await discoverPlugins(configDir, {
93
+ builtinAllowlist,
94
+ builtinDir: options.builtinDir,
95
+ });
76
96
  const rl = new Runline({
77
97
  connections: config.connections,
78
98
  timeoutMs: config.timeoutMs,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "runline",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "description": "Code mode for agents — turn any API or command into a callable action",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",