claude-yes 1.31.2 → 1.32.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.
Files changed (44) hide show
  1. package/README.md +225 -21
  2. package/dist/agent-yes.js +2 -0
  3. package/dist/amp-yes.js +2 -0
  4. package/dist/auggie-yes.js +2 -0
  5. package/dist/claude-yes.js +2 -20432
  6. package/dist/cli.js +18342 -10955
  7. package/dist/codex-yes.js +2 -20432
  8. package/dist/copilot-yes.js +2 -20432
  9. package/dist/cursor-yes.js +2 -20432
  10. package/dist/gemini-yes.js +2 -20432
  11. package/dist/grok-yes.js +2 -20432
  12. package/dist/index.js +16258 -13586
  13. package/dist/qwen-yes.js +2 -20432
  14. package/package.json +93 -81
  15. package/ts/ReadyManager.spec.ts +10 -10
  16. package/ts/ReadyManager.ts +1 -1
  17. package/ts/SUPPORTED_CLIS.ts +4 -0
  18. package/ts/catcher.spec.ts +69 -70
  19. package/ts/cli-idle.spec.ts +8 -8
  20. package/ts/cli.ts +18 -26
  21. package/ts/defineConfig.ts +4 -4
  22. package/ts/idleWaiter.spec.ts +9 -9
  23. package/ts/index.ts +474 -233
  24. package/ts/logger.ts +22 -0
  25. package/ts/parseCliArgs.spec.ts +146 -147
  26. package/ts/parseCliArgs.ts +127 -59
  27. package/ts/postbuild.ts +29 -15
  28. package/ts/pty-fix.ts +155 -0
  29. package/ts/pty.ts +19 -0
  30. package/ts/removeControlCharacters.spec.ts +37 -38
  31. package/ts/removeControlCharacters.ts +2 -1
  32. package/ts/runningLock.spec.ts +119 -125
  33. package/ts/runningLock.ts +44 -55
  34. package/ts/session-integration.spec.ts +34 -42
  35. package/ts/utils.spec.ts +35 -35
  36. package/ts/utils.ts +7 -7
  37. package/dist/cli.js.map +0 -365
  38. package/dist/index.js.map +0 -323
  39. package/ts/codex-resume.spec.ts +0 -239
  40. package/ts/codexSessionManager.spec.ts +0 -51
  41. package/ts/codexSessionManager.test.ts +0 -259
  42. package/ts/codexSessionManager.ts +0 -312
  43. package/ts/yesLog.spec.ts +0 -74
  44. package/ts/yesLog.ts +0 -27
package/package.json CHANGED
@@ -1,134 +1,146 @@
1
1
  {
2
2
  "name": "claude-yes",
3
- "version": "1.31.2",
3
+ "version": "1.32.2",
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
+ "ai",
7
+ "anthropic",
8
+ "assistant",
9
+ "auto-response",
10
+ "automation",
6
11
  "claude",
7
- "qwen",
8
- "gemini",
12
+ "cli",
9
13
  "codex",
10
14
  "copilot",
11
15
  "cursor",
16
+ "gemini",
12
17
  "grok",
13
- "ai",
14
- "automation",
15
- "cli",
16
- "wrapper",
17
- "assistant",
18
- "anthropic",
19
- "auto-response"
18
+ "qwen",
19
+ "wrapper"
20
20
  ],
21
- "homepage": "https://github.com/snomiao/claude-yes#readme",
21
+ "homepage": "https://github.com/snomiao/agent-yes#readme",
22
22
  "bugs": {
23
- "url": "https://github.com/snomiao/claude-yes/issues"
24
- },
25
- "repository": {
26
- "type": "git",
27
- "url": "git+https://github.com/snomiao/claude-yes.git"
23
+ "url": "https://github.com/snomiao/agent-yes/issues"
28
24
  },
29
25
  "license": "MIT",
30
26
  "author": "snomiao <snomiao@gmail.com>",
