runline 0.29.0 → 0.30.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 (69) hide show
  1. package/dist/auth/errors.d.ts +22 -0
  2. package/dist/auth/errors.js +25 -0
  3. package/dist/auth/oauth2.d.ts +21 -0
  4. package/dist/auth/oauth2.js +154 -0
  5. package/dist/auth/token.d.ts +11 -0
  6. package/dist/auth/token.js +231 -0
  7. package/dist/auth/types.d.ts +93 -0
  8. package/dist/auth/types.js +1 -0
  9. package/dist/commands/auth.js +26 -13
  10. package/dist/commands/connection.js +3 -6
  11. package/dist/commands/exec.js +7 -2
  12. package/dist/commands/init.js +9 -2
  13. package/dist/config/loader.d.ts +7 -13
  14. package/dist/config/loader.js +58 -88
  15. package/dist/config/store.d.ts +17 -0
  16. package/dist/config/store.js +85 -0
  17. package/dist/connections/file.d.ts +13 -0
  18. package/dist/connections/file.js +53 -0
  19. package/dist/connections/memory.d.ts +15 -0
  20. package/dist/connections/memory.js +70 -0
  21. package/dist/connections/types.d.ts +47 -0
  22. package/dist/connections/types.js +10 -0
  23. package/dist/core/engine.d.ts +5 -2
  24. package/dist/core/engine.js +48 -55
  25. package/dist/core/oauth.d.ts +20 -15
  26. package/dist/core/oauth.js +195 -98
  27. package/dist/credentials/http.d.ts +19 -0
  28. package/dist/credentials/http.js +109 -0
  29. package/dist/credentials/policy.d.ts +5 -0
  30. package/dist/credentials/policy.js +92 -0
  31. package/dist/credentials/registry.d.ts +31 -0
  32. package/dist/credentials/registry.js +171 -0
  33. package/dist/credentials/transport.d.ts +38 -0
  34. package/dist/credentials/transport.js +283 -0
  35. package/dist/credentials/types.d.ts +80 -0
  36. package/dist/credentials/types.js +1 -0
  37. package/dist/index.d.ts +12 -0
  38. package/dist/index.js +8 -0
  39. package/dist/plugin/types.d.ts +30 -17
  40. package/dist/plugins/_shared/credentialAdapter.js +88 -0
  41. package/dist/plugins/_shared/googleAuth.js +89 -103
  42. package/dist/plugins/_shared/googleCredentials.js +160 -0
  43. package/dist/plugins/_shared/microsoftAuth.js +81 -74
  44. package/dist/plugins/_shared/microsoftCredentials.js +90 -0
  45. package/dist/plugins/_shared/tokenRefresh.js +39 -0
  46. package/dist/plugins/bitwarden/src/index.js +13 -31
  47. package/dist/plugins/gmail/src/index.js +8 -44
  48. package/dist/plugins/googleAppsScript/src/index.js +3 -25
  49. package/dist/plugins/googleCalendar/src/index.js +3 -41
  50. package/dist/plugins/googleContacts/src/index.js +3 -36
  51. package/dist/plugins/googleDocs/src/index.js +5 -0
  52. package/dist/plugins/googleDocs/src/shared.js +2 -30
  53. package/dist/plugins/googleDrive/src/index.js +52 -98
  54. package/dist/plugins/googleSheets/src/index.js +3 -40
  55. package/dist/plugins/googleSlides/src/index.js +5 -39
  56. package/dist/plugins/googleTasks/src/index.js +3 -30
  57. package/dist/plugins/halopsa/src/index.js +16 -31
  58. package/dist/plugins/microsoftCalendar/src/index.js +2 -1
  59. package/dist/plugins/microsoftFiles/src/index.js +10 -24
  60. package/dist/plugins/microsoftMail/src/index.js +2 -1
  61. package/dist/plugins/paypal/src/index.js +14 -29
  62. package/dist/plugins/plaud/src/index.js +210 -0
  63. package/dist/plugins/plaud/src/shared.js +221 -0
  64. package/dist/plugins/salesforce/src/shared.js +17 -32
  65. package/dist/sdk.d.ts +13 -5
  66. package/dist/sdk.js +35 -29
  67. package/dist/utils/observer.d.ts +2 -0
  68. package/dist/utils/observer.js +11 -0
  69. package/package.json +1 -1
package/dist/sdk.d.ts CHANGED
@@ -1,9 +1,13 @@
1
- import { type ActionInvocation, type ExecuteResult } from "./core/engine.js";
1
+ import type { ConnectionProvider } from "./connections/types.js";
2
+ import { type EngineHooks, type ExecuteResult } from "./core/engine.js";
2
3
  import type { PluginFunction } from "./plugin/api.js";
