agent-relay-runner 0.119.3 → 0.119.7

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-relay-runner",
3
- "version": "0.119.3",
3
+ "version": "0.119.7",
4
4
  "description": "Unified provider lifecycle runner for Agent Relay",
5
5
  "type": "module",
6
6
  "bin": {
@@ -20,8 +20,8 @@
20
20
  "directory": "runner"
21
21
  },
22
22
  "dependencies": {
23
- "agent-relay-providers": "0.104.2",
24
- "agent-relay-sdk": "0.2.104",
23
+ "agent-relay-providers": "0.104.3",
24
+ "agent-relay-sdk": "0.2.105",
25
25
  "callmux": "0.23.0"
26
26
  },
27
27
  "devDependencies": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "agent-relay-runner",
3
3
  "description": "Thin Agent Relay runner bridge for Claude Code",
4
- "version": "0.119.3",
4
+ "version": "0.119.7",
5
5
  "agentRelayContracts": {
6
6
  "providerPluginProtocol": 1
7
7
  }
@@ -129,7 +129,7 @@ var claudeProviderManifest = {
129
129
  },
130
130
  slashCommands: ["/clear", "/compact", "/model", "/help"],
131
131
  resume: { supported: true, idFormat: "uuid-v4", idPattern: "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}" },
132
- home: { configDir: ".claude", envPrefix: "CLAUDE", configDirEnvVar: "CLAUDE_CONFIG_DIR", quotaCredentialFile: ".credentials.json", authItems: [".credentials.json", "statsig"] },
132
+ home: { configDir: ".claude", envPrefix: "CLAUDE", configDirEnvVar: "CLAUDE_CONFIG_DIR", quotaCredentialFile: ".credentials.json", authItems: [".credentials.json", "statsig"], globalInstructionFiles: ["CLAUDE.md"] },
133
133
  provisioning: {
134
134
  pluginManifestPath: ".claude-plugin/plugin.json",
135
135
  bundledPlugin: {
@@ -255,7 +255,7 @@ var codexProviderManifest = {
255
255
  },
256
256
  slashCommands: ["/compact", "/new"],
257
257
  resume: { supported: true, idFormat: "codex-thread-id", idPattern: "[\\w-]+" },
258
- home: { configDir: ".codex", envPrefix: "CODEX", configDirEnvVar: "CODEX_HOME", quotaCredentialFile: "auth.json", authItems: ["auth.json", "installation_id"] },
258
+ home: { configDir: ".codex", envPrefix: "CODEX", configDirEnvVar: "CODEX_HOME", quotaCredentialFile: "auth.json", authItems: ["auth.json", "installation_id"], globalInstructionFiles: ["AGENTS.md"] },
259
259
  provisioning: {
260
260
  pluginManifestPath: ".codex-plugin/plugin.json",
261
261
  bundledSkills: {
package/src/adapter.ts CHANGED
@@ -64,6 +64,7 @@ export interface ProviderConfig {
64
64
  defaultArgs: string[];
65
65
  env: Record<string, string>;
66
66
  pluginDirs: string[];
67
+ globalInstructionFiles?: string[];
67
68
  defaultCapabilities: string[];
68
69
  defaultApprovalMode: string;
69
70
  defaultTags: string[];
package/src/config.ts CHANGED
@@ -12,6 +12,7 @@ interface ProviderConfig {
12
12
  defaultArgs: string[];
13
13
  env: Record<string, string>;
14
14
  pluginDirs: string[];
15
+ globalInstructionFiles?: string[];
15
16
  defaultCapabilities: string[];
16
17
  defaultApprovalMode: string;
17
18
  defaultTags: string[];
@@ -47,11 +48,13 @@ const DEFAULT_PROVIDER_ARGS: Record<string, string[]> = {
47
48
 
48
49
  export function defaultProviderConfig(provider: string): ProviderConfig {
49
50
  const manifest = getManifest(provider);
51
+ const home = recordValue(manifest?.home);
50
52
  return {
51
53
  command: manifest?.probe?.command ?? provider,
52
54
  defaultArgs: DEFAULT_PROVIDER_ARGS[provider] ?? [],
53
55
  env: {},
54
56
  pluginDirs: [],
57
+ globalInstructionFiles: stringArray(home.globalInstructionFiles) ?? [],
55
58
  defaultCapabilities: ["chat", "code", "review"],
56
59
  defaultApprovalMode: "guarded",
57
60
  defaultTags: [],
@@ -231,6 +234,7 @@ export function loadProviderConfig(provider: string, home = agentRelayHome()): L
231
234
  defaultArgs: stringArray(raw.defaultArgs) ?? defaults.defaultArgs,
232
235
  env: stringRecord(raw.env) ?? defaults.env,
233
236
  pluginDirs: stringArray(raw.pluginDirs) ?? defaults.pluginDirs,
237
+ globalInstructionFiles: stringArray(raw.globalInstructionFiles) ?? defaults.globalInstructionFiles,
234
238
  defaultCapabilities: stringArray(raw.defaultCapabilities) ?? defaults.defaultCapabilities,
235
239
  defaultApprovalMode: stringValue(raw.defaultApprovalMode) ?? defaults.defaultApprovalMode,
236
240
  defaultTags: stringArray(raw.defaultTags) ?? defaults.defaultTags,
@@ -276,6 +280,7 @@ export function providerConfigPublic(config: LoadedProviderConfig): Record<strin
276
280
  defaultArgs: config.defaultArgs,
277
281
  env: maskEnv(config.env),
278
282
  pluginDirs: config.pluginDirs,
283
+ globalInstructionFiles: config.globalInstructionFiles ?? [],
279
284
  defaultCapabilities: config.defaultCapabilities,
280
285
  defaultApprovalMode: config.defaultApprovalMode,
281
286
  defaultTags: config.defaultTags,
@@ -398,6 +403,7 @@ function providerConfigFromValue(provider: string, value: unknown, path: string)
398
403
  defaultArgs: stringArray(raw.defaultArgs) ?? defaults.defaultArgs,
399
404
  env: stringRecord(raw.env) ?? defaults.env,
400
405
  pluginDirs: stringArray(raw.pluginDirs) ?? defaults.pluginDirs,
406
+ globalInstructionFiles: stringArray(raw.globalInstructionFiles) ?? defaults.globalInstructionFiles,
401
407
  defaultCapabilities: stringArray(raw.defaultCapabilities) ?? defaults.defaultCapabilities,
402
408
  defaultApprovalMode: stringValue(raw.defaultApprovalMode) ?? defaults.defaultApprovalMode,
403
409
  defaultTags: stringArray(raw.defaultTags) ?? defaults.defaultTags,
@@ -101,7 +101,7 @@ function prepareProviderHome(provider: SpawnProvider, config: RunnerSpawnConfig)
101
101
  const authItems = manifest?.home?.authItems ?? [];
102
102
  const sourceHome = providerSourceHome(provider);
103
103
  const authLinked = linkExistingAuthItems(sourceHome, target, authItems);
104
- linkHostGlobalInstructionFiles(provider, sourceHome, target, config);
104
+ linkHostGlobalInstructionFiles(sourceHome, target, config);
105
105
  return { path: target, authLinked };
106
106
  }
107
107
 
@@ -109,6 +109,7 @@ export const prepareCodexProfileHome = (config: RunnerSpawnConfig) => preparePro
109
109
  export const prepareClaudeProfileHome = (config: RunnerSpawnConfig) => prepareProviderHome("claude", config);
110
110
 
111
111
  function bootstrapCodexFirstRun(codexHome: string, config: RunnerSpawnConfig): void {
112
+ disableCodexAppsConnectors(codexHome);
112
113
  trustWorkspaceForCodex(codexHome, config);
113
114
  }
114
115
 
@@ -186,10 +187,11 @@ function linkExistingPath(source: string, target: string): boolean {
186
187
  return true;
187
188
  }
188
189
 
189
- function linkHostGlobalInstructionFiles(provider: SpawnProvider, sourceHome: string, targetHome: string, config: RunnerSpawnConfig): void {
190
+ function linkHostGlobalInstructionFiles(sourceHome: string, targetHome: string, config: RunnerSpawnConfig): void {
190
191
  if (!profileAllowsHostGlobalInstructions(config)) return;
191
- const files = provider === "claude" ? ["CLAUDE.md"] : provider === "codex" ? ["AGENTS.md"] : [];
192
- for (const file of files) linkExistingPath(join(sourceHome, file), join(targetHome, file));
192
+ for (const file of config.providerConfig.globalInstructionFiles ?? []) {
193
+ linkExistingPath(join(sourceHome, file), join(targetHome, file));
194
+ }
193
195
  }
194
196
 
195
197
  function trustWorkspaceForCodex(codexHome: string, config: RunnerSpawnConfig): void {
@@ -204,6 +206,50 @@ function trustWorkspaceForCodex(codexHome: string, config: RunnerSpawnConfig): v
204
206
  writeFileSync(path, `${prefix ? `${prefix}\n\n` : ""}${entry}`, { mode: 0o600 });
205
207
  }
206
208
 
209
+ function disableCodexAppsConnectors(codexHome: string): void {
210
+ const path = join(codexHome, "config.toml");
211
+ const current = existsSync(path) ? readFileSync(path, "utf8") : "";
212
+ const next = withTomlFeatureFlag(current, "apps", false);
213
+ if (next === current) return;
214
+ writeFileSync(path, next, { mode: 0o600 });
215
+ }
216
+
217
+ function withTomlFeatureFlag(input: string, key: string, value: boolean): string {
218
+ const lines = input.length ? input.split("\n") : [];
219
+ const headerIndex = lines.findIndex((line) => line.trim() === "[features]");
220
+ const entry = `${key} = ${value ? "true" : "false"}`;
221
+ if (headerIndex === -1) {
222
+ const prefix = input.trimEnd();
223
+ return `${prefix ? `${prefix}\n\n` : ""}[features]\n${entry}\n`;
224
+ }
225
+
226
+ let sectionEnd = lines.length;
227
+ for (let i = headerIndex + 1; i < lines.length; i += 1) {
228
+ const line = lines[i] ?? "";
229
+ if (/^\s*\[[^\]]+\]\s*(?:#.*)?$/.test(line)) {
230
+ sectionEnd = i;
231
+ break;
232
+ }
233
+ }
234
+
235
+ const flagPattern = new RegExp(`^\\s*${escapeRegExp(key)}\\s*=`);
236
+ for (let i = headerIndex + 1; i < sectionEnd; i += 1) {
237
+ const line = lines[i] ?? "";
238
+ if (flagPattern.test(line)) {
239
+ if (lines[i] === entry) return input;
240
+ lines[i] = entry;
241
+ return lines.join("\n");
242
+ }
243
+ }
244
+
245
+ lines.splice(headerIndex + 1, 0, entry);
246
+ return lines.join("\n");
247
+ }
248
+
249
+ function escapeRegExp(value: string): string {
250
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
251
+ }
252
+
207
253
  function writeClaudeRelayManual(claudeHome: string): void {
208
254
  const path = join(claudeHome, "CLAUDE.md");
209
255
  writeFileSync(path, claudeRelayManual(), { mode: 0o600 });