axconfig 3.0.1 → 3.2.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.
@@ -9,29 +9,40 @@ import type { AgentCli } from "axshared";
9
9
  type GetAgentConfigEnvironmentResult = {
10
10
  ok: true;
11
11
  env: Record<string, string>;
12
+ warning: string | undefined;
12
13
  } | {
13
14
  ok: false;
14
15
  error: string;
15
16
  };
16
17
  /**
17
- * Get agent-specific environment variables for a custom config directory.
18
+ * Get agent-specific environment variables for custom directories.
18
19
  *
19
- * Computes the environment variables needed to run an agent with a specific
20
- * config directory. This handles agents that require the env var to point to
21
- * a parent directory (e.g., HOME for gemini, XDG_DATA_HOME for opencode).
20
+ * Computes the environment variables needed to run an agent with specific
21
+ * config and data directories. This handles agents that require env vars to
22
+ * point to parent directories (e.g., HOME for gemini, XDG paths for opencode).
23
+ *
24
+ * **Agents without separation** (Claude, Codex, Gemini, Copilot):
25
+ * - `configDirectory` and `dataDirectory` are interchangeable
26
+ * - Either can be provided alone to set both locations
27
+ *
28
+ * **Agents with separation** (OpenCode):
29
+ * - Directories are independent
30
+ * - If only `configDirectory` provided, data uses default location
31
+ * - If only `dataDirectory` provided, config uses default location
22
32
  *
23
33
  * @param agent - The agent CLI identifier
24
- * @param configDirectory - The config directory path (must end with expected suffix for some agents)
25
- * @returns Result with agent-specific env vars, or error if configDirectory is invalid
34
+ * @param configDirectory - Custom config directory (optional)
35
+ * @param dataDirectory - Custom data directory (optional)
36
+ * @returns Result with agent-specific env vars, warning, or error
26
37
  *
27
38
  * @example
28
39
  * // Claude: env var points directly to config dir
29
40
  * getAgentConfigEnvironment("claude", "/tmp/test/.claude")
30
- * // Returns: { ok: true, env: { CLAUDE_CONFIG_DIR: "/tmp/test/.claude" } }
41
+ * // Returns: { ok: true, env: { CLAUDE_CONFIG_DIR: "/tmp/test/.claude" }, warning: undefined }
31
42
  *
32
- * // Gemini: env var points to parent (HOME), config is in .gemini subdirectory
33
- * getAgentConfigEnvironment("gemini", "/tmp/test/.gemini")
34
- * // Returns: { ok: true, env: { HOME: "/tmp/test", GEMINI_FORCE_FILE_STORAGE: "true" } }
43
+ * // OpenCode with only configDir: data uses default
44
+ * getAgentConfigEnvironment("opencode", "/tmp/config/opencode")
45
+ * // Returns: { ok: true, env: { XDG_CONFIG_HOME: "/tmp/config", XDG_DATA_HOME: "/home/user/.local/share" }, warning: "..." }
35
46
  */
36
- declare function getAgentConfigEnvironment(agent: AgentCli, configDirectory: string): GetAgentConfigEnvironmentResult;
47
+ declare function getAgentConfigEnvironment(agent: AgentCli, configDirectory?: string, dataDirectory?: string): GetAgentConfigEnvironmentResult;
37
48
  export { getAgentConfigEnvironment, type GetAgentConfigEnvironmentResult };
@@ -5,44 +5,78 @@
5
5
  * with custom config directories. Delegates to axshared for path info.
6
6
  */
7
7
  import path from "node:path";
8
- import { buildAgentRuntimeEnvironment, getAgentConfigSubdirectory, } from "axshared";
8
+ import { buildAgentRuntimeEnvironment, getAgentPathInfo, resolveAgentConfigDirectory, resolveAgentDataDirectory, resolveCustomDirectories, } from "axshared";
9
9
  /**
10
- * Get agent-specific environment variables for a custom config directory.
10
+ * Get agent-specific environment variables for custom directories.
11
11
  *
12
- * Computes the environment variables needed to run an agent with a specific
13
- * config directory. This handles agents that require the env var to point to
14
- * a parent directory (e.g., HOME for gemini, XDG_DATA_HOME for opencode).
12
+ * Computes the environment variables needed to run an agent with specific
13
+ * config and data directories. This handles agents that require env vars to
14
+ * point to parent directories (e.g., HOME for gemini, XDG paths for opencode).
15
+ *
16
+ * **Agents without separation** (Claude, Codex, Gemini, Copilot):
17
+ * - `configDirectory` and `dataDirectory` are interchangeable
18
+ * - Either can be provided alone to set both locations
19
+ *
20
+ * **Agents with separation** (OpenCode):
21
+ * - Directories are independent
22
+ * - If only `configDirectory` provided, data uses default location
23
+ * - If only `dataDirectory` provided, config uses default location
15
24
  *
16
25
  * @param agent - The agent CLI identifier
17
- * @param configDirectory - The config directory path (must end with expected suffix for some agents)
18
- * @returns Result with agent-specific env vars, or error if configDirectory is invalid
26
+ * @param configDirectory - Custom config directory (optional)
27
+ * @param dataDirectory - Custom data directory (optional)
28
+ * @returns Result with agent-specific env vars, warning, or error
19
29
  *
20
30
  * @example
21
31
  * // Claude: env var points directly to config dir
22
32
  * getAgentConfigEnvironment("claude", "/tmp/test/.claude")
23
- * // Returns: { ok: true, env: { CLAUDE_CONFIG_DIR: "/tmp/test/.claude" } }
33
+ * // Returns: { ok: true, env: { CLAUDE_CONFIG_DIR: "/tmp/test/.claude" }, warning: undefined }
24
34
  *
25
- * // Gemini: env var points to parent (HOME), config is in .gemini subdirectory
26
- * getAgentConfigEnvironment("gemini", "/tmp/test/.gemini")
27
- * // Returns: { ok: true, env: { HOME: "/tmp/test", GEMINI_FORCE_FILE_STORAGE: "true" } }
35
+ * // OpenCode with only configDir: data uses default
36
+ * getAgentConfigEnvironment("opencode", "/tmp/config/opencode")
37
+ * // Returns: { ok: true, env: { XDG_CONFIG_HOME: "/tmp/config", XDG_DATA_HOME: "/home/user/.local/share" }, warning: "..." }
28
38
  */
