@oisincoveney/pipeline 1.16.1 → 1.16.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.
package/dist/config.d.ts CHANGED
@@ -223,8 +223,8 @@ declare const configSchema: z.ZodObject<{
223
223
  policy: z.ZodOptional<z.ZodObject<{
224
224
  commands: z.ZodOptional<z.ZodEnum<{
225
225
  allow: "allow";
226
- "trusted-only": "trusted-only";
227
226
  deny: "deny";
227
+ "trusted-only": "trusted-only";
228
228
  }>>;
229
229
  modules: z.ZodOptional<z.ZodEnum<{
230
230
  allow: "allow";
@@ -240,6 +240,7 @@ declare const configSchema: z.ZodObject<{
240
240
  }>;
241
241
  provider: z.ZodLiteral<"toolhive">;
242
242
  token_env: z.ZodDefault<z.ZodString>;
243
+ url: z.ZodOptional<z.ZodString>;
243
244
  url_env: z.ZodDefault<z.ZodString>;
244
245
  }, z.core.$strict>>;
245
246
  mcp_servers: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
@@ -278,10 +279,10 @@ declare const configSchema: z.ZodObject<{
278
279
  }, z.core.$strict>>;
279
280
  output: z.ZodOptional<z.ZodObject<{
280
281
  format: z.ZodEnum<{
282
+ json_schema: "json_schema";
281
283
  text: "text";
282
284
  json: "json";
283
285
  jsonl: "jsonl";
284
- json_schema: "json_schema";
285
286
  }>;
286
287
  repair: z.ZodOptional<z.ZodObject<{
287
288
  enabled: z.ZodOptional<z.ZodBoolean>;
@@ -325,10 +326,10 @@ declare const configSchema: z.ZodObject<{
325
326
  disabled: "disabled";
326
327
  }>>>;
327
328
  output_formats: z.ZodOptional<z.ZodArray<z.ZodEnum<{
329
+ json_schema: "json_schema";
328
330
  text: "text";
329
331
  json: "json";
330
332
  jsonl: "jsonl";
331
- json_schema: "json_schema";
332
333
  }>>>;
333
334
  rules: z.ZodOptional<z.ZodBoolean>;
334
335
  skills: z.ZodOptional<z.ZodBoolean>;
package/dist/config.js CHANGED
@@ -132,7 +132,8 @@ const mcpGatewaySchema = z.object({
132
132
  default_profile: z.string().min(1).optional(),
133
133
  mode: z.enum(["hosted", "local"]),
134
134
  provider: z.literal("toolhive"),
135
- token_env: z.string().min(1).default("PIPELINE_MCP_GATEWAY_TOKEN"),
135
+ token_env: z.string().min(1).default("MEMORY_MCP_BASIC_AUTH"),
136
+ url: z.string().url().refine((value) => ["http:", "https:"].includes(new URL(value).protocol), { message: "MCP gateway url must use http or https" }).optional(),
136
137
  url_env: z.string().min(1).default("PIPELINE_MCP_GATEWAY_URL")
137
138
  }).strict();
138
139
  const instructionsSchema = z.object({
@@ -5,6 +5,7 @@ import { execa } from "execa";
5
5
  //#region src/mcp/gateway.ts
6
6
  const PIPELINE_GATEWAY_SERVER_ID = "pipeline-gateway";
7
7
  const DEFAULT_LOCAL_GATEWAY_URL = "http://127.0.0.1:4483/mcp";
8
+ const AUTHORIZATION_ENV_RE = /\{env:([A-Za-z_][A-Za-z0-9_]*)\}/g;
8
9
  const LEGACY_CODEX_MCP_RE = /\[mcp_servers\./;
9
10
  const LEGACY_OPENCODE_MCP_RE = /"mcp"\s*:\s*{(?!\s*"pipeline-gateway")/s;
10
11
  const LEGACY_PIPELINE_MCP_RE = /path:\s*\.mcp\.json|uvx\s+mcpm|mcpm\s+run/;
@@ -25,7 +26,7 @@ function gatewayServer(config, env = process.env) {
25
26
  const gateway = configuredGateway(config);
26
27
  const url = gatewayUrl(gateway, env);
27
28
  return {
28
- bearer_token_env_var: gateway.token_env,
29
+ headers: { Authorization: gatewayAuthorizationHeader(gateway) },
29
30
  url
30
31
  };
31
32
  }
@@ -36,6 +37,7 @@ function configuredGateway(config) {
36
37
  function gatewayUrl(gateway, env = process.env) {
37
38
  const url = env[gateway.url_env];
38
39
  if (url) return url;
40
+ if (gateway.url) return gateway.url;
39
41
  if (gateway.mode === "local") return DEFAULT_LOCAL_GATEWAY_URL;
40
42
  throw new PipelineMcpGatewayError(`MCP gateway URL is required. Set ${gateway.url_env}.`);
41
43
  }
@@ -44,6 +46,7 @@ function renderGatewayConfig(config) {
44
46
  return [
45
47
  `provider: ${gateway.provider}`,
46
48
  `mode: ${gateway.mode}`,
49
+ gateway.url ? `url: ${gateway.url}` : "",
47
50
  `url_env: ${gateway.url_env}`,
48
51
  `token_env: ${gateway.token_env}`,
49
52
  gateway.default_profile ? `default_profile: ${gateway.default_profile}` : "",
@@ -67,7 +70,7 @@ function renderOpenCodeGatewayConfig(config) {
67
70
  $schema: "https://opencode.ai/config.json",
68
71
  mcp: { [PIPELINE_GATEWAY_SERVER_ID]: {
69
72
  enabled: true,
70
- headers: { Authorization: `Bearer {env:${gateway.token_env}}` },
73
+ headers: gatewayOpenCodeHeaders(gateway),
71
74
  type: "remote",
72
75
  url: gatewayUrl(gateway)
73
76
  } }
@@ -171,6 +174,17 @@ function checkGatewayToken(gateway) {
171
174
  passed: false
172
175
  };
173
176
  }
177
+ function gatewayAuthorizationHeader(gateway) {
178
+ return `Basic {env:${gateway.token_env}}`;
179
+ }
180
+ function resolveHeaderEnvPlaceholders(value, env = process.env) {
181
+ return value.replace(AUTHORIZATION_ENV_RE, (_match, envVar) => {
182
+ return env[envVar] || `{env:${envVar}}`;
183
+ });
184
+ }
185
+ function gatewayOpenCodeHeaders(gateway) {
186
+ return { Authorization: gatewayAuthorizationHeader(gateway) };
187
+ }
174
188
  async function checkThv(cwd) {
175
189
  try {
176
190
  await execa("thv", ["version"], {
@@ -240,11 +254,12 @@ async function checkGatewayHealth(gateway) {
240
254
  }
241
255
  }
242
256
  async function firstHealthyGatewayResponse(url, gateway) {
257
+ const authorization = process.env[gateway.token_env] ? `Basic ${process.env[gateway.token_env]}` : void 0;
243
258
  for (const healthUrl of gatewayHealthUrls(url)) {
244
259
  const response = await fetch(healthUrl, {
245
260
  headers: {
246
261
  Accept: "application/json, text/event-stream",
247
- ...process.env[gateway.token_env] ? { Authorization: `Bearer ${process.env[gateway.token_env]}` } : {}
262
+ ...authorization ? { Authorization: authorization } : {}
248
263
  },
249
264
  method: "GET"
250
265
  });
@@ -287,4 +302,4 @@ function legacyContentHit(cwd, path, pattern) {
287
302
  return pattern.test(readFileSync(fullPath, "utf8")) ? path : void 0;
288
303
  }
289
304
  //#endregion
290
- export { configureGatewayHosts, gatewayServerForProfile, localGatewayStatus, renderGatewayConfig, runGatewayDoctor, startLocalGateway };
305
+ export { configureGatewayHosts, gatewayServerForProfile, localGatewayStatus, renderGatewayConfig, resolveHeaderEnvPlaceholders, runGatewayDoctor, startLocalGateway };
@@ -1,4 +1,4 @@
1
- import { gatewayServerForProfile } from "./gateway.js";
1
+ import { gatewayServerForProfile, resolveHeaderEnvPlaceholders } from "./gateway.js";
2
2
  import { mkdtempSync } from "node:fs";
3
3
  import { join } from "node:path";
4
4
  import { tmpdir } from "node:os";
@@ -74,7 +74,7 @@ function codexMcpArgs(servers) {
74
74
  if (isRemoteMcpServer(server)) return [
75
75
  "--config",
76
76
  `mcp_servers.${id}.url=${tomlValue(server.url)}`,
77
- ...server.headers ? ["--config", `mcp_servers.${id}.http_headers=${tomlValue(server.headers)}`] : [],
77
+ ...server.headers ? ["--config", `mcp_servers.${id}.http_headers=${tomlValue(codexHttpHeaders(server.headers))}`] : [],
78
78
  ...server.bearer_token_env_var ? ["--config", `mcp_servers.${id}.bearer_token_env_var=${tomlValue(server.bearer_token_env_var)}`] : []
79
79
  ];
80
80
  return [
@@ -85,6 +85,9 @@ function codexMcpArgs(servers) {
85
85
  ];
86
86
  });
87
87
  }
88
+ function codexHttpHeaders(headers) {
89
+ return Object.fromEntries(Object.entries(headers).map(([key, value]) => [key, resolveHeaderEnvPlaceholders(value)]));
90
+ }
88
91
  function tomlValue(value) {
89
92
  if (Array.isArray(value)) return `[${value.map(tomlValue).join(", ")}]`;
90
93
  if (value && typeof value === "object") return `{ ${Object.entries(value).map(([key, item]) => `${tomlKey(key)} = ${tomlValue(item)}`).join(", ")} }`;
@@ -353,7 +353,7 @@ mcp_gateway:
353
353
  provider: toolhive
354
354
  mode: local
355
355
  url_env: PIPELINE_MCP_GATEWAY_URL
356
- token_env: PIPELINE_MCP_GATEWAY_TOKEN
356
+ token_env: MEMORY_MCP_BASIC_AUTH
357
357
  default_profile: default
358
358
 
359
359
  profiles:
@@ -150,8 +150,9 @@ MCP-enabled profiles use one gateway grant:
150
150
  mcp_gateway:
151
151
  provider: toolhive
152
152
  mode: hosted
153
+ url: https://pipeline-mcp.momokaya.ee/mcp/
153
154
  url_env: PIPELINE_MCP_GATEWAY_URL
154
- token_env: PIPELINE_MCP_GATEWAY_TOKEN
155
+ token_env: MEMORY_MCP_BASIC_AUTH
155
156
  default_profile: default
156
157
 
157
158
  profiles:
@@ -52,8 +52,9 @@ Example profile config:
52
52
  mcp_gateway:
53
53
  provider: toolhive
54
54
  mode: hosted
55
+ url: https://pipeline-mcp.momokaya.ee/mcp/
55
56
  url_env: PIPELINE_MCP_GATEWAY_URL
56
- token_env: PIPELINE_MCP_GATEWAY_TOKEN
57
+ token_env: MEMORY_MCP_BASIC_AUTH
57
58
  default_profile: default
58
59
 
59
60
  profiles:
@@ -378,8 +378,9 @@ Use the same client config shape for hosted and local gateways:
378
378
  mcp_gateway:
379
379
  provider: toolhive
380
380
  mode: hosted
381
+ url: https://pipeline-mcp.momokaya.ee/mcp/
381
382
  url_env: PIPELINE_MCP_GATEWAY_URL
382
- token_env: PIPELINE_MCP_GATEWAY_TOKEN
383
+ token_env: MEMORY_MCP_BASIC_AUTH
383
384
  default_profile: default
384
385
  ```
385
386
 
@@ -422,7 +423,7 @@ startup:
422
423
  # Codex pipeline runs receive MCP gateway config through runtime launch args.
423
424
  # Persistent Codex MCP config is intentionally left empty to avoid startup-time MCP fan-out.
424
425
  # gateway_url = "https://gateway.example/mcp"
425
- # token_env = "PIPELINE_MCP_GATEWAY_TOKEN"
426
+ # token_env = "MEMORY_MCP_BASIC_AUTH"
426
427
  ```
427
428
 
428
429
  OpenCode receives:
@@ -526,8 +527,9 @@ singleton gateway server to profiles that need MCP.
526
527
  mcp_gateway:
527
528
  provider: toolhive
528
529
  mode: hosted
530
+ url: https://pipeline-mcp.momokaya.ee/mcp/
529
531
  url_env: PIPELINE_MCP_GATEWAY_URL
530
- token_env: PIPELINE_MCP_GATEWAY_TOKEN
532
+ token_env: MEMORY_MCP_BASIC_AUTH
531
533
 
532
534
  profiles:
533
535
  pipeline-router:
package/package.json CHANGED
@@ -99,7 +99,7 @@
99
99
  "prepack": "bun run build:cli"
100
100
  },
101
101
  "type": "module",
102
- "version": "1.16.1",
102
+ "version": "1.16.2",
103
103
  "description": "Config-driven multi-agent pipeline runner for repository work",
104
104
  "main": "./dist/index.js",
105
105
  "types": "./dist/index.d.ts",