@joeytheman/gemini-mcp-tool 2.2.0 → 2.3.1

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 (115) hide show
  1. package/README.md +10 -7
  2. package/dist/__tests__/agyModelSteps.test.d.ts +2 -0
  3. package/dist/__tests__/agyModelSteps.test.d.ts.map +1 -0
  4. package/dist/__tests__/agyModelSteps.test.js +58 -0
  5. package/dist/__tests__/agyModelSteps.test.js.map +1 -0
  6. package/dist/__tests__/capture-script.chromium.test.d.ts +2 -0
  7. package/dist/__tests__/capture-script.chromium.test.d.ts.map +1 -0
  8. package/dist/__tests__/capture-script.chromium.test.js +235 -0
  9. package/dist/__tests__/capture-script.chromium.test.js.map +1 -0
  10. package/dist/__tests__/layout-snippet.chromium.test.d.ts +2 -0
  11. package/dist/__tests__/layout-snippet.chromium.test.d.ts.map +1 -0
  12. package/dist/__tests__/layout-snippet.chromium.test.js +333 -0
  13. package/dist/__tests__/layout-snippet.chromium.test.js.map +1 -0
  14. package/dist/__tests__/layout-snippet.test.d.ts +2 -0
  15. package/dist/__tests__/layout-snippet.test.d.ts.map +1 -0
  16. package/dist/__tests__/layout-snippet.test.js +12 -0
  17. package/dist/__tests__/layout-snippet.test.js.map +1 -0
  18. package/dist/__tests__/live-pass.test.js +531 -7
  19. package/dist/__tests__/live-pass.test.js.map +1 -1
  20. package/dist/__tests__/screen-review.test.js +111 -2
  21. package/dist/__tests__/screen-review.test.js.map +1 -1
  22. package/dist/__tests__/server-progress.test.d.ts +2 -0
  23. package/dist/__tests__/server-progress.test.d.ts.map +1 -0
  24. package/dist/__tests__/server-progress.test.js +63 -0
  25. package/dist/__tests__/server-progress.test.js.map +1 -0
  26. package/dist/__tests__/server.test.js +1 -8
  27. package/dist/__tests__/server.test.js.map +1 -1
  28. package/dist/__tests__/simple-tools.test.js +8 -3
  29. package/dist/__tests__/simple-tools.test.js.map +1 -1
  30. package/dist/__tests__/tools.test.js +29 -1
  31. package/dist/__tests__/tools.test.js.map +1 -1
  32. package/dist/__tests__/utils/agyExecutor.test.js +176 -61
  33. package/dist/__tests__/utils/agyExecutor.test.js.map +1 -1
  34. package/dist/__tests__/utils/commandExecutor.test.js +155 -1
  35. package/dist/__tests__/utils/commandExecutor.test.js.map +1 -1
  36. package/dist/__tests__/utils/progressUpdates.test.d.ts +2 -0
  37. package/dist/__tests__/utils/progressUpdates.test.d.ts.map +1 -0
  38. package/dist/__tests__/utils/progressUpdates.test.js +62 -0
  39. package/dist/__tests__/utils/progressUpdates.test.js.map +1 -0
  40. package/dist/constants.d.ts +33 -10
  41. package/dist/constants.d.ts.map +1 -1
  42. package/dist/constants.js +42 -10
  43. package/dist/constants.js.map +1 -1
  44. package/dist/index.js +19 -94
  45. package/dist/index.js.map +1 -1
  46. package/dist/layoutCheckSnippet.generated.d.ts +2 -0
  47. package/dist/layoutCheckSnippet.generated.d.ts.map +1 -0
  48. package/dist/layoutCheckSnippet.generated.js +3 -0
  49. package/dist/layoutCheckSnippet.generated.js.map +1 -0
  50. package/dist/tools/ask-gemini.tool.d.ts.map +1 -1
  51. package/dist/tools/ask-gemini.tool.js +6 -5
  52. package/dist/tools/ask-gemini.tool.js.map +1 -1
  53. package/dist/tools/brainstorm.tool.d.ts.map +1 -1
  54. package/dist/tools/brainstorm.tool.js +2 -1
  55. package/dist/tools/brainstorm.tool.js.map +1 -1
  56. package/dist/tools/live-pass.tool.d.ts +24 -1
  57. package/dist/tools/live-pass.tool.d.ts.map +1 -1
  58. package/dist/tools/live-pass.tool.js +174 -52
  59. package/dist/tools/live-pass.tool.js.map +1 -1
  60. package/dist/tools/registry.d.ts +2 -2
  61. package/dist/tools/registry.d.ts.map +1 -1
  62. package/dist/tools/registry.js +2 -2
  63. package/dist/tools/registry.js.map +1 -1
  64. package/dist/tools/screen-review.tool.d.ts +3 -0
  65. package/dist/tools/screen-review.tool.d.ts.map +1 -1
  66. package/dist/tools/screen-review.tool.js +42 -8
  67. package/dist/tools/screen-review.tool.js.map +1 -1
  68. package/dist/tools/simple-tools.d.ts.map +1 -1
  69. package/dist/tools/simple-tools.js +6 -2
  70. package/dist/tools/simple-tools.js.map +1 -1
  71. package/dist/utils/agyExecutor.d.ts +9 -1
  72. package/dist/utils/agyExecutor.d.ts.map +1 -1
  73. package/dist/utils/agyExecutor.js +54 -48
  74. package/dist/utils/agyExecutor.js.map +1 -1
  75. package/dist/utils/agyModelSteps.d.ts +5 -0
  76. package/dist/utils/agyModelSteps.d.ts.map +1 -0
  77. package/dist/utils/agyModelSteps.js +33 -0
  78. package/dist/utils/agyModelSteps.js.map +1 -0
  79. package/dist/utils/artifactFile.d.ts +6 -0
  80. package/dist/utils/artifactFile.d.ts.map +1 -0
  81. package/dist/utils/artifactFile.js +55 -0
  82. package/dist/utils/artifactFile.js.map +1 -0
  83. package/dist/utils/captureScript.d.ts +24 -0
  84. package/dist/utils/captureScript.d.ts.map +1 -0
  85. package/dist/utils/captureScript.js +83 -0
  86. package/dist/utils/captureScript.js.map +1 -0
  87. package/dist/utils/commandExecutor.d.ts +7 -1
  88. package/dist/utils/commandExecutor.d.ts.map +1 -1
  89. package/dist/utils/commandExecutor.js +154 -22
  90. package/dist/utils/commandExecutor.js.map +1 -1
  91. package/dist/utils/gitCheckout.d.ts +14 -0
  92. package/dist/utils/gitCheckout.d.ts.map +1 -0
  93. package/dist/utils/gitCheckout.js +36 -0
  94. package/dist/utils/gitCheckout.js.map +1 -0
  95. package/dist/utils/layoutCheck.d.ts +58 -0
  96. package/dist/utils/layoutCheck.d.ts.map +1 -0
  97. package/dist/utils/layoutCheck.js +84 -0
  98. package/dist/utils/layoutCheck.js.map +1 -0
  99. package/dist/utils/logger.d.ts +0 -1
  100. package/dist/utils/logger.d.ts.map +1 -1
  101. package/dist/utils/logger.js +0 -6
  102. package/dist/utils/logger.js.map +1 -1
  103. package/dist/utils/progressUpdates.d.ts +14 -0
  104. package/dist/utils/progressUpdates.d.ts.map +1 -0
  105. package/dist/utils/progressUpdates.js +40 -0
  106. package/dist/utils/progressUpdates.js.map +1 -0
  107. package/package.json +18 -13
  108. package/dist/__tests__/utils/agyTranscriptRecovery.test.d.ts +0 -2
  109. package/dist/__tests__/utils/agyTranscriptRecovery.test.d.ts.map +0 -1
  110. package/dist/__tests__/utils/agyTranscriptRecovery.test.js +0 -127
  111. package/dist/__tests__/utils/agyTranscriptRecovery.test.js.map +0 -1
  112. package/dist/utils/agyTranscriptRecovery.d.ts +0 -16
  113. package/dist/utils/agyTranscriptRecovery.d.ts.map +0 -1
  114. package/dist/utils/agyTranscriptRecovery.js +0 -149
  115. package/dist/utils/agyTranscriptRecovery.js.map +0 -1