31
- "type": "module",
32
- "exports": {
33
- "import": "./dist/index.js",
34
- "types": "./ts/index.ts"
27
+ "repository": {
28
+ "type": "git",
29
+ "url": "git+https://github.com/snomiao/agent-yes.git"
35
30
  },
36
- "module": "ts/index.ts",
37
- "types": "./ts/index.ts",
38
31
  "bin": {
39
- "claude-yes": "dist/claude-yes.js",
40
- "cli-yes": "dist/cli.js",
41
- "codex-yes": "dist/codex-yes.js",
42
- "copilot-yes": "dist/copilot-yes.js",
43
- "cursor-yes": "dist/cursor-yes.js",
44
- "gemini-yes": "dist/gemini-yes.js",
45
- "grok-yes": "dist/grok-yes.js",
46
- "qwen-yes": "dist/qwen-yes.js"
32
+ "agent-yes": "./dist/agent-yes.js",
33
+ "amp-yes": "./dist/amp-yes.js",
34
+ "auggie-yes": "./dist/auggie-yes.js",
35
+ "claude-yes": "./dist/claude-yes.js",
36
+ "codex-yes": "./dist/codex-yes.js",
37
+ "copilot-yes": "./dist/copilot-yes.js",
38
+ "cursor-yes": "./dist/cursor-yes.js",
39
+ "gemini-yes": "./dist/gemini-yes.js",
40
+ "grok-yes": "./dist/grok-yes.js",
41
+ "qwen-yes": "./dist/qwen-yes.js"
47
42
  },
48
43
  "directories": {
49
44
  "doc": "docs"
50
45
  },
51
46
  "files": [
52
- "ts/*.ts",
53
- "dist",
54
- "scripts"
47
+ "dist/**/*.js",
48
+ "!dist/**/*.map",
49
+ "scripts",
50
+ "ts/*.ts"
55
51
  ],
52
+ "type": "module",
53
+ "module": "ts/index.ts",
54
+ "types": "./ts/index.ts",
55
+ "exports": {
56
+ "types": "./ts/index.ts",
57
+ "import": "./dist/index.js"
58
+ },
59
+ "publishConfig": {
60
+ "access": "public",
61
+ "registry": "https://registry.npmjs.org/"
62
+ },
56
63
  "scripts": {
57
- "build": "bun run build:index && bun run build:cli",
64
+ "build": "bun build ./ts/cli.ts ./ts/index.ts --outdir=dist --target=node --sourcemap --external=@snomiao/bun-pty --external=bun-pty --external=node-pty --external=from-node-stream --external=bun",
58
65
  "postbuild": "bun ./ts/postbuild.ts",
59
- "build:cli": "bun build ts/cli.ts --outdir=dist --target=node --sourcemap --external=bun-pty --external=node-pty --external=from-node-stream --external=bun",
60
- "build:index": "bun build ts/index.ts --outdir=dist --target=node --sourcemap --external=bun-pty --external=node-pty --external=from-node-stream --external=bun",
61
66
  "demo": "bun run build && bun link && claude-yes -- demo",
62
67
  "dev": "bun ts/index.ts",
63
- "fmt": "bunx @biomejs/biome check --fix && bunx sort-package-json",
64
- "prepack": "bun run build",
65
- "prepare": "bunx husky && bun run build",
68
+ "fmt": "oxlint --fix --fix-suggestions && oxfmt",
69
+ "_prepack": "bun run build",
70
+ "prepare": "husky",
71
+ "release": "standard-version && npm publish",
72
+ "release:beta": "standard-version && npm publish --tag beta",
66
73
  "test": "bun test --coverage"
67
74
  },
68
- "lint-staged": {
69
- "*.{ts,js,json,md}": [
70
- "bunx @biomejs/biome check --fix"
71
- ]
72
- },
73
- "release": {
74
- "branches": [
75
- "main"
76
- ],
77
- "plugins": [
78
- "@semantic-release/commit-analyzer",
79
- "@semantic-release/release-notes-generator",
80
- "@semantic-release/changelog",
81
- "@semantic-release/npm",
82
- [
83
- "@semantic-release/exec",
84
- {
85
- "publishCmd": "npm pkg set name=claude-yes"
86
- }
87
- ],
88
- "@semantic-release/npm",
89
- "@semantic-release/git",
90
- "@semantic-release/github"
91
- ]
92
- },
93
75
  "dependencies": {
94
- "bun": "^1.3.1",
95
- "bun-pty": "^0.3.2",
76
+ "@snomiao/bun-pty": "^0.3.4",
77
+ "bun-pty": "^0.4.8",
96
78
  "from-node-stream": "^0.1.2"
97
79
  },
98
80
  "devDependencies": {
99
- "@biomejs/biome": "^2.2.5",
81
+ "@anthropic-ai/sdk": "^0.71.2",
100
82
  "@semantic-release/changelog": "^6.0.3",
101
83
  "@semantic-release/exec": "^7.1.0",
102
84
  "@semantic-release/git": "^10.0.1",
103
85
  "@semantic-release/release-notes-generator": "^14.1.0",
104
- "@types/bun": "^1.2.18",
86
+ "@types/bun": "^1.3.6",
105
87
  "@types/jest": "^30.0.0",
106
88
  "@types/ms": "^2.1.0",
107
- "@types/node": "^24.0.10",
108
- "@types/yargs": "^17.0.33",
89
+ "@types/node": "^25.0.10",
90
+ "@types/yargs": "^17.0.35",
109
91
  "cpu-wait": "^0.0.10",
110
- "execa": "^9.6.0",
92
+ "execa": "^9.6.1",
111
93
  "husky": "^9.1.7",
112
- "lint-staged": "^16.1.4",
94
+ "ink": "^6.6.0",
95
+ "lint-staged": "^16.2.7",
113
96
  "ms": "^2.1.3",
114
- "p-map": "^7.0.3",
97
+ "node-pty": "^1.1.0",
98
+ "openai": "^6.16.0",
99
+ "oxfmt": "^0.26.0",
100
+ "oxlint": "^1.41.0",
101
+ "p-map": "^7.0.4",
115
102
  "phpdie": "^1.7.0",
116
- "rambda": "^10.3.2",
117
- "semantic-release": "^24.2.6",
118
- "sflow": "^1.20.2",
103
+ "rambda": "^11.0.1",
104
+ "semantic-release": "^25.0.2",
105
+ "sflow": "^1.27.0",
106
+ "standard-version": "^9.5.0",
119
107
  "strip-ansi-control-characters": "^2.0.0",
120
- "terminal-render": "^1.2.0",
121
- "tsa-composer": "^3.0.2",
122
- "vitest": "^3.2.4",
108
+ "terminal-render": "^1.2.2",
109
+ "tsa-composer": "^3.0.3",
110
+ "vitest": "^4.0.17",
111
+ "winston": "^3.19.0",
123
112
  "yargs": "^18.0.0"
124
113
  },
125
114
  "peerDependencies": {
126
- "node-pty": "^1.1.0-beta38",
127
- "typescript": "^5.8.3"
115
+ "node-pty": "latest",
116
+ "typescript": "^5.9.3"
128
117
  },
129
118
  "peerDependenciesMeta": {
130
119
  "node-pty": {
131
120
  "optional": true
132
121
  }
122
+ },
123
+ "engines": {
124
+ "node": ">=22.0.0"
125
+ },
126
+ "_release": {
127
+ "branches": [
128
+ "main"
129
+ ],
130
+ "plugins": [
131
+ "@semantic-release/commit-analyzer",
132
+ "@semantic-release/release-notes-generator",
133
+ "@semantic-release/changelog",
134
+ "@semantic-release/npm",
135
+ [
136
+ "@semantic-release/exec",
137
+ {
138
+ "publishCmd": "npm pkg set name=claude-yes"
139
+ }
140
+ ],
141
+ "@semantic-release/npm",
142
+ "@semantic-release/git",
143
+ "@semantic-release/github"
144
+ ]
133
145
  }
134
146
  }