29
- function getAgentConfigEnvironment(agent, configDirectory) {
30
- const subdirectory = getAgentConfigSubdirectory(agent);
31
- const resolvedConfigDirectory = path.resolve(configDirectory);
32
- // Validate subdirectory suffix for agents that require it
33
- if (subdirectory !== undefined) {
34
- const actualSuffix = path.basename(resolvedConfigDirectory);
35
- if (actualSuffix !== subdirectory) {
39
+ function getAgentConfigEnvironment(agent, configDirectory, dataDirectory) {
40
+ const pathInfo = getAgentPathInfo(agent);
41
+ // Resolve directories based on agent capabilities
42
+ const resolved = resolveCustomDirectories(agent, configDirectory, dataDirectory);
43
+ if (!resolved.ok) {
44
+ return { ok: false, error: resolved.error };
45
+ }
46
+ // Determine effective directories using resolved values or defaults
47
+ const effectiveConfigDirectory = resolved.configDir
48
+ ? path.resolve(resolved.configDir)
49
+ : resolveAgentConfigDirectory(agent);
50
+ const effectiveDataDirectory = resolved.dataDir
51
+ ? path.resolve(resolved.dataDir)
52
+ : resolveAgentDataDirectory(agent);
53
+ // Validate config subdirectory suffix for agents that require it
54
+ if (pathInfo.subdirectory !== undefined) {
55
+ const actualSuffix = path.basename(effectiveConfigDirectory);
56
+ if (actualSuffix !== pathInfo.subdirectory) {
57
+ return {
58
+ ok: false,
59
+ error: `Config directory for ${agent} must end with '${pathInfo.subdirectory}', got '${actualSuffix}'.\n` +
60
+ `Expected path like: /some/path/${pathInfo.subdirectory}`,
61
+ };
62
+ }
63
+ }
64
+ // Validate data subdirectory suffix for agents that require it
65
+ const dataSubdirectory = pathInfo.dataSubdirectory ?? pathInfo.subdirectory;
66
+ if (dataSubdirectory !== undefined) {
67
+ const actualSuffix = path.basename(effectiveDataDirectory);
68
+ if (actualSuffix !== dataSubdirectory) {
36
69
  return {
37
70
  ok: false,
38
- error: `Config directory for ${agent} must end with '${subdirectory}', got '${actualSuffix}'.\n` +
39
- `Expected path like: /some/path/${subdirectory}`,
71
+ error: `Data directory for ${agent} must end with '${dataSubdirectory}', got '${actualSuffix}'.\n` +
72
+ `Expected path like: /some/path/${dataSubdirectory}`,
40
73
  };
41
74
  }
42
75
  }
43
76
  return {
44
77
  ok: true,
45
- env: buildAgentRuntimeEnvironment(agent, resolvedConfigDirectory),
78
+ env: buildAgentRuntimeEnvironment(agent, effectiveConfigDirectory, effectiveDataDirectory),
79
+ warning: resolved.warning,
46
80
  };
47
81
  }
48
82
  export { getAgentConfigEnvironment };
package/dist/types.d.ts CHANGED
@@ -140,11 +140,17 @@ interface ConfigReader {
140
140
  */
141
141
  subdirectory: string | undefined;
142
142
  /**
143
- * Build environment variables for running this agent with a custom config directory.
144
- * @param basePath - The base path (parent of subdirectory, or config dir if no subdirectory)
143
+ * Build environment variables for running this agent with custom directories.
144
+ *
145
+ * For agents that support separate config and data directories (OpenCode),
146
+ * both paths can differ. For agents that don't support separation, both
147
+ * paths will typically be the same.
148
+ *
149
+ * @param configBasePath - The base path for configuration
150
+ * @param dataBasePath - The base path for data
145
151
  * @returns Environment variables to set for the agent
146
152
  */
147
- buildRuntimeEnvironment: (basePath: string) => Record<string, string>;
153
+ buildRuntimeEnvironment: (configBasePath: string, dataBasePath: string) => Record<string, string>;
148
154
  /** Read permissions from agent config and translate to unified format */
149
155
  readPermissions: (configDirectory: string) => ReadPermissionsResult;
150
156
  /** Read model from agent config */
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "axconfig",
3
3
  "author": "Łukasz Jerciński",
4
4
  "license": "MIT",
5
- "version": "3.0.1",
5
+ "version": "3.2.0",
6
6
  "description": "Unified configuration management for AI coding agents - common API for permissions, settings, and config across Claude Code, Codex, Gemini CLI, and OpenCode",
7
7
  "repository": {
8
8
  "type": "git",
@@ -68,7 +68,7 @@
68
68
  "dependencies": {
69
69
  "@commander-js/extra-typings": "^14.0.0",
70
70
  "@iarna/toml": "^2.2.5",
71
- "axshared": "^1.3.0",
71
+ "axshared": "^1.5.0",
72
72
  "commander": "^14.0.2"
73
73
  },
74
74
  "devDependencies": {