@@ -11,7 +11,6 @@ const mockServerInstance = {
11
11
  setRequestHandlerCalls.push(args);
12
12
  }),
13
13
  connect: vi.fn().mockResolvedValue(undefined),
14
- notification: vi.fn(),
15
14
  };
16
15
  vi.mock('@modelcontextprotocol/sdk/server/index.js', () => {
17
16
  const ServerMock = vi.fn(function (...args) {
@@ -47,7 +46,7 @@ describe('Gemini MCP Server', () => {
47
46
  expect(serverConstructorCalls.length).toBeGreaterThanOrEqual(1);
48
47
  const [serverConfig] = serverConstructorCalls[0];
49
48
  expect(serverConfig).toHaveProperty('name', 'gemini-mcp');
50
- expect(packageVersion).toBe('2.2.0');
49
+ expect(packageVersion).toBe('2.3.1');
51
50
  expect(serverConfig).toHaveProperty('version', packageVersion);
52
51
  });
53
52
  it('should register capabilities', () => {
@@ -62,12 +61,6 @@ describe('Gemini MCP Server', () => {
62
61
  expect(setRequestHandlerCalls.length).toBeGreaterThanOrEqual(4);
63
62
  });
64
63
  });
65
- describe('Progress Notifications', () => {
66
- it('should support progress notifications', () => {
67
- expect(mockServerInstance).toHaveProperty('notification');
68
- expect(typeof mockServerInstance.notification).toBe('function');
69
- });
70
- });
71
64
  describe('Transport Connection', () => {
72
65
  it('should create StdioServerTransport', () => {
73
66
  expect(stdioTransportConstructorCalls.length).toBeGreaterThanOrEqual(1);
@@ -1 +1 @@
1
- {"version":3,"file":"server.test.js","sourceRoot":"","sources":["../../src/__tests__/server.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.test.js","sourceRoot":"","sources":["../../src/__tests__/server.test.ts"],"names":[],"mappings":"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"}
@@ -4,15 +4,20 @@ vi.mock('../utils/commandExecutor.js', () => ({
4
4
  executeCommand: (...args) => mockExecuteCommand(...args),
5
5
  }));
6
6
  import { helpTool, pingTool } from '../tools/simple-tools.js';
7
+ import { AGY_LIMITS } from '../constants.js';
7
8
  describe('simple tools', () => {
8
9
  beforeEach(() => {
9
10
  vi.clearAllMocks();
10
11
  mockExecuteCommand.mockResolvedValue('help output');
11
12
  });
12
- it('Help should call agy help', async () => {
13
- const result = await helpTool.execute({});
13
+ it('Help should call agy help under the default ceiling and the request signal', async () => {
14
+ const controller = new AbortController();
15
+ const result = await helpTool.execute({}, undefined, controller.signal);
14
16
  expect(result).toBe('help output');
15
- expect(mockExecuteCommand).toHaveBeenCalledWith('agy', ['--help'], undefined);
17
+ expect(mockExecuteCommand).toHaveBeenCalledWith('agy', ['--help'], undefined, undefined, {
18
+ killAfterMs: AGY_LIMITS.DEFAULT_CEILING_MS,
19
+ signal: controller.signal,
20
+ });
16
21
  });
17
22
  it('ping should return directly without spawning a shell command', async () => {
18
23
  const onProgress = vi.fn();
@@ -1 +1 @@
1
- {"version":3,"file":"simple-tools.test.js","sourceRoot":"","sources":["../../src/__tests__/simple-tools.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAE9D,MAAM,kBAAkB,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;AACnC,EAAE,CAAC,IAAI,CAAC,6BAA6B,EAAE,GAAG,EAAE,CAAC,CAAC;IAC5C,cAAc,EAAE,CAAC,GAAG,IAAW,EAAE,EAAE,CAAC,kBAAkB,CAAC,GAAG,IAAI,CAAC;CAChE,CAAC,CAAC,CAAC;AAEJ,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAE9D,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,UAAU,CAAC,GAAG,EAAE;QACd,EAAE,CAAC,aAAa,EAAE,CAAC;QACnB,kBAAkB,CAAC,iBAAiB,CAAC,aAAa,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2BAA2B,EAAE,KAAK,IAAI,EAAE;QACzC,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAE1C,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACnC,MAAM,CAAC,kBAAkB,CAAC,CAAC,oBAAoB,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,EAAE,SAAS,CAAC,CAAC;IAChF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8DAA8D,EAAE,KAAK,IAAI,EAAE;QAC5E,MAAM,UAAU,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QAE3B,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,UAAU,CAAC,CAAC;QAEvE,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC7B,MAAM,CAAC,UAAU,CAAC,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC;QACjD,MAAM,CAAC,kBAAkB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IACpD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"simple-tools.test.js","sourceRoot":"","sources":["../../src/__tests__/simple-tools.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAE9D,MAAM,kBAAkB,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;AACnC,EAAE,CAAC,IAAI,CAAC,6BAA6B,EAAE,GAAG,EAAE,CAAC,CAAC;IAC5C,cAAc,EAAE,CAAC,GAAG,IAAW,EAAE,EAAE,CAAC,kBAAkB,CAAC,GAAG,IAAI,CAAC;CAChE,CAAC,CAAC,CAAC;AAEJ,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,UAAU,CAAC,GAAG,EAAE;QACd,EAAE,CAAC,aAAa,EAAE,CAAC;QACnB,kBAAkB,CAAC,iBAAiB,CAAC,aAAa,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4EAA4E,EAAE,KAAK,IAAI,EAAE;QAC1F,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QAEzC,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;QAExE,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACnC,MAAM,CAAC,kBAAkB,CAAC,CAAC,oBAAoB,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE;YACvF,WAAW,EAAE,UAAU,CAAC,kBAAkB;YAC1C,MAAM,EAAE,UAAU,CAAC,MAAM;SAC1B,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8DAA8D,EAAE,KAAK,IAAI,EAAE;QAC5E,MAAM,UAAU,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QAE3B,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,UAAU,CAAC,CAAC;QAEvE,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC7B,MAAM,CAAC,UAAU,CAAC,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC;QACjD,MAAM,CAAC,kBAAkB,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IACpD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1,6 +1,9 @@
1
1
  import { describe, it, expect } from 'vitest';
2
2
  import { toolRegistry, getToolDefinitions, toolExists, getPromptDefinitions } from '../tools/index.js';
3
- import { CLI } from '../constants.js';
3
+ import { CLI, ERROR_MESSAGES } from '../constants.js';
4
+ import { askGeminiArgsSchema } from '../tools/ask-gemini.tool.js';
5
+ import { livePassArgsSchema } from '../tools/live-pass.tool.js';
6
+ import { screenReviewArgsSchema } from '../tools/screen-review.tool.js';
4
7
  describe('Tool Registry', () => {
5
8
  describe('getToolDefinitions', () => {
6
9
  it('should return an array of tool definitions', () => {
@@ -131,6 +134,31 @@ describe('Tool Registry', () => {
131
134
  expect(properties).toHaveProperty('approvalMode');
132
135
  expect(properties).toHaveProperty('printTimeout');
133
136
  });
137
+ it('ask-gemini describes the resume check for every output format', () => {
138
+ const askGeminiTool = getToolDefinitions().find(t => t.name === 'ask-gemini');
139
+ const conversationId = askGeminiTool?.inputSchema.properties?.conversationId;
140
+ expect(conversationId.description).toContain('The call errors when agy silently starts a different conversation');
141
+ expect(conversationId.description).not.toContain("outputFormat 'json'");
142
+ });
143
+ it.each(['ask-gemini', 'live-pass', 'screen-review'])('%s documents when the server stops agy past printTimeout', (toolName) => {
144
+ const tool = getToolDefinitions().find(t => t.name === toolName);
145
+ const printTimeout = tool?.inputSchema.properties?.printTimeout;
146
+ expect(printTimeout.description).toContain('The server stops agy 2 minutes after this limit, or after 2 hours when no limit is given.');
147
+ });
148
+ describe.each([
149
+ ['ask-gemini', askGeminiArgsSchema],
150
+ ['live-pass', livePassArgsSchema],
151
+ ['screen-review', screenReviewArgsSchema],
152
+ ])('%s printTimeout', (_toolName, schema) => {
153
+ it.each(['abc', '+3h', '1h30'])('rejects %j, naming the accepted form', (printTimeout) => {
154
+ const result = schema.shape.printTimeout.safeParse(printTimeout);
155
+ expect(result.success).toBe(false);
156
+ expect(result.error?.issues[0].message).toBe(ERROR_MESSAGES.INVALID_PRINT_TIMEOUT);
157
+ });
158
+ it.each(['90s', '2h30m', '2.5h', '0'])('accepts %j', (printTimeout) => {
159
+ expect(schema.shape.printTimeout.safeParse(printTimeout)).toEqual({ success: true, data: printTimeout });
160
+ });
161
+ });
134
162
  it('brainstorm should have methodology parameter', () => {
135
163
  const tools = getToolDefinitions();
136
164
  const brainstormTool = tools.find(t => t.name === 'brainstorm');
@@ -1 +1 @@
1
- {"version":3,"file":"tools.test.js","sourceRoot":"","sources":["../../src/__tests__/tools.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tools.test.js","sourceRoot":"","sources":["../../src/__tests__/tools.test.ts"],"names":[],"mappings":"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"}
@@ -27,29 +27,38 @@ vi.mock('../../utils/chunkCache.js', () => ({
27
27
  cacheChunks: vi.fn().mockReturnValue('chunk123'),
28
28
  getChunks: vi.fn().mockReturnValue(null),
29
29
  }));
30
- const mockRecover = vi.fn();
31
- vi.mock('../../utils/agyTranscriptRecovery.js', () => ({
32
- isRecoverableEmptyOutput: (s) => {
33
- const t = s.trim();
34
- return t === '' || t === 'Error: timed out waiting for response';
35
- },
36
- recoverFromTranscript: (...args) => mockRecover(...args),
37
- }));
38
- import { executeAgyCLI, executeAgyJson, processChangeModeOutput, parseAgyJsonEnvelope, renderAgyJsonEnvelope, deniedActionsSummary, formatAgyUsageLine, formatConversationLine, } from '../../utils/agyExecutor.js';
39
- import { CLI, MODELS, ERROR_MESSAGES } from '../../constants.js';
30
+ import { executeAgyCLI, executeAgyJson, processChangeModeOutput, parseAgyJsonEnvelope, renderAgyJsonEnvelope, deniedActionsSummary, formatAgyUsageLine, formatConversationLine, agyKillAfterMs, printTimeoutSchema, } from '../../utils/agyExecutor.js';
31
+ import { CLI, MODELS, ERROR_MESSAGES, AGY_LIMITS } from '../../constants.js';
32
+ const ENVELOPE = {
33
+ conversation_id: 'conv-abc',
34
+ status: 'SUCCESS',
35
+ response: 'plain answer',
36
+ structured_output: { ok: true },
37
+ num_turns: 2,
38
+ duration_seconds: 12.5,
39
+ usage: { input_tokens: 100, output_tokens: 20, thinking_tokens: 5, cache_read_tokens: 0, total_tokens: 125 },
40
+ denied_actions: [],
41
+ };
42
+ function envelopeLine(overrides = {}) {
43
+ return JSON.stringify({ ...ENVELOPE, ...overrides });
44
+ }
45
+ /** The envelope agy prints for a text call: an answer and no structured output. */
46
+ function textEnvelope(response, overrides = {}) {
47
+ return envelopeLine({ response, structured_output: null, ...overrides });
48
+ }
40
49
  describe('executeAgyCLI', () => {
41
50
  beforeEach(() => {
42
51
  vi.clearAllMocks();
43
52
  mockIsCacheEnabled.mockReturnValue(false);
44
53
  mockGenerateCacheKey.mockReturnValue('mock-cache-key');
45
54
  mockGetCachedResponse.mockReturnValue(undefined);
46
- mockExecuteCommand.mockResolvedValue('Gemini response');
55
+ mockExecuteCommand.mockResolvedValue(textEnvelope('Gemini response'));
47
56
  });
48
57
  describe('argument building', () => {
49
58
  it('should use agy with the default Gemini model and print mode', async () => {
50
59
  await executeAgyCLI('test', {});
51
60
  expect(MODELS.DEFAULT).toBe('Gemini 4 Argon (High)');
52
- expect(mockExecuteCommand).toHaveBeenCalledWith(CLI.COMMANDS.AGY, [CLI.FLAGS.MODEL, MODELS.DEFAULT, CLI.FLAGS.PRINT, 'test'], undefined, undefined);
61
+ expect(mockExecuteCommand).toHaveBeenCalledWith(CLI.COMMANDS.AGY, [CLI.FLAGS.MODEL, MODELS.DEFAULT, CLI.FLAGS.OUTPUT_FORMAT, 'json', CLI.FLAGS.PRINT, 'test'], undefined, undefined, { killAfterMs: AGY_LIMITS.DEFAULT_CEILING_MS, signal: undefined });
53
62
  });
54
63
  it.each([
55
64
  'Gemini 4 Argon (Low)',
@@ -87,6 +96,8 @@ describe('executeAgyCLI', () => {
87
96
  'src',
88
97
  CLI.FLAGS.ADD_DIR,
89
98
  'lib',
99
+ CLI.FLAGS.OUTPUT_FORMAT,
100
+ 'json',
90
101
  CLI.FLAGS.PRINT,
91
102
  'test',
92
103
  ]);
@@ -112,6 +123,7 @@ describe('executeAgyCLI', () => {
112
123
  expect(args).not.toContain(CLI.FLAGS.CONVERSATION);
113
124
  });
114
125
  it('should map conversation IDs to conversation flag', async () => {
126
+ mockExecuteCommand.mockResolvedValue(textEnvelope('resumed', { conversation_id: 'conversation-123' }));
115
127
  await executeAgyCLI('test', { resume: 'conversation-123' });
116
128
  const args = mockExecuteCommand.mock.calls[0][1];
117
129
  expect(args).toContain(CLI.FLAGS.CONVERSATION);
@@ -140,6 +152,16 @@ describe('executeAgyCLI', () => {
140
152
  expect(args).toContain('Gemini 3.8 Flash (Low)');
141
153
  });
142
154
  });
155
+ describe('process limits', () => {
156
+ it('limits agy to its print timeout plus the margin and passes the request signal', async () => {
157
+ const controller = new AbortController();
158
+ await executeAgyCLI('test', { printTimeout: '10m', signal: controller.signal });
159
+ expect(mockExecuteCommand.mock.calls[0][4]).toEqual({
160
+ killAfterMs: 10 * 60_000 + AGY_LIMITS.CEILING_MARGIN_MS,
161
+ signal: controller.signal,
162
+ });
163
+ });
164
+ });
143
165
  describe('unsupported legacy Gemini CLI options', () => {
144
166
  it.each([
145
167
  [{ debug: true }, 'debug'],
@@ -169,40 +191,82 @@ describe('executeAgyCLI', () => {
169
191
  await expect(executeAgyCLI('test', {})).rejects.toThrow(ERROR_MESSAGES.AGY_NOT_FOUND);
170
192
  });
171
193
  });
172
- describe('output recovery', () => {
173
- it('recovers from the transcript when stdout is empty', async () => {
174
- mockExecuteCommand.mockResolvedValue('');
175
- mockRecover.mockReturnValue('RECOVERED ANSWER');
176
- const result = await executeAgyCLI('test', {});
177
- expect(result).toBe('RECOVERED ANSWER');
178
- expect(mockRecover).toHaveBeenCalled();
194
+ describe('text answers from the JSON envelope', () => {
195
+ it('returns the trimmed envelope response as the text answer', async () => {
196
+ mockExecuteCommand.mockResolvedValue(textEnvelope('STEP-ONE\n\na real answer\n'));
197
+ expect(await executeAgyCLI('test', {})).toBe('STEP-ONE\n\na real answer');
179
198
  });
180
- it('recovers when stdout is the timeout sentinel', async () => {
181
- mockExecuteCommand.mockResolvedValue('Error: timed out waiting for response');
182
- mockRecover.mockReturnValue('RECOVERED ANSWER');
183
- const result = await executeAgyCLI('test', {});
184
- expect(result).toBe('RECOVERED ANSWER');
199
+ it('throws AGY_JSON_PARSE when agy printed nothing', async () => {
200
+ mockExecuteCommand.mockResolvedValue('');
201
+ await expect(executeAgyCLI('test', {})).rejects.toThrow(ERROR_MESSAGES.AGY_JSON_PARSE);
185
202
  });
186
- it('throws AGY_NO_OUTPUT for the timeout sentinel when recovery fails', async () => {
203
+ it('throws AGY_NO_OUTPUT for the timeout sentinel and caches nothing', async () => {
187
204
  mockIsCacheEnabled.mockReturnValue(true);
188
205
  mockExecuteCommand.mockResolvedValue('Error: timed out waiting for response');
189
- mockRecover.mockReturnValue(null);
190
206
  await expect(executeAgyCLI('test', {})).rejects.toThrow(ERROR_MESSAGES.AGY_NO_OUTPUT);
191
207
  expect(mockCacheResponse).not.toHaveBeenCalled();
192
208
  });
193
- it('returns empty (soft) and does not cache for genuinely empty output without recovery', async () => {
209
+ it.each([
210
+ ['an empty answer', textEnvelope('')],
211
+ ['a whitespace-only answer', textEnvelope(' \n ')],
212
+ ])('throws AGY_EMPTY_ANSWER with the conversation to resume for %s, and caches nothing', async (_label, stdout) => {
194
213
  mockIsCacheEnabled.mockReturnValue(true);
195
- mockExecuteCommand.mockResolvedValue('');
196
- mockRecover.mockReturnValue(null);
197
- const result = await executeAgyCLI('test', {});
198
- expect(result).toBe('');
214
+ mockExecuteCommand.mockResolvedValue(stdout);
215
+ await expect(executeAgyCLI('test', {})).rejects.toThrow(new Error(`${ERROR_MESSAGES.AGY_EMPTY_ANSWER} [GEMINI_CONVERSATION_ID=conv-abc]`));
199
216
  expect(mockCacheResponse).not.toHaveBeenCalled();
200
217
  });
201
- it('does not attempt recovery for normal output', async () => {
202
- mockExecuteCommand.mockResolvedValue('a real answer');
203
- const result = await executeAgyCLI('test', {});
204
- expect(result).toBe('a real answer');
205
- expect(mockRecover).not.toHaveBeenCalled();
218
+ it('throws AGY_EMPTY_ANSWER for an empty changeMode answer instead of reporting no edits', async () => {
219
+ mockExecuteCommand.mockResolvedValue(textEnvelope(''));
220
+ await expect(executeAgyCLI('test', { changeMode: true })).rejects.toThrow(ERROR_MESSAGES.AGY_EMPTY_ANSWER);
221
+ });
222
+ it('throws AGY_STATUS_ERROR with the envelope error text', async () => {
223
+ mockExecuteCommand.mockResolvedValue(textEnvelope('', { status: 'ERROR', error: 'model unavailable' }));
224
+ await expect(executeAgyCLI('test', {}))
225
+ .rejects.toThrow(`${ERROR_MESSAGES.AGY_STATUS_ERROR}: model unavailable`);
226
+ });
227
+ it('throws AGY_DENIED_ACTIONS when an empty answer came with denied actions', async () => {
228
+ mockExecuteCommand.mockResolvedValue(textEnvelope('', {
229
+ denied_actions: [{ action: 'command', display_name: 'RunCommand' }],
230
+ }));
231
+ await expect(executeAgyCLI('test', {}))
232
+ .rejects.toThrow(`${ERROR_MESSAGES.AGY_DENIED_ACTIONS}: RunCommand (command)`);
233
+ });
234
+ it('throws AGY_DENIED_ACTIONS when only a replayed structured_output came back', async () => {
235
+ mockExecuteCommand.mockResolvedValue(textEnvelope('', {
236
+ structured_output: { ok: true },
237
+ denied_actions: [{ action: 'command', display_name: 'RunCommand' }],
238
+ }));
239
+ await expect(executeAgyCLI('test', {}))
240
+ .rejects.toThrow(`${ERROR_MESSAGES.AGY_DENIED_ACTIONS}: RunCommand (command)`);
241
+ });
242
+ it('throws CHANGEMODE_DENIED_ACTIONS, not the yolo advice, when changeMode had an action denied', async () => {
243
+ mockExecuteCommand.mockResolvedValue(textEnvelope('', {
244
+ denied_actions: [{ action: 'write_file', display_name: 'EditFile' }],
245
+ }));
246
+ await expect(executeAgyCLI('test', { changeMode: true }))
247
+ .rejects.toThrow(`${ERROR_MESSAGES.CHANGEMODE_DENIED_ACTIONS}: EditFile (write_file)`);
248
+ });
249
+ it('names a denied shell command in changeMode without claiming Gemini acted on the files', async () => {
250
+ mockExecuteCommand.mockResolvedValue(textEnvelope('', {
251
+ denied_actions: [{ action: 'command', display_name: 'RunCommand' }],
252
+ }));
253
+ await expect(executeAgyCLI('test', { changeMode: true })).rejects.toThrow(new Error('changeMode returned no OLD/NEW edits. Ask again for the change as OLD/NEW edits, without yolo. ' +
254
+ 'Denied: RunCommand (command)'));
255
+ });
256
+ it('returns changeMode OLD/NEW text from the response for parsing', async () => {
257
+ const edits = `**FILE: src/a.ts:10**
258
+ \`\`\`
259
+ OLD:
260
+ const x = 1;
261
+ NEW:
262
+ const x = 2;
263
+ \`\`\``;
264
+ mockExecuteCommand.mockResolvedValue(textEnvelope(edits));
265
+ const result = await executeAgyCLI('test', { changeMode: true });
266
+ expect(result).toBe(edits);
267
+ const formatted = await processChangeModeOutput(result);
268
+ expect(formatted).toContain('[CHANGEMODE OUTPUT');
269
+ expect(formatted).toContain('const x = 2;');
206
270
  });
207
271
  });
208
272
  describe('safety guards', () => {
@@ -223,14 +287,14 @@ describe('executeAgyCLI', () => {
223
287
  it('should cache successful responses when cache is enabled', async () => {
224
288
  mockIsCacheEnabled.mockReturnValue(true);
225
289
  mockGetCachedResponse.mockReturnValue(undefined);
226
- mockExecuteCommand.mockResolvedValue('fresh result');
290
+ mockExecuteCommand.mockResolvedValue(textEnvelope('fresh result'));
227
291
  await executeAgyCLI('test', {});
228
292
  expect(mockCacheResponse).toHaveBeenCalledWith('mock-cache-key', 'fresh result');
229
293
  });
230
294
  it('should not cache changeMode responses', async () => {
231
295
  mockIsCacheEnabled.mockReturnValue(true);
232
296
  mockGetCachedResponse.mockReturnValue(undefined);
233
- mockExecuteCommand.mockResolvedValue('edit result');
297
+ mockExecuteCommand.mockResolvedValue(textEnvelope('edit result'));
234
298
  await executeAgyCLI('test', { changeMode: true });
235
299
  expect(mockCacheResponse).not.toHaveBeenCalled();
236
300
  });
@@ -378,19 +442,6 @@ new
378
442
  expect(result).toContain('src/fresh.ts');
379
443
  });
380
444
  });
381
- const ENVELOPE = {
382
- conversation_id: 'conv-abc',
383
- status: 'SUCCESS',
384
- response: 'plain answer',
385
- structured_output: { ok: true },
386
- num_turns: 2,
387
- duration_seconds: 12.5,
388
- usage: { input_tokens: 100, output_tokens: 20, thinking_tokens: 5, cache_read_tokens: 0, total_tokens: 125 },
389
- denied_actions: [],
390
- };
391
- function envelopeLine(overrides = {}) {
392
- return JSON.stringify({ ...ENVELOPE, ...overrides });
393
- }
394
445
  describe('executeAgyCLI json mode', () => {
395
446
  beforeEach(() => {
396
447
  vi.clearAllMocks();
@@ -431,11 +482,10 @@ describe('executeAgyCLI json mode', () => {
431
482
  await expect(executeAgyCLI('test', { outputFormat: 'json' }))
432
483
  .rejects.toThrow('--effort is not supported for model "Gemini 3.8 Flash (High)"');
433
484
  });
434
- it('throws AGY_JSON_PARSE for empty stdout and never runs transcript recovery', async () => {
485
+ it('throws AGY_JSON_PARSE for empty stdout', async () => {
435
486
  mockExecuteCommand.mockResolvedValue('');
436
487
  await expect(executeAgyCLI('test', { outputFormat: 'json' }))
437
488
  .rejects.toThrow(ERROR_MESSAGES.AGY_JSON_PARSE);
438
- expect(mockRecover).not.toHaveBeenCalled();
439
489
  });
440
490
  it('throws AGY_NO_OUTPUT for the timeout sentinel', async () => {
441
491
  mockExecuteCommand.mockResolvedValue('Error: timed out waiting for response');
@@ -453,6 +503,33 @@ describe('executeAgyCLI json mode', () => {
453
503
  .rejects.toThrow('RunCommand (command)');
454
504
  expect(mockCacheResponse).not.toHaveBeenCalled();
455
505
  });
506
+ it.each([
507
+ ['no structured_output', { structured_output: null }],
508
+ ['a structured_output replayed without a schema', { structured_output: { ok: true } }],
509
+ ])('never caches an envelope with an empty response and %s', async (_label, overrides) => {
510
+ mockIsCacheEnabled.mockReturnValue(true);
511
+ const raw = envelopeLine({ response: '', ...overrides });
512
+ mockExecuteCommand.mockResolvedValue(raw);
513
+ expect(await executeAgyCLI('test', { outputFormat: 'json' })).toBe(raw);
514
+ expect(mockCacheResponse).not.toHaveBeenCalled();
515
+ });
516
+ it('caches an envelope whose only answer is this call\'s schema output', async () => {
517
+ mockIsCacheEnabled.mockReturnValue(true);
518
+ const raw = envelopeLine({ response: '' });
519
+ mockExecuteCommand.mockResolvedValue(raw);
520
+ await executeAgyCLI('test', { outputFormat: 'json', jsonSchema: '{"type":"object"}' });
521
+ expect(mockCacheResponse).toHaveBeenCalledWith('mock-cache-key', raw);
522
+ });
523
+ it('returns a SUCCESS envelope with an empty answer for its json caller to report', async () => {
524
+ const raw = envelopeLine({ response: '', structured_output: null });
525
+ mockExecuteCommand.mockResolvedValue(raw);
526
+ expect(await executeAgyCLI('test', { outputFormat: 'json' })).toBe(raw);
527
+ });
528
+ it('resolves when actions were denied but this call\'s schema answer came back', async () => {
529
+ const raw = envelopeLine({ response: '', denied_actions: [{ action: 'command', display_name: 'RunCommand' }] });
530
+ mockExecuteCommand.mockResolvedValue(raw);
531
+ expect(await executeAgyCLI('test', { outputFormat: 'json', jsonSchema: '{"type":"object"}' })).toBe(raw);
532
+ });
456
533
  it('resolves when actions were denied but a response still came back', async () => {
457
534
  const raw = envelopeLine({ denied_actions: [{ action: 'command', display_name: 'RunCommand' }] });
458
535
  mockExecuteCommand.mockResolvedValue(raw);
@@ -504,10 +581,11 @@ describe('option validation', () => {
504
581
  expect(args).toContain(CLI.FLAGS.EFFORT);
505
582
  expect(args).toContain('medium');
506
583
  });
507
- it('leaves text mode arguments unchanged when outputFormat is text', async () => {
508
- await executeAgyCLI('test', { outputFormat: 'text' });
584
+ it('asks agy for its JSON envelope when the caller wants text', async () => {
585
+ mockExecuteCommand.mockResolvedValue(textEnvelope('plain answer'));
586
+ expect(await executeAgyCLI('test', { outputFormat: 'text' })).toBe('plain answer');
509
587
  expect(mockExecuteCommand.mock.calls[0][1]).toEqual([
510
- CLI.FLAGS.MODEL, MODELS.DEFAULT, CLI.FLAGS.PRINT, 'test',
588
+ CLI.FLAGS.MODEL, MODELS.DEFAULT, CLI.FLAGS.OUTPUT_FORMAT, 'json', CLI.FLAGS.PRINT, 'test',
511
589
  ]);
512
590
  });
513
591
  });
@@ -524,11 +602,10 @@ describe('conversation resolution', () => {
524
602
  expect(args).toContain('conv-abc');
525
603
  expect(args).not.toContain(CLI.FLAGS.CONTINUE);
526
604
  });
527
- it('hands the explicit conversation id to transcript recovery', async () => {
528
- mockExecuteCommand.mockResolvedValue('');
529
- mockRecover.mockReturnValue('RECOVERED');
530
- await executeAgyCLI('test', { conversationId: 'conv-abc' });
531
- expect(mockRecover).toHaveBeenCalledWith(expect.objectContaining({ conversationId: 'conv-abc' }));
605
+ it('throws CONVERSATION_NOT_RESUMED when a text call started a new conversation instead', async () => {
606
+ mockExecuteCommand.mockResolvedValue(textEnvelope('an answer', { conversation_id: 'conv-other' }));
607
+ await expect(executeAgyCLI('test', { conversationId: 'conv-abc' }))
608
+ .rejects.toThrow(`${ERROR_MESSAGES.CONVERSATION_NOT_RESUMED} conv-abc`);
532
609
  });
533
610
  it.each([
534
611
  ['resume', { resume: true }],
@@ -613,4 +690,42 @@ describe('envelope rendering', () => {
613
690
  expect(formatConversationLine('conv-abc')).toBe('[GEMINI_CONVERSATION_ID=conv-abc]');
614
691
  });
615
692
  });
693
+ describe('agyKillAfterMs', () => {
694
+ it.each([
695
+ ['90s', 90_000],
696
+ ['15m', 15 * 60_000],
697
+ ['1h', 60 * 60_000],
698
+ ['2h30m', 150 * 60_000],
699
+ ['1h30m', 90 * 60_000],
700
+ ['2.5h', 150 * 60_000],
701
+ ['1m30.5s', 90_500],
702
+ ['500ms', 500],
703
+ ])('limits a %s print timeout to it plus the margin', (printTimeout, timeoutMs) => {
704
+ expect(agyKillAfterMs(printTimeout)).toBe(timeoutMs + AGY_LIMITS.CEILING_MARGIN_MS);
705
+ });
706
+ it.each([
707
+ ['no print timeout', undefined],
708
+ ['an empty value', ''],
709
+ ['garbage', 'abc'],
710
+ ['a unit with no amount', 'h'],
711
+ ['a duration followed by garbage', '1habc'],
712
+ ['a zero timeout, which agy reads as no limit', '0'],
713
+ ['a zero duration', '0s'],
714
+ ['a compound zero duration', '0h0m'],
715
+ ['a bare number', '600'],
716
+ ['an overflowing duration', `${'9'.repeat(400)}h`],
717
+ ])('falls back to the default ceiling for %s', (_label, printTimeout) => {
718
+ expect(agyKillAfterMs(printTimeout)).toBe(AGY_LIMITS.DEFAULT_CEILING_MS);
719
+ });
720
+ });
721
+ describe('printTimeoutSchema', () => {
722
+ it.each(['90s', '15m', '1h', '2h30m', '2.5h', '1m30.5s', '500ms', '0', '0s'])('accepts %j', (printTimeout) => {
723
+ expect(printTimeoutSchema.safeParse(printTimeout).success).toBe(true);
724
+ });
725
+ it.each([
726
+ '', 'abc', 'h', '1habc', '+3h', '-1h', '1h30', '.5h', '600', '1us', '90 s', ' 90s',
727
+ ])('rejects %j', (printTimeout) => {
728
+ expect(printTimeoutSchema.safeParse(printTimeout).success).toBe(false);
729
+ });
730
+ });
616
731
  //# sourceMappingURL=agyExecutor.test.js.map