@@ -1,13 +1,13 @@
1
- import { describe, expect, it } from 'vitest';
2
- import { ReadyManager } from './ReadyManager';
1
+ import { describe, expect, it } from "vitest";
2
+ import { ReadyManager } from "./ReadyManager";
3
3
 
4
- describe('ReadyManager', () => {
5
- it('should start in not ready state', () => {
4
+ describe("ReadyManager", () => {
5
+ it("should start in not ready state", () => {
6
6
  const manager = new ReadyManager();
7
7
  expect(manager.wait()).toBeInstanceOf(Promise);
8
8
  });
9
9
 
10
- it('should resolve wait when ready is called', async () => {
10
+ it("should resolve wait when ready is called", async () => {
11
11
  const manager = new ReadyManager();
12
12
  const waitPromise = manager.wait();
13
13
 
@@ -16,7 +16,7 @@ describe('ReadyManager', () => {
16
16
  await expect(waitPromise).resolves.toBeUndefined();
17
17
  });
18
18
 
19
- it('should resolve immediately if already ready', async () => {
19
+ it("should resolve immediately if already ready", async () => {
20
20
  const manager = new ReadyManager();
21
21
  manager.ready();
22
22
 
@@ -24,7 +24,7 @@ describe('ReadyManager', () => {
24
24
  expect(result).toBeUndefined();
25
25
  });
26
26
 
27
- it('should handle multiple waiters', async () => {
27
+ it("should handle multiple waiters", async () => {
28
28
  const manager = new ReadyManager();
29
29
  const wait1 = manager.wait();
30
30
  const wait2 = manager.wait();
@@ -39,7 +39,7 @@ describe('ReadyManager', () => {
39
39
  ]);
40
40
  });
41
41
 
42
- it('should reset to not ready when unready is called', async () => {
42
+ it("should reset to not ready when unready is called", async () => {
43
43
  const manager = new ReadyManager();
44
44
  manager.ready();
45
45
  manager.unready();
@@ -47,13 +47,13 @@ describe('ReadyManager', () => {
47
47
  expect(manager.wait()).toBeInstanceOf(Promise);
48
48
  });
49
49
 
50
- it('should handle ready with no waiting queue', () => {
50
+ it("should handle ready with no waiting queue", () => {
51
51
  const manager = new ReadyManager();
52
52
  manager.ready(); // Should not throw even if no one is waiting
53
53
  expect(manager.wait()).toBeUndefined(); // Should be ready now
54
54
  });
55
55
 
56
- it('should handle multiple ready/unready cycles', async () => {
56
+ it("should handle multiple ready/unready cycles", async () => {
57
57
  const manager = new ReadyManager();
58
58
 
59
59
  // First cycle
@@ -1,5 +1,5 @@
1
1
  export class ReadyManager {
2
- private isReady = false;
2
+ isReady = false;
3
3
  private readyQueue: (() => void)[] = [];
4
4
  wait() {
5
5
  if (this.isReady) return;
@@ -0,0 +1,4 @@
1
+ import { CLIS_CONFIG } from "./index.ts";
2
+
3
+ export const SUPPORTED_CLIS = Object.keys(CLIS_CONFIG) as SUPPORTED_CLIS[];
4
+ export type SUPPORTED_CLIS = keyof typeof CLIS_CONFIG;
@@ -1,15 +1,15 @@
1
- import { describe, expect, it } from 'vitest';
2
- import { catcher } from './catcher';
1
+ import { describe, expect, it } from "vitest";
2
+ import { catcher } from "./catcher";
3
3
 
4
- describe('catcher', () => {
5
- describe('curried overload', () => {
6
- it('should return a function when called with only catchFn', () => {
7
- const catchFn = () => 'error';
4
+ describe("catcher", () => {
5
+ describe("curried overload", () => {
6
+ it("should return a function when called with only catchFn", () => {
7
+ const catchFn = () => "error";
8
8
  const result = catcher(catchFn);
9
- expect(typeof result).toBe('function');
9
+ expect(typeof result).toBe("function");
10
10
  });
11
11
 
12
- it('should catch errors and call catchFn with error, function, and args', () => {
12
+ it("should catch errors and call catchFn with error, function, and args", () => {
13
13
  let catchedError: unknown;
14
14
  let catchedFn: unknown;
15
15
  let catchedArgs: unknown[];
@@ -17,49 +17,49 @@ describe('catcher', () => {
17
17
  catchedError = error;
18
18
  catchedFn = fn;
19
19
  catchedArgs = args;
20
- return 'caught';
20
+ return "caught";
21
21
  };
22
22
 
23
23
  let calledArgs: unknown[] = [];
24
24
  const errorFn = (...args: unknown[]) => {
25
25
  calledArgs = args;
26
- throw new Error('test error');
26
+ throw new Error("test error");
27
27
  };
28
28
 
29
29
  const wrappedFn = catcher(catchFn)(errorFn);
30
- const result = wrappedFn('arg1', 'arg2');
30
+ const result = wrappedFn("arg1", "arg2");
31
31
 
32
- expect(result).toBe('caught');
32
+ expect(result).toBe("caught");
33
33
  expect(catchedError).toBeInstanceOf(Error);
34
34
  expect(catchedFn).toBe(errorFn);
35
- expect(catchedArgs).toEqual(['arg1', 'arg2']);
36
- expect(calledArgs).toEqual(['arg1', 'arg2']);
35
+ expect(catchedArgs).toEqual(["arg1", "arg2"]);
36
+ expect(calledArgs).toEqual(["arg1", "arg2"]);
37
37
  });
38
38
 
39
- it('should return normal result when no error occurs', () => {
39
+ it("should return normal result when no error occurs", () => {
40
40
  let catchCalled = false;
41
41
  const catchFn = () => {
42
42
  catchCalled = true;
43
- return 'error';
43
+ return "error";
44
44
  };
45
45
 
46
46
  let calledArgs: unknown[] = [];
47
47
  const normalFn = (...args: unknown[]) => {
48
48
  calledArgs = args;
49
- return 'success';
49
+ return "success";
50
50
  };
51
51
 
52
52
  const wrappedFn = catcher(catchFn)(normalFn);
53
- const result = wrappedFn('arg1', 'arg2');
53
+ const result = wrappedFn("arg1", "arg2");
54
54
 
55
- expect(result).toBe('success');
55
+ expect(result).toBe("success");
56
56
  expect(catchCalled).toBe(false);
57
- expect(calledArgs).toEqual(['arg1', 'arg2']);
57
+ expect(calledArgs).toEqual(["arg1", "arg2"]);
58
58
  });
59
59
  });
60
60
 
61
- describe('direct overload', () => {
62
- it('should catch errors and call catchFn with error, function, and args directly', () => {
61
+ describe("direct overload", () => {
62
+ it("should catch errors and call catchFn with error, function, and args directly", () => {
63
63
  let catchedError: unknown;
64
64
  let catchedFn: unknown;
65
65
  let catchedArgs: unknown[];
@@ -67,73 +67,73 @@ describe('catcher', () => {
67
67
  catchedError = error;
68
68
  catchedFn = fn;
69
69
  catchedArgs = args;
70
- return 'caught';
70
+ return "caught";
71
71
  };
72
72
 
73
73
  let calledArgs: unknown[] = [];
74
74
  const errorFn = (...args: unknown[]) => {
75
75
  calledArgs = args;
76
- throw new Error('test error');
76
+ throw new Error("test error");
77
77
  };
78
78
 
79
79
  const wrappedFn = catcher(catchFn, errorFn);
80
- const result = wrappedFn('arg1', 'arg2');
80
+ const result = wrappedFn("arg1", "arg2");
81
81
 
82
- expect(result).toBe('caught');
82
+ expect(result).toBe("caught");
83
83
  expect(catchedError).toBeInstanceOf(Error);
84
84
  expect(catchedFn).toBe(errorFn);
85
- expect(catchedArgs).toEqual(['arg1', 'arg2']);
86
- expect(calledArgs).toEqual(['arg1', 'arg2']);
85
+ expect(catchedArgs).toEqual(["arg1", "arg2"]);
86
+ expect(calledArgs).toEqual(["arg1", "arg2"]);
87
87
  });
88
88
 
89
- it('should return normal result when no error occurs directly', () => {
89
+ it("should return normal result when no error occurs directly", () => {
90
90
  let catchCalled = false;
91
91
  const catchFn = () => {
92
92
  catchCalled = true;
93
- return 'error';
93
+ return "error";
94
94
  };
95
95
 
96
96
  let calledArgs: unknown[] = [];
97
97
  const normalFn = (...args: unknown[]) => {
98
98
  calledArgs = args;
99
- return 'success';
99
+ return "success";
100
100
  };
101
101
 
102
102
  const wrappedFn = catcher(catchFn, normalFn);
103
- const result = wrappedFn('arg1', 'arg2');
103
+ const result = wrappedFn("arg1", "arg2");
104
104
 
105
- expect(result).toBe('success');
105
+ expect(result).toBe("success");
106
106
  expect(catchCalled).toBe(false);
107
- expect(calledArgs).toEqual(['arg1', 'arg2']);
107
+ expect(calledArgs).toEqual(["arg1", "arg2"]);
108
108
  });
109
109
  });
110
110
 
111
- describe('error handling', () => {
112
- it('should handle different error types and pass function context', () => {
111
+ describe("error handling", () => {
112
+ it("should handle different error types and pass function context", () => {
113
113
  const results: unknown[] = [];
114
114
  const functions: unknown[] = [];
115
- const catchFn = (error: unknown, fn: unknown, ...args: unknown[]) => {
115
+ const catchFn = (error: unknown, fn: unknown, ..._args: unknown[]) => {
116
116
  results.push(error);
117
117
  functions.push(fn);
118
- return 'handled';
118
+ return "handled";
119
119
  };
120
120
 
121
121
  // String error
122
122
  const stringErrorFn = () => {
123
- throw 'string error';
123
+ throw "string error";
124
124
  };
125
125
  const wrappedStringFn = catcher(catchFn, stringErrorFn);
126
- expect(wrappedStringFn()).toBe('handled');
127
- expect(results[0]).toBe('string error');
126
+ expect(wrappedStringFn()).toBe("handled");
127
+ expect(results[0]).toBe("string error");
128
128
  expect(functions[0]).toBe(stringErrorFn);
129
129
 
130
130
  // Object error
131
- const objectError = { message: 'object error' };
131
+ const objectError = { message: "object error" };
132
132
  const objectErrorFn = () => {
133
133
  throw objectError;
134
134
  };
135
135
  const wrappedObjectFn = catcher(catchFn, objectErrorFn);
136
- expect(wrappedObjectFn()).toBe('handled');
136
+ expect(wrappedObjectFn()).toBe("handled");
137
137
  expect(results[1]).toBe(objectError);
138
138
  expect(functions[1]).toBe(objectErrorFn);
139
139
 
@@ -142,12 +142,12 @@ describe('catcher', () => {
142
142
  throw null;
143
143
  };
144
144
  const wrappedNullFn = catcher(catchFn, nullErrorFn);
145
- expect(wrappedNullFn()).toBe('handled');
145
+ expect(wrappedNullFn()).toBe("handled");
146
146
  expect(results[2]).toBe(null);
147
147
  expect(functions[2]).toBe(nullErrorFn);
148
148
  });
149
149
 
150
- it('should preserve function parameters and pass them to catchFn', () => {
150
+ it("should preserve function parameters and pass them to catchFn", () => {
151
151
  let caughtError: unknown;
152
152
  let caughtFn: unknown;
153
153
  let caughtArgs: unknown[];
@@ -155,31 +155,31 @@ describe('catcher', () => {
155
155
  caughtError = error;
156
156
  caughtFn = fn;
157
157
  caughtArgs = args;
158
- return 'caught';
158
+ return "caught";
159
159
  };
160
160
 
161
161
  let testArgs: [number, string, boolean] | undefined;
162
162
  const testFn = (a: number, b: string, c: boolean) => {
163
163
  testArgs = [a, b, c];
164
- if (a > 5) throw new Error('too big');
164
+ if (a > 5) throw new Error("too big");
165
165
  return `${a}-${b}-${c}`;
166
166
  };
167
167
 
168
168
  const wrappedFn = catcher(catchFn, testFn);
169
169
 
170
170
  // Normal execution
171
- expect(wrappedFn(3, 'test', true)).toBe('3-test-true');
172
- expect(testArgs).toEqual([3, 'test', true]);
171
+ expect(wrappedFn(3, "test", true)).toBe("3-test-true");
172
+ expect(testArgs).toEqual([3, "test", true]);
173
173
 
174
174
  // Error execution
175
- expect(wrappedFn(10, 'error', false)).toBe('caught');
176
- expect(testArgs).toEqual([10, 'error', false]);
175
+ expect(wrappedFn(10, "error", false)).toBe("caught");
176
+ expect(testArgs).toEqual([10, "error", false]);
177
177
  expect(caughtError).toBeInstanceOf(Error);
178
178
  expect(caughtFn).toBe(testFn);
179
- expect(caughtArgs).toEqual([10, 'error', false]);
179
+ expect(caughtArgs).toEqual([10, "error", false]);
180
180
  });
181
181
 
182
- it('should handle functions with no parameters', () => {
182
+ it("should handle functions with no parameters", () => {
183
183
  let caughtError: unknown;
184
184
  let caughtFn: unknown;
185
185
  let caughtArgs: unknown[];
@@ -187,26 +187,26 @@ describe('catcher', () => {
187
187
  caughtError = error;
188
188
  caughtFn = fn;
189
189
  caughtArgs = args;
190
- return 'no params caught';
190
+ return "no params caught";
191
191
  };
192
192
 
193
193
  let called = false;
194
194
  const noParamsFn = () => {
195
195
  called = true;
196
- throw new Error('no params error');
196
+ throw new Error("no params error");
197
197
  };
198
198
 
199
199
  const wrappedFn = catcher(catchFn, noParamsFn);
200
200
  const result = wrappedFn();
201
201
 
202
- expect(result).toBe('no params caught');
202
+ expect(result).toBe("no params caught");
203
203
  expect(called).toBe(true);
204
204
  expect(caughtError).toBeInstanceOf(Error);
205
205
  expect(caughtFn).toBe(noParamsFn);
206
206
  expect(caughtArgs).toEqual([]);
207
207
  });
208
208
 
209
- it('should handle functions returning different types', () => {
209
+ it("should handle functions returning different types", () => {
210
210
  const catchFn = () => null;
211
211
 
212
212
  // Function returning number
@@ -214,7 +214,7 @@ describe('catcher', () => {
214
214
  expect(numberFn()).toBe(42);
215
215
 
216
216
  // Function returning object
217
- const obj = { key: 'value' };
217
+ const obj = { key: "value" };
218
218
  const objectFn = catcher(catchFn, () => obj);
219
219
  expect(objectFn()).toBe(obj);
220
220
 
@@ -224,37 +224,36 @@ describe('catcher', () => {
224
224
  });
225
225
  });
226
226
 
227
- describe('type safety', () => {
228
- it('should maintain function signature', () => {
229
- const catchFn = (error: unknown, fn: unknown, ...args: unknown[]) =>
230
- 'error';
227
+ describe("type safety", () => {
228
+ it("should maintain function signature", () => {
229
+ const catchFn = (_error: unknown, _fn: unknown, ..._args: unknown[]) => "error";
231
230
  const originalFn = (a: number, b: string): string => `${a}-${b}`;
232
231
 
233
232
  const wrappedFn = catcher(catchFn, originalFn);
234
233
 
235
234
  // This should be type-safe
236
- const result: string = wrappedFn(1, 'test');
237
- expect(result).toBe('1-test');
235
+ const result: string = wrappedFn(1, "test");
236
+ expect(result).toBe("1-test");
238
237
  });
239
238
 
240
- it('should pass function reference and arguments to catchFn', () => {
239
+ it("should pass function reference and arguments to catchFn", () => {
241
240
  let capturedFn: unknown;
242
241
  let capturedArgs: unknown[];
243
242
  const catchFn = (error: unknown, fn: unknown, ...args: unknown[]) => {
244
243
  capturedFn = fn;
245
244
  capturedArgs = args;
246
- return 'handled';
245
+ return "handled";
247
246
  };
248
247
 
249
- const testFn = (x: number, y: string) => {
250
- throw new Error('test');
248
+ const testFn = (_x: number, _y: string) => {
249
+ throw new Error("test");
251
250
  };
252
251
 
253
252
  const wrappedFn = catcher(catchFn, testFn);
254
- wrappedFn(42, 'hello');
253
+ wrappedFn(42, "hello");
255
254
 
256
255
  expect(capturedFn).toBe(testFn);
257
- expect(capturedArgs).toEqual([42, 'hello']);
256
+ expect(capturedArgs).toEqual([42, "hello"]);
258
257
  });
259
258
  });
260
259
  });
@@ -1,19 +1,19 @@
1
- import { exec } from 'child_process';
2
- import { fromStdio } from 'from-node-stream';
3
- import sflow from 'sflow';
4
- import { describe, it } from 'vitest';
5
- import { sleepms } from './utils';
1
+ import { exec } from "child_process";
2
+ import { fromStdio } from "from-node-stream";
3
+ import sflow from "sflow";
4
+ import { describe, it } from "vitest";
5
+ import { sleepms } from "./utils";
6
6
 
7
- describe('CLI idle tests', () => {
7
+ describe("CLI idle tests", () => {
8
8
  // 2025-08-11 ok
9
- it.skip('CLI --exit-on-idle flag with custom timeout', async () => {
9
+ it.skip("CLI --exit-on-idle flag with custom timeout", async () => {
10
10
  const p = exec(
11
11
  `bunx tsx ./ts/cli.ts claude --verbose --logFile=./cli-idle.log --exit-on-idle=3s "say hello and wait"`,
12
12
  );
13
13
  const tr = new TransformStream<string, string>();
14
14
  const output = await sflow(tr.readable).by(fromStdio(p)).log().text();
15
15
  console.log(output);
16
- expect(output).toContain('hello');
16
+ expect(output).toContain("hello");
17
17
  await sleepms(1000); // wait for process exit
18
18
  expect(p.exitCode).toBe(0);
19
19
  }, 20e3);