claude-yes 1.46.5 → 1.47.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.
@@ -10118,7 +10118,7 @@ const globalAgentRegistry = new AgentRegistry();
10118
10118
 
10119
10119
  //#endregion
10120
10120
  //#region ts/index.ts
10121
- const config = await import("./agent-yes.config-DQLH9OgO.js").then((mod) => mod.default || mod);
10121
+ const config = await import("./agent-yes.config-DgkhZ7eQ.js").then((mod) => mod.default || mod);
10122
10122
  const CLIS_CONFIG = config.clis;
10123
10123
  /**
10124
10124
  * Main function to run agent-cli with automatic yes/no responses
@@ -10735,4 +10735,4 @@ const SUPPORTED_CLIS = Object.keys(CLIS_CONFIG);
10735
10735
 
10736
10736
  //#endregion
10737
10737
  export { AgentContext as a, config as i, CLIS_CONFIG as n, PidStore as o, agentYes as r, removeControlCharacters as s, SUPPORTED_CLIS as t };
10738
- //# sourceMappingURL=SUPPORTED_CLIS-BwukLRmP.js.map
10738
+ //# sourceMappingURL=SUPPORTED_CLIS-OBl9bioJ.js.map
@@ -1,7 +1,8 @@
1
1
  import { t as logger } from "./logger-DH1Rx9HI.js";
2
- import { mkdir } from "node:fs/promises";
2
+ import { access, mkdir, readFile } from "node:fs/promises";
3
3
  import os from "node:os";
4
4
  import path from "node:path";
5
+ import { parse } from "yaml";
5
6
 
6
7
  //#region ts/defineConfig.ts
7
8
  async function defineCliYesConfig(cfg) {
@@ -20,6 +21,94 @@ function deepMixin(target, source, ...more) {
20
21
  return target;
21
22
  }
22
23
 
24
+ //#endregion
25
+ //#region ts/configLoader.ts
26
+ //! Config file loader with cascading support
27
+ //! Supports JSON, YAML, YML formats
28
+ //! Priority: project-dir > home-dir > package-dir
29
+ const CONFIG_FILENAME = ".agent-yes.config";
30
+ const CONFIG_EXTENSIONS = [
31
+ ".json",
32
+ ".yml",
33
+ ".yaml"
34
+ ];
35
+ /**
36
+ * Check if a file exists
37
+ */
38
+ async function fileExists(filepath) {
39
+ try {
40
+ await access(filepath);
41
+ return true;
42
+ } catch {
43
+ return false;
44
+ }
45
+ }
46
+ /**
47
+ * Parse config file based on extension
48
+ */
49
+ async function parseConfigFile(filepath) {
50
+ const content = await readFile(filepath, "utf-8");
51
+ const ext = path.extname(filepath).toLowerCase();
52
+ switch (ext) {
53
+ case ".json": return JSON.parse(content);
54
+ case ".yml":
55
+ case ".yaml": return parse(content) ?? {};
56
+ default: throw new Error(`Unsupported config file extension: ${ext}`);
57
+ }
58
+ }
59
+ /**
60
+ * Find config file in a directory (checks all supported extensions)
61
+ */
62
+ async function findConfigInDir(dir) {
63
+ for (const ext of CONFIG_EXTENSIONS) {
64
+ const filepath = path.join(dir, `${CONFIG_FILENAME}${ext}`);
65
+ if (await fileExists(filepath)) return filepath;
66
+ }
67
+ return null;
68
+ }
69
+ /**
70
+ * Load config from a directory if it exists
71
+ */
72
+ async function loadConfigFromDir(dir) {
73
+ const filepath = await findConfigInDir(dir);
74
+ if (!filepath) return {};
75
+ try {
76
+ logger.debug(`[config] Loading config from: ${filepath}`);
77
+ return await parseConfigFile(filepath);
78
+ } catch (error) {
79
+ logger.warn(`[config] Failed to parse config file ${filepath}:`, error);
80
+ return {};
81
+ }
82
+ }
83
+ /**
84
+ * Get the package directory (where agent-yes is installed)
85
+ */
86
+ function getPackageDir() {
87
+ return path.dirname(new URL(import.meta.url).pathname);
88
+ }
89
+ /**
90
+ * Load configs from cascading locations and merge them
91
+ * Priority (highest to lowest): project-dir > home-dir > package-dir
92
+ * Higher priority configs override lower priority ones
93
+ */
94
+ async function loadCascadingConfig(options = {}) {
95
+ const projectDir = options.projectDir ?? process.cwd();
96
+ const homeDir = options.homeDir ?? os.homedir();
97
+ const packageDir = getPackageDir();
98
+ const nonEmptyConfigs = (await Promise.all([
99
+ loadConfigFromDir(packageDir),
100
+ loadConfigFromDir(homeDir),
101
+ loadConfigFromDir(projectDir)
102
+ ])).filter((c) => c && Object.keys(c).length > 0);
103
+ if (nonEmptyConfigs.length === 0) {
104
+ logger.debug("[config] No config files found in any location");
105
+ return {};
106
+ }
107
+ const merged = deepMixin({}, ...nonEmptyConfigs);
108
+ logger.debug("[config] Merged config from", nonEmptyConfigs.length, "sources");
109
+ return merged;
110
+ }
111
+
23
112
  //#endregion
