axconfig 3.2.0 → 3.3.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.
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Gemini CLI settings utilities.
3
+ */
4
+ type NestedRecord = Record<string, unknown>;
5
+ /**
6
+ * Read existing settings.json, returning empty object if not found.
7
+ * Throws if file exists but contains invalid JSON to prevent data loss.
8
+ */
9
+ export declare function readExistingSettings(settingsPath: string): NestedRecord;
10
+ /**
11
+ * Merge existing settings with security.environmentVariableRedaction.enabled = false.
12
+ */
13
+ export declare function mergeSecuritySettings(existing: NestedRecord): NestedRecord;
14
+ export {};
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Gemini CLI settings utilities.
3
+ */
4
+ import { existsSync, readFileSync } from "node:fs";
5
+ /**
6
+ * Read existing settings.json, returning empty object if not found.
7
+ * Throws if file exists but contains invalid JSON to prevent data loss.
8
+ */
9
+ export function readExistingSettings(settingsPath) {
10
+ if (!existsSync(settingsPath)) {
11
+ return {};
12
+ }
13
+ try {
14
+ const content = readFileSync(settingsPath, "utf8");
15
+ return JSON.parse(content);
16
+ }
17
+ catch (error) {
18
+ const message = error instanceof Error ? error.message : String(error);
19
+ throw new Error(`Failed to parse existing settings at ${settingsPath}: ${message}`);
20
+ }
21
+ }
22
+ /**
23
+ * Merge existing settings with security.environmentVariableRedaction.enabled = false.
24
+ */
25
+ export function mergeSecuritySettings(existing) {
26
+ const security = (existing.security ?? {});
27
+ const redaction = (security.environmentVariableRedaction ??
28
+ {});
29
+ return {
30
+ ...existing,
31
+ security: {
32
+ ...security,
33
+ environmentVariableRedaction: { ...redaction, enabled: false },
34
+ },
35
+ };
36
+ }
@@ -8,10 +8,11 @@
8
8
  * - Bash patterns via commandPrefix
9
9
  * - Does NOT support path restrictions
10
10
  */
11
- import { existsSync, mkdirSync, readFileSync } from "node:fs";
11
+ import { mkdirSync } from "node:fs";
12
12
  import path from "node:path";
13
13
  import { atomicWriteFileSync } from "../atomic-write.js";
14
14
  import { registerConfigBuilder } from "../builder.js";
15
+ import { mergeSecuritySettings, readExistingSettings, } from "./gemini-settings.js";
15
16
  // Re-export reader
16
17
  export { geminiConfigReader } from "./gemini-reader.js";
17
18
  /** Gemini CLI tool name mapping */
@@ -56,23 +57,6 @@ commandPrefix = ${prefixValue}
56
57
  decision = "${decision}"
57
58
  priority = ${priority}`;
58
59
  }
59
- /**
60
- * Read existing settings.json, returning empty object if not found.
61
- * Throws if file exists but contains invalid JSON to prevent data loss.
62
- */
63
- function readExistingSettings(settingsPath) {
64
- if (!existsSync(settingsPath)) {
65
- return {};
66
- }
67
- try {
68
- const content = readFileSync(settingsPath, "utf8");
69
- return JSON.parse(content);
70
- }
71
- catch (error) {
72
- const message = error instanceof Error ? error.message : String(error);
73
- throw new Error(`Failed to parse existing settings at ${settingsPath}: ${message}`);
74
- }
75
- }
76
60
  /**
77
61
  * Build Gemini CLI configuration.
78
62
  *
@@ -149,10 +133,6 @@ function build(config, output) {
149
133
  if (denyBash.length > 0) {
150
134
  rules.push(generateBashRule(denyBash, "deny", 499));
151
135
  }
152
- // Default deny for shell commands not explicitly allowed
153
- if (allowBash.length > 0 || denyBash.length > 0) {
154
- rules.push(generateToolRule(["run_shell_command"], "deny", 1));
155
- }
156
136
  }
157
137
  // Write policy file
158
138
  const policyPath = path.join(policiesDirectory, "axconfig.toml");
@@ -161,7 +141,10 @@ function build(config, output) {
161
141
  // Write settings.json, preserving existing settings (e.g., model)
162
142
  const settingsPath = path.join(output, "settings.json");
163
143
  const existingSettings = readExistingSettings(settingsPath);
164
- atomicWriteFileSync(settingsPath, JSON.stringify(existingSettings, undefined, 2));
144
+ // Disable Gemini's environment variable redaction so shell commands
145
+ // can access tokens like GH_TOKEN in CI environments
146
+ const settings = mergeSecuritySettings(existingSettings);
147
+ atomicWriteFileSync(settingsPath, JSON.stringify(settings, undefined, 2));
165
148
  return {
166
149
  ok: true,
167
150
  env: { GEMINI_DIR: output },
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.2.0",
5
+ "version": "3.3.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.5.0",
71
+ "axshared": "^1.7.0",
72
72
  "commander": "^14.0.2"
73
73
  },
74
74
  "devDependencies": {
@@ -78,18 +78,18 @@
78
78
  "@types/iarna__toml": "^2.0.5",
79
79
  "@types/node": "^25.0.3",
80
80
  "@vitest/coverage-v8": "^4.0.16",
81
- "@vitest/eslint-plugin": "^1.5.4",
81
+ "@vitest/eslint-plugin": "^1.6.5",
82
82
  "eslint": "^9.39.2",
83
83
  "eslint-config-prettier": "^10.1.8",
84
84
  "eslint-plugin-unicorn": "^62.0.0",
85
85
  "fta-check": "^1.5.1",
86
86
  "fta-cli": "^3.0.0",
87
- "globals": "^16.5.0",
88
- "knip": "^5.76.1",
87
+ "globals": "^17.0.0",
88
+ "knip": "^5.79.0",
89
89
  "prettier": "3.7.4",
90
90
  "semantic-release": "^25.0.2",
91
91
  "typescript": "^5.9.3",
92
- "typescript-eslint": "^8.50.0",
92
+ "typescript-eslint": "^8.51.0",
93
93
  "vitest": "^4.0.16"
94
94
  }
95
95
  }