3
4
  import type { ActionAccess, ConnectionConfig, InputSchema, PluginDef } from "./plugin/types.js";
4
5
  export interface RunlineOptions {
5
6
  plugins?: Array<PluginDef | PluginFunction>;
7
+ /** Initial process-local connections. No environment lookup or disk writes. */
6
8
  connections?: ConnectionConfig[];
9
+ /** Host-owned credentials; mutually exclusive with initial connections. */
10
+ connectionProvider?: ConnectionProvider;
7
11
  timeoutMs?: number;
8
12
  memoryLimitBytes?: number;
9
13
  /**
@@ -19,7 +23,7 @@ export interface RunlineOptions {
19
23
  * never breaks a run. Not part of `RunlineConfig` on purpose —
20
24
  * config round-trips through JSON (`fromProject`), functions do not.
21
25
  */
22
- onAction?: (info: ActionInvocation) => void;
26
+ onAction?: EngineHooks["onAction"];
23
27
  }
24
28
  export interface RunlineExecuteOptions {
25
29
  timeoutMs?: number;
@@ -30,10 +34,11 @@ export interface RunlineExecuteOptions {
30
34
  export declare class Runline {
31
35
  private _registry;
32
36
  private _config;
37
+ private readonly _connectionProvider;
38
+ private readonly _memoryConnections?;
33
39
  /**
34
40
  * One engine per Runline instance, so its pooled worker survives across
35
- * `execute()` calls. Constructing an engine per call would spawn (and
36
- * leak) a fresh worker every time — the exact bug pooling exists to fix.
41
+ * `execute()` calls and avoids per-execution thread allocation.
37
42
  */
38
43
  private _engine;
39
44
  private readonly _onAction;
@@ -65,7 +70,10 @@ export declare class Runline {
65
70
  actions: string[];
66
71
  connectionConfigSchema?: PluginDef["connectionConfigSchema"];
67
72
  }>;
68
- /** Return all connections currently configured. */
73
+ /**
74
+ * Snapshot of process-local connections. Host-managed providers are not
75
+ * enumerated: their accounts can be caller-scoped and must be listed by the host.
76
+ */
69
77
  connections(): ConnectionConfig[];
70
78
  /**
71
79
  * Load runline from a project directory.
package/dist/sdk.js CHANGED
@@ -1,6 +1,9 @@
1
- import { existsSync, readFileSync } from "node:fs";
2
- import { join } from "node:path";
1
+ import { existsSync } from "node:fs";
2
+ import { join, resolve } from "node:path";
3
+ import { loadConfigFrom } from "./config/loader.js";
3
4
  import { DEFAULT_CONFIG } from "./config/types.js";
5
+ import { FileConnectionProvider } from "./connections/file.js";
6
+ import { MemoryConnectionProvider } from "./connections/memory.js";
4
7
  import { ExecutionEngine, } from "./core/engine.js";
5
8
  import { resolvePluginExport } from "./plugin/api.js";
6
9
  import { discoverPlugins } from "./plugin/loader.js";
@@ -8,22 +11,33 @@ import { PluginRegistry } from "./plugin/registry.js";
8
11
  export class Runline {
9
12
  _registry;
10
13
  _config;
14
+ _connectionProvider;
15
+ _memoryConnections;
11
16
  /**
12
17
  * One engine per Runline instance, so its pooled worker survives across
13
- * `execute()` calls. Constructing an engine per call would spawn (and
14
- * leak) a fresh worker every time — the exact bug pooling exists to fix.
18
+ * `execute()` calls and avoids per-execution thread allocation.
15
19
  */
16
20
  _engine = null;
17
21
  _onAction;
18
22
  constructor(options) {
19
23
  this._registry = new PluginRegistry();
20
24
  this._onAction = options.onAction;
25
+ if (options.connectionProvider && options.connections) {
26
+ throw new Error("Pass connections or connectionProvider, not both");
27
+ }
28
+ if (options.connectionProvider) {
29
+ this._connectionProvider = options.connectionProvider;
30
+ }
31
+ else {
32
+ this._memoryConnections = new MemoryConnectionProvider(options.connections);
33
+ this._connectionProvider = this._memoryConnections;
34
+ }
21
35
  for (const pluginOrFn of options.plugins ?? []) {
22
36
  const plugin = resolvePluginExport(pluginOrFn, "unknown");
23
37
  this._registry.register(plugin);
24
38
  }
25
39
  this._config = {
26
- connections: options.connections ?? [],
40
+ connections: [],
27
41
  timeoutMs: options.timeoutMs ?? DEFAULT_CONFIG.timeoutMs,
28
42
  memoryLimitBytes: options.memoryLimitBytes ?? DEFAULT_CONFIG.memoryLimitBytes,
29
43
  ...(options.maxRunsPerWorker !== undefined
@@ -35,6 +49,7 @@ export class Runline {
35
49
  if (!this._engine) {
36
50
  this._engine = new ExecutionEngine(this._registry, this._config, {
37
51
  onAction: this._onAction,
52
+ connectionProvider: this._connectionProvider,
38
53
  });
39
54
  }
40
55
  return this._engine;
@@ -58,15 +73,14 @@ export class Runline {
58
73
  /** Register an additional plugin after creation. */
59
74
  addPlugin(pluginOrFn, connections) {
60
75
  const plugin = resolvePluginExport(pluginOrFn, "unknown");
61
- this._registry.register(plugin);
62
76
  if (connections) {
63
- this._config = {
64
- ...this._config,
65
- connections: [...this._config.connections, ...connections],
66
- };
77
+ if (!this._memoryConnections) {
78
+ throw new Error("Configure connections through the host connection provider");
79
+ }
80
+ this._memoryConnections.add(connections);
67
81
  }
68
- // The pooled worker baked in the old plugin surface and the engine holds
69
- // the old config object: both are stale now.
82
+ this._registry.register(plugin);
83
+ // Rebuild the worker's action surface; connection custody survives disposal.
70
84
  this.dispose();
71
85
  }
72
86
  /** List all available actions across all plugins. */
@@ -88,9 +102,12 @@ export class Runline {
88
102
  connectionConfigSchema: p.connectionConfigSchema,
89
103
  }));
90
104
  }
91
- /** Return all connections currently configured. */
105
+ /**
106
+ * Snapshot of process-local connections. Host-managed providers are not
107
+ * enumerated: their accounts can be caller-scoped and must be listed by the host.
108
+ */
92
109
  connections() {
93
- return [...this._config.connections];
110
+ return this._memoryConnections?.list() ?? [];
94
111
  }
95
112
  /**
96
113
  * Load runline from a project directory.
@@ -118,16 +135,17 @@ export class Runline {
118
135
  const configDir = findRunlineDir(dir);
119
136
  if (!configDir)
120
137
  return null;
121
- const config = loadConfigFrom(configDir);
138
+ const config = loadConfigFrom(join(configDir, "config.json"));
122
139
  const builtinAllowlist = new Set(config.connections.map((c) => c.plugin));
123
140
  const plugins = await discoverPlugins(configDir, {
124
141
  builtinAllowlist,
125
142
  builtinDir: options.builtinDir,
126
143
  });
127
144
  const rl = new Runline({
128
- connections: config.connections,
145
+ connectionProvider: new FileConnectionProvider(join(configDir, "config.json")),
129
146
  timeoutMs: config.timeoutMs,
130
147
  memoryLimitBytes: config.memoryLimitBytes,
148
+ maxRunsPerWorker: config.maxRunsPerWorker,
131
149
  });
132
150
  for (const plugin of plugins) {
133
151
  rl._registry.register(plugin);
@@ -136,7 +154,7 @@ export class Runline {
136
154
  }
137
155
  }
138
156
  function findRunlineDir(from) {
139
- let dir = from;
157
+ let dir = resolve(from);
140
158
  while (true) {
141
159
  if (existsSync(join(dir, ".runline")))
142
160
  return join(dir, ".runline");
@@ -147,15 +165,3 @@ function findRunlineDir(from) {
147
165
  }
148
166
  return null;
149
167
  }
150
- function loadConfigFrom(configDir) {
151
- const configPath = join(configDir, "config.json");
152
- if (!existsSync(configPath))
153
- return { ...DEFAULT_CONFIG };
154
- try {
155
- const raw = JSON.parse(readFileSync(configPath, "utf-8"));
156
- return { ...DEFAULT_CONFIG, ...raw };
157
- }
158
- catch {
159
- return { ...DEFAULT_CONFIG };
160
- }
161
- }
@@ -0,0 +1,2 @@
1
+ /** Observers cannot fail an operation, whether they throw or reject asynchronously. */
2
+ export declare function notifyObserver<T>(observer: ((event: T) => void | Promise<void>) | undefined, event: T): void;
@@ -0,0 +1,11 @@
1
+ /** Observers cannot fail an operation, whether they throw or reject asynchronously. */
2
+ export function notifyObserver(observer, event) {
3
+ if (!observer)
4
+ return;
5
+ try {
6
+ void Promise.resolve(observer(event)).catch(() => { });
7
+ }
8
+ catch {
9
+ // Operational success does not depend on observability.
10
+ }
11
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "runline",
3
- "version": "0.29.0",
3
+ "version": "0.30.0",
4
4
  "description": "Code mode for agents \u2014 turn any API or command into a callable action",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",