24
113
  //#region agent-yes.config.ts
25
114
  logger.debug("loading cli-yes.config.ts from " + import.meta.url);
@@ -35,7 +124,13 @@ const configDir = await (async () => {
35
124
  return tmpConfigDir;
36
125
  }
37
126
  })();
38
- var agent_yes_config_default = deepMixin(await getDefaultConfig(), await import(path.resolve(os.homedir(), ".agent-yes/config.ts")).catch(() => ({ default: {} })).then((mod) => mod.default), await import(path.resolve(process.cwd(), "node_modules/.agent-yes/config.ts")).catch(() => ({ default: {} })).then((mod) => mod.default), await import(path.resolve(process.cwd(), ".agent-yes/config.ts")).catch(() => ({ default: {} })).then((mod) => mod.default));
127
+ const cascadingConfig = await loadCascadingConfig();
128
+ const legacyConfigs = await Promise.all([
129
+ import(path.resolve(os.homedir(), ".agent-yes/config.ts")).catch(() => ({ default: {} })).then((mod) => mod.default),
130
+ import(path.resolve(process.cwd(), "node_modules/.agent-yes/config.ts")).catch(() => ({ default: {} })).then((mod) => mod.default),
131
+ import(path.resolve(process.cwd(), ".agent-yes/config.ts")).catch(() => ({ default: {} })).then((mod) => mod.default)
132
+ ]);
133
+ var agent_yes_config_default = deepMixin(await getDefaultConfig(), cascadingConfig, ...legacyConfigs);
39
134
  function getDefaultConfig() {
40
135
  return defineCliYesConfig({
41
136
  configDir,
@@ -157,4 +252,4 @@ function getDefaultConfig() {
157
252
 
158
253
  //#endregion
159
254
  export { agent_yes_config_default as t };
160
- //# sourceMappingURL=agent-yes.config-CrlZMQo-.js.map
255
+ //# sourceMappingURL=agent-yes.config-CUuciqYW.js.map
@@ -1,4 +1,4 @@
1
1
  import "./logger-DH1Rx9HI.js";
2
- import { t as agent_yes_config_default } from "./agent-yes.config-CrlZMQo-.js";
2
+ import { t as agent_yes_config_default } from "./agent-yes.config-CUuciqYW.js";
3
3
 
4
4
  export { agent_yes_config_default as default };
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env bun
2
2
  import { c as __toESM, i as __commonJSMin, r as require_ms, t as logger } from "./logger-DH1Rx9HI.js";
3
- import "./agent-yes.config-CrlZMQo-.js";
4
- import { o as PidStore, t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-BwukLRmP.js";
3
+ import "./agent-yes.config-CUuciqYW.js";
4
+ import { o as PidStore, t as SUPPORTED_CLIS } from "./SUPPORTED_CLIS-OBl9bioJ.js";
5
5
  import { createRequire } from "node:module";
6
6
  import { argv } from "process";
7
7
  import { spawn } from "child_process";
@@ -4505,7 +4505,7 @@ const Yargs = YargsFactory(esm_default);
4505
4505
  //#endregion
4506
4506
  //#region package.json
4507
4507
  var name = "agent-yes";
4508
- var version = "1.46.5";
4508
+ var version = "1.47.0";
4509
4509
 
4510
4510
  //#endregion
4511
4511
  //#region ts/parseCliArgs.ts
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
1
  import "./logger-DH1Rx9HI.js";
2
- import { a as AgentContext, i as config, n as CLIS_CONFIG, r as agentYes, s as removeControlCharacters } from "./SUPPORTED_CLIS-BwukLRmP.js";
2
+ import { a as AgentContext, i as config, n as CLIS_CONFIG, r as agentYes, s as removeControlCharacters } from "./SUPPORTED_CLIS-OBl9bioJ.js";
3
3
 
4
4
  export { AgentContext, CLIS_CONFIG, config, agentYes as default, removeControlCharacters };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-yes",
3
- "version": "1.46.5",
3
+ "version": "1.47.0",
4
4
  "description": "A wrapper tool that automates interactions with various AI CLI tools by automatically handling common prompts and responses.",
5
5
  "keywords": [
6
6
  "ai",
@@ -82,7 +82,8 @@
82
82
  "@snomiao/bun-pty": "^0.3.4",
83
83
  "@snomiao/keyv-sqlite": "^5.0.4",
84
84
  "bun-pty": "^0.4.8",
85
- "from-node-stream": "^0.1.2"
85
+ "from-node-stream": "^0.1.2",
86
+ "yaml": "^2.8.2"
86
87
  },
87
88
  "devDependencies": {
88
89
  "@semantic-release/exec": "^7.1.0",
@@ -0,0 +1,127 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from "bun:test";
2
+ import { loadCascadingConfig, getConfigPaths } from "./configLoader.ts";
3
+ import { mkdir, writeFile, rm } from "node:fs/promises";
4
+ import path from "node:path";
5
+ import os from "node:os";
6
+
7
+ describe("configLoader", () => {
8
+ const testDir = path.join(os.tmpdir(), "agent-yes-config-test");
9
+
10
+ beforeEach(async () => {
11
+ await mkdir(testDir, { recursive: true });
12
+ });
13
+
14
+ afterEach(async () => {
15
+ await rm(testDir, { recursive: true, force: true });
16
+ });
17
+
18
+ it("should load JSON config", async () => {
19
+ const configPath = path.join(testDir, ".agent-yes.config.json");
20
+ await writeFile(
21
+ configPath,
22
+ JSON.stringify({
23
+ configDir: "/custom/config",
24
+ clis: {
25
+ claude: {
26
+ defaultArgs: ["--verbose"],
27
+ },
28
+ },
29
+ })
30
+ );
31
+
32
+ const config = await loadCascadingConfig({ projectDir: testDir });
33
+ expect(config.configDir).toBe("/custom/config");
34
+ expect(config.clis?.claude?.defaultArgs).toEqual(["--verbose"]);
35
+ });
36
+
37
+ it("should load YAML config", async () => {
38
+ const configPath = path.join(testDir, ".agent-yes.config.yaml");
39
+ await writeFile(
40
+ configPath,
41
+ `
42
+ configDir: /custom/yaml/config
43
+ clis:
44
+ gemini:
45
+ defaultArgs:
46
+ - --resume
47
+ `
48
+ );
49
+
50
+ const config = await loadCascadingConfig({ projectDir: testDir });
51
+ expect(config.configDir).toBe("/custom/yaml/config");
52
+ expect(config.clis?.gemini?.defaultArgs).toEqual(["--resume"]);
53
+ });
54
+
55
+ it("should load YML config", async () => {
56
+ const configPath = path.join(testDir, ".agent-yes.config.yml");
57
+ await writeFile(
58
+ configPath,
59
+ `
60
+ logsDir: /custom/logs
61
+ `
62
+ );
63
+
64
+ const config = await loadCascadingConfig({ projectDir: testDir });
65
+ expect(config.logsDir).toBe("/custom/logs");
66
+ });
67
+
68
+ it("should prefer JSON over YAML when both exist", async () => {
69
+ await writeFile(
70
+ path.join(testDir, ".agent-yes.config.json"),
71
+ JSON.stringify({ configDir: "/json/config" })
72
+ );
73
+ await writeFile(
74
+ path.join(testDir, ".agent-yes.config.yaml"),
75
+ `configDir: /yaml/config`
76
+ );
77
+
78
+ const config = await loadCascadingConfig({ projectDir: testDir });
79
+ expect(config.configDir).toBe("/json/config");
80
+ });
81
+
82
+ it("should return config paths", () => {
83
+ const paths = getConfigPaths({ projectDir: testDir });
84
+ expect(paths.length).toBeGreaterThan(0);
85
+ expect(paths.some((p) => p.includes(".agent-yes.config.json"))).toBe(true);
86
+ expect(paths.some((p) => p.includes(".agent-yes.config.yml"))).toBe(true);
87
+ expect(paths.some((p) => p.includes(".agent-yes.config.yaml"))).toBe(true);
88
+ });
89
+
90
+ it("should return empty config when no config files exist", async () => {
91
+ const emptyDir = path.join(testDir, "empty");
92
+ await mkdir(emptyDir, { recursive: true });
93
+
94
+ const config = await loadCascadingConfig({
95
+ projectDir: emptyDir,
96
+ homeDir: emptyDir, // Use same empty dir to avoid loading actual home config
97
+ });
98
+
99
+ expect(config).toEqual({});
100
+ });
101
+
102
+ it("should merge configs with project taking precedence", async () => {
103
+ const homeDir = path.join(testDir, "home");
104
+ const projectDir = path.join(testDir, "project");
105
+ await mkdir(homeDir, { recursive: true });
106
+ await mkdir(projectDir, { recursive: true });
107
+
108
+ await writeFile(
109
+ path.join(homeDir, ".agent-yes.config.json"),
110
+ JSON.stringify({
111
+ configDir: "/home/config",
112
+ logsDir: "/home/logs",
113
+ })
114
+ );
115
+
116
+ await writeFile(
117
+ path.join(projectDir, ".agent-yes.config.json"),
118
+ JSON.stringify({
119
+ configDir: "/project/config",
120
+ })
121
+ );
122
+
123
+ const config = await loadCascadingConfig({ projectDir, homeDir });
124
+ expect(config.configDir).toBe("/project/config"); // Project takes precedence
125
+ expect(config.logsDir).toBe("/home/logs"); // Home is used when not overridden
126
+ });
127
+ });
@@ -0,0 +1,148 @@
1
+ //! Config file loader with cascading support
2
+ //! Supports JSON, YAML, YML formats
3
+ //! Priority: project-dir > home-dir > package-dir
4
+
5
+ import { readFile, access } from "node:fs/promises";
6
+ import path from "node:path";
7
+ import os from "node:os";
8
+ import { parse as parseYaml } from "yaml";
9
+ import { logger } from "./logger.ts";
10
+ import type { AgentYesConfig } from "./index.ts";
11
+ import { deepMixin } from "./utils.ts";
12
+
13
+ const CONFIG_FILENAME = ".agent-yes.config";
14
+ const CONFIG_EXTENSIONS = [".json", ".yml", ".yaml"] as const;
15
+
16
+ /**
17
+ * Check if a file exists
18
+ */
19
+ async function fileExists(filepath: string): Promise<boolean> {
20
+ try {
21
+ await access(filepath);
22
+ return true;
23
+ } catch {
24
+ return false;
25
+ }
26
+ }
27
+
28
+ /**
29
+ * Parse config file based on extension
30
+ */
31
+ async function parseConfigFile(filepath: string): Promise<Partial<AgentYesConfig>> {
32
+ const content = await readFile(filepath, "utf-8");
33
+ const ext = path.extname(filepath).toLowerCase();
34
+
35
+ switch (ext) {
36
+ case ".json":
37
+ return JSON.parse(content);
38
+ case ".yml":
39
+ case ".yaml":
40
+ return parseYaml(content) ?? {};
41
+ default:
42
+ throw new Error(`Unsupported config file extension: ${ext}`);
43
+ }
44
+ }
45
+
46
+ /**
47
+ * Find config file in a directory (checks all supported extensions)
48
+ */
49
+ async function findConfigInDir(dir: string): Promise<string | null> {
50
+ for (const ext of CONFIG_EXTENSIONS) {
51
+ const filepath = path.join(dir, `${CONFIG_FILENAME}${ext}`);
52
+ if (await fileExists(filepath)) {
53
+ return filepath;
54
+ }
55
+ }
56
+ return null;
57
+ }
58
+
59
+ /**
60
+ * Load config from a directory if it exists
61
+ */
62
+ async function loadConfigFromDir(dir: string): Promise<Partial<AgentYesConfig>> {
63
+ const filepath = await findConfigInDir(dir);
64
+ if (!filepath) {
65
+ return {};
66
+ }
67
+
68
+ try {
69
+ logger.debug(`[config] Loading config from: ${filepath}`);
70
+ return await parseConfigFile(filepath);
71
+ } catch (error) {
72
+ logger.warn(`[config] Failed to parse config file ${filepath}:`, error);
73
+ return {};
74
+ }
75
+ }
76
+
77
+ /**
78
+ * Get the package directory (where agent-yes is installed)
79
+ */
80
+ function getPackageDir(): string {
81
+ // __dirname equivalent for ESM
82
+ return path.dirname(new URL(import.meta.url).pathname);
83
+ }
84
+
85
+ export interface ConfigLoadOptions {
86
+ /** Override the project directory (defaults to process.cwd()) */
87
+ projectDir?: string;
88
+ /** Override the home directory (defaults to os.homedir()) */
89
+ homeDir?: string;
90
+ }
91
+
92
+ /**
93
+ * Load configs from cascading locations and merge them
94
+ * Priority (highest to lowest): project-dir > home-dir > package-dir
95
+ * Higher priority configs override lower priority ones
96
+ */
97
+ export async function loadCascadingConfig(
98
+ options: ConfigLoadOptions = {}
99
+ ): Promise<Partial<AgentYesConfig>> {
100
+ const projectDir = options.projectDir ?? process.cwd();
101
+ const homeDir = options.homeDir ?? os.homedir();
102
+ const packageDir = getPackageDir();
103
+
104
+ // Load configs from each location (lowest to highest priority)
105
+ const configs = await Promise.all([
106
+ // Package directory (lowest priority - defaults from package)
107
+ loadConfigFromDir(packageDir),
108
+ // Home directory (middle priority - user defaults)
109
+ loadConfigFromDir(homeDir),
110
+ // Project directory (highest priority - project-specific)
111
+ loadConfigFromDir(projectDir),
112
+ ]);
113
+
114
+ // Filter out empty configs and merge
115
+ const nonEmptyConfigs = configs.filter(
116
+ (c) => c && Object.keys(c).length > 0
117
+ );
118
+
119
+ if (nonEmptyConfigs.length === 0) {
120
+ logger.debug("[config] No config files found in any location");
121
+ return {};
122
+ }
123
+
124
+ // Merge configs with deepMixin (later configs override earlier ones)
125
+ const merged = deepMixin({}, ...nonEmptyConfigs);
126
+ logger.debug("[config] Merged config from", nonEmptyConfigs.length, "sources");
127
+
128
+ return merged;
129
+ }
130
+
131
+ /**
132
+ * Get all possible config file paths (for debugging/user info)
133
+ */
134
+ export function getConfigPaths(options: ConfigLoadOptions = {}): string[] {
135
+ const projectDir = options.projectDir ?? process.cwd();
136
+ const homeDir = options.homeDir ?? os.homedir();
137
+ const packageDir = getPackageDir();
138
+
139
+ const paths: string[] = [];
140
+
141
+ for (const dir of [packageDir, homeDir, projectDir]) {
142
+ for (const ext of CONFIG_EXTENSIONS) {
143
+ paths.push(path.join(dir, `${CONFIG_FILENAME}${ext}`));
144
+ }
145
+ }
146
+
147
+ return paths;
148
+ }