@guildai/cli 0.6.0 → 0.6.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 (59) hide show
  1. package/README.md +17 -0
  2. package/dist/commands/agent/chat.js +31 -31
  3. package/dist/commands/agent/fork.js +1 -1
  4. package/dist/commands/agent/init.js +1 -1
  5. package/dist/commands/agent/publish.js +13 -53
  6. package/dist/commands/agent/pull.js +36 -21
  7. package/dist/commands/agent/save.js +16 -52
  8. package/dist/commands/agent/test.js +8 -12
  9. package/dist/commands/auth/login.js +3 -3
  10. package/dist/commands/chat.js +68 -106
  11. package/dist/commands/credentials/endpoint-list.js +1 -1
  12. package/dist/commands/integration/connect.d.ts +3 -0
  13. package/dist/commands/integration/connect.js +76 -0
  14. package/dist/commands/integration/create.d.ts +3 -0
  15. package/dist/commands/integration/create.js +298 -0
  16. package/dist/commands/integration/get.d.ts +3 -0
  17. package/dist/commands/integration/get.js +95 -0
  18. package/dist/commands/integration/list.d.ts +3 -0
  19. package/dist/commands/integration/list.js +61 -0
  20. package/dist/commands/integration/operation/create.d.ts +3 -0
  21. package/dist/commands/integration/operation/create.js +163 -0
  22. package/dist/commands/integration/operation/list.d.ts +3 -0
  23. package/dist/commands/integration/operation/list.js +83 -0
  24. package/dist/commands/integration/update.d.ts +3 -0
  25. package/dist/commands/integration/update.js +139 -0
  26. package/dist/commands/integration/version/build.d.ts +3 -0
  27. package/dist/commands/integration/version/build.js +86 -0
  28. package/dist/commands/integration/version/create.d.ts +3 -0
  29. package/dist/commands/integration/version/create.js +45 -0
  30. package/dist/commands/integration/version/get.d.ts +3 -0
  31. package/dist/commands/integration/version/get.js +72 -0
  32. package/dist/commands/integration/version/list.d.ts +3 -0
  33. package/dist/commands/integration/version/list.js +44 -0
  34. package/dist/commands/integration/version/publish.d.ts +3 -0
  35. package/dist/commands/integration/version/publish.js +79 -0
  36. package/dist/commands/integration/version/test.d.ts +3 -0
  37. package/dist/commands/integration/version/test.js +104 -0
  38. package/dist/commands/workspace/create.js +10 -4
  39. package/dist/index.js +38 -0
  40. package/dist/lib/api-types.d.ts +69 -12
  41. package/dist/lib/auth.d.ts +1 -1
  42. package/dist/lib/auth.js +3 -2
  43. package/dist/lib/integration-helpers.d.ts +15 -0
  44. package/dist/lib/integration-helpers.js +38 -0
  45. package/dist/lib/output.d.ts +11 -1
  46. package/dist/lib/output.js +94 -0
  47. package/dist/lib/session-events-fetch.d.ts +27 -0
  48. package/dist/lib/session-events-fetch.js +25 -0
  49. package/dist/lib/session-polling.d.ts +7 -2
  50. package/dist/lib/session-polling.js +19 -12
  51. package/dist/lib/session-resume.js +2 -5
  52. package/dist/lib/table.d.ts +0 -1
  53. package/dist/lib/table.js +0 -1
  54. package/dist/lib/version-helpers.d.ts +15 -0
  55. package/dist/lib/version-helpers.js +83 -0
  56. package/dist/mcp/tools.js +6 -12
  57. package/docs/CLI_WORKFLOW.md +15 -0
  58. package/docs/skills/agent-dev.md +15 -0
  59. package/package.json +4 -3
package/README.md CHANGED
@@ -183,6 +183,23 @@ guild trigger deactivate <trigger-id> # Deactivate a trigger
183
183
  guild trigger sessions <trigger-id> # List sessions spawned by a trigger
184
184
  ```
185
185
 
186
+ ### Integrations
187
+
188
+ ```bash
189
+ guild integration list # List integrations
190
+ guild integration get <id> # Get integration details
191
+ guild integration create <name> # Create a new integration
192
+ guild integration update <id> # Update an integration
193
+ guild integration version list <id> # List versions
194
+ guild integration version create <id> # Create a draft version
195
+ guild integration version get <id> # Get version details
196
+ guild integration version build <id> # Build (validate) a draft
197
+ guild integration version publish <id> # Publish a built version
198
+ guild integration version test <id> # Test an endpoint invocation
199
+ guild integration operation list <id> # List operations for a version
200
+ guild integration operation create <id> # Create operations (or import from OpenAPI)
201
+ ```
202
+
186
203
  ### Chat
187
204
 
188
205
  ```bash
@@ -38,13 +38,29 @@ export function createAgentChatCommand() {
38
38
  .option('--no-splash', 'Skip the splash screen animation')
39
39
  .option('--resume <session-id>', 'Resume an existing session')
40
40
  .option('--open', 'Open session in web dashboard')
41
- .addHelpText('after', '\nFor general chat with the Guild assistant, use: guild chat')
41
+ .addHelpText('after', '\nTo chat with a published agent by name: guild chat --agent owner/agent-name')
42
42
  .action(async (promptArgs, options) => {
43
43
  try {
44
44
  // Get agent ID from guild.json in the specified path
45
45
  const agentPath = options.path || '.';
46
46
  const { agentId, config } = await getAgentId(undefined, agentPath);
47
47
  const initialPrompt = promptArgs.length > 0 ? promptArgs.join(' ') : 'Hello';
48
+ // If using JSON input, read it early (before auth) for fast failure on bad input
49
+ let inputData;
50
+ if (options.mode === 'json') {
51
+ try {
52
+ inputData = await readStdinAsJSON();
53
+ }
54
+ catch (error) {
55
+ const err = error;
56
+ console.error(`Error: ${err.message}`);
57
+ console.error('');
58
+ console.error('Example usage:');
59
+ console.error(' echo \'{"prompt": "test"}\' | guild agent chat --mode json');
60
+ console.error(' guild agent chat --mode json < input.json');
61
+ process.exit(1);
62
+ }
63
+ }
48
64
  // Check authentication (uses shared function from chat.tsx)
49
65
  await ensureAuthenticated();
50
66
  const client = new GuildAPIClient();
@@ -152,25 +168,14 @@ export function createAgentChatCommand() {
152
168
  console.error(` guild agent chat ${agentId}`);
153
169
  process.exit(1);
154
170
  }
155
- // If using JSON input, read it early (before session creation)
156
- let inputData;
157
- if (options.mode === 'json') {
158
- try {
159
- inputData = await readStdinAsJSON();
160
- }
161
- catch (error) {
162
- const err = error;
163
- console.error(`Error: ${err.message}`);
164
- console.error('');
165
- console.error('Example usage:');
166
- console.error(' echo \'{"prompt": "test"}\' | guild agent chat --mode json');
167
- console.error(' guild agent chat --mode json < input.json');
168
- process.exit(1);
169
- }
170
- }
171
171
  // Branch: JSON/JSONL modes vs interactive
172
172
  if (options.mode === 'json' || options.mode === 'jsonl') {
173
- const session = await createSession(client, options.workspace, initialPrompt, version.id);
173
+ // For JSON mode with piped input, use the piped data as the initial prompt
174
+ // so the agent receives it as its input (not the default 'Hello')
175
+ const sessionPrompt = options.mode === 'json' && inputData
176
+ ? JSON.stringify(inputData)
177
+ : initialPrompt;
178
+ const session = await createSession(client, options.workspace, sessionPrompt, version.id);
174
179
  if (!quiet) {
175
180
  console.log(`✓ Agent: ${config?.name || agentId}`);
176
181
  const sessionLink = session.session_url
@@ -183,13 +188,10 @@ export function createAgentChatCommand() {
183
188
  await open(session.session_url);
184
189
  }
185
190
  if (options.mode === 'json' && inputData) {
186
- // JSON one-shot mode
191
+ // JSON one-shot mode — input was passed as initial_prompt during
192
+ // session creation, so the agent already has it. Just poll for the response.
187
193
  try {
188
- await client.post(`/sessions/${session.id}/events`, {
189
- mode: 'json',
190
- content: inputData,
191
- });
192
- const response = await pollForResponse(client, session.id, 0);
194
+ const { response } = await pollForResponse(client, session.id, undefined);
193
195
  if (!response) {
194
196
  console.error('Timeout: No response received from agent');
195
197
  process.exit(1);
@@ -219,7 +221,7 @@ export function createAgentChatCommand() {
219
221
  });
220
222
  let lineNumber = 0;
221
223
  let processedCount = 0;
222
- let lastEventCount = 0;
224
+ let lastEventId;
223
225
  for await (const line of rl) {
224
226
  lineNumber++;
225
227
  if (!line.trim())
@@ -233,15 +235,13 @@ export function createAgentChatCommand() {
233
235
  mode: 'json',
234
236
  content: jsonInput,
235
237
  });
236
- const response = await pollForResponse(client, session.id, lastEventCount);
237
- if (!response) {
238
+ const result = await pollForResponse(client, session.id, lastEventId);
239
+ lastEventId = result.lastEventId;
240
+ if (!result.response) {
238
241
  console.error(`Timeout: No response for line ${lineNumber}`);
239
- const eventsAfterResponse = await client.get(`/sessions/${session.id}/events`);
240
- lastEventCount = eventsAfterResponse?.items?.length || 0;
241
242
  continue;
242
243
  }
243
- const eventsAfterResponse = await client.get(`/sessions/${session.id}/events`);
244
- lastEventCount = eventsAfterResponse?.items?.length || 0;
244
+ const response = result.response;
245
245
  if (quiet) {
246
246
  console.log(response);
247
247
  }
@@ -52,7 +52,7 @@ export function createAgentForkCommand() {
52
52
  .option('--name <name>', 'Name for the forked agent')
53
53
  .option('--description <desc>', 'Description for the forked agent')
54
54
  .option('--directory <path>', 'Target directory for clone')
55
- .option('--owner <owner-id>', 'Owner account (user or organization ID)')
55
+ .option('--owner <owner>', 'Owner (name or ID)')
56
56
  .action(async (identifierArg, options) => {
57
57
  const output = createOutputWriter();
58
58
  try {
@@ -79,7 +79,7 @@ export function createAgentInitCommand() {
79
79
  .option('--name <name>', 'Agent name')
80
80
  .option('--template <template>', 'Agent template (LLM, AUTO_MANAGED_STATE, BLANK)')
81
81
  .option('--fork <agent-id>', 'Fork from existing agent')
82
- .option('--owner <owner-id>', 'Owner account (user or organization ID)')
82
+ .option('--owner <owner>', 'Owner (name or ID)')
83
83
  .option('--directory <path>', 'Directory to initialize (created if needed)')
84
84
  .option('--force', 'Overwrite existing guild.json', false)
85
85
  .action(async (options) => {
@@ -4,8 +4,8 @@ import { Command } from 'commander';
4
4
  import { GuildAPIClient } from '../../lib/api-client.js';
5
5
  import { getAgentId, resolveAgentRef } from '../../lib/agent-helpers.js';
6
6
  import { handleAxiosError, ErrorCodes } from '../../lib/errors.js';
7
- import { pollUntilComplete } from '../../lib/polling.js';
8
7
  import { createOutputWriter } from '../../lib/output.js';
8
+ import { waitForValidation, waitForPublish } from '../../lib/version-helpers.js';
9
9
  export function createAgentPublishCommand() {
10
10
  const cmd = new Command('publish');
11
11
  cmd
@@ -37,71 +37,31 @@ export function createAgentPublishCommand() {
37
37
  process.exit(1);
38
38
  }
39
39
  // Check validation status before attempting publish
40
- let validationStatus = versionToPublish.validation_status;
41
40
  let currentVersion = versionToPublish;
41
+ const validationStatus = currentVersion.validation_status;
42
42
  if (validationStatus === 'PENDING' || validationStatus === 'RUNNING') {
43
43
  if (options.wait) {
44
- // Wait for validation to complete
45
- const result = await pollUntilComplete({
46
- resourceId: versionToPublish.id,
47
- endpoint: `/versions/${versionToPublish.id}`,
48
- isComplete: (response) => response.validation_status !== 'PENDING' &&
49
- response.validation_status !== 'RUNNING',
50
- message: 'Waiting for validation to complete...',
51
- successMessage: 'Validation complete',
52
- timeoutMessage: 'Validation timed out',
53
- maxAttempts: 120, // 2 minutes
54
- delayMs: 1000,
55
- });
56
- if (!result.success || !result.response) {
57
- output.error('Validation did not complete in time', 'Check status manually:\n guild agent versions');
58
- process.exit(1);
59
- }
60
- currentVersion = result.response;
61
- validationStatus = currentVersion.validation_status;
62
- // Re-check validation status after waiting - will be handled below
63
- // by the main validation check
44
+ currentVersion = await waitForValidation(currentVersion.id, output);
64
45
  }
65
46
  else {
66
- output.error('Cannot publish: validation is still in progress', `Validation status: ${validationStatus === 'PENDING' ? 'Waiting to start' : 'Running'}\n\nThe version number is extracted from package.json during validation.\n\nOptions:\n • Wait for validation: guild agent publish --wait\n • Check status: guild agent versions`);
47
+ output.error('Cannot publish: validation is still in progress', `Validation status: ${validationStatus === 'PENDING' ? 'Waiting to start' : 'Running'}\n\nOptions:\n • Wait for validation: guild agent publish --wait\n • Check status: guild agent versions`);
67
48
  process.exit(1);
68
49
  }
69
50
  }
70
- if (validationStatus === 'FAILED') {
71
- // Fetch validation steps to show the actual error
72
- let failureDetails = '';
73
- try {
74
- const stepsResponse = await client.get(`/versions/${currentVersion.id}/validation/steps`);
75
- const failedSteps = stepsResponse.steps.filter((step) => step.status === 'FAILED');
76
- if (failedSteps.length > 0) {
77
- const stepMessages = failedSteps.map((step) => {
78
- let msg = `Step "${step.name}" failed:`;
79
- if (step.content) {
80
- msg += `\n ${step.content}`;
81
- }
82
- return msg;
83
- });
84
- failureDetails = stepMessages.join('\n\n');
85
- }
86
- else {
87
- failureDetails =
88
- 'No failed steps found. Check validation logs for details.';
89
- }
90
- }
91
- catch {
92
- // If we can't fetch steps, just show generic message
93
- failureDetails = 'Could not fetch validation details.';
94
- }
95
- output.error('Cannot publish: validation failed', `${failureDetails}\n\nFix the issues, then save a new version:\n guild agent save --message "Fix validation errors"`);
51
+ else if (validationStatus === 'FAILED') {
52
+ output.error('Cannot publish: validation failed', 'Fix the issues, then save a new version:\n guild agent save --message "Fix validation errors"');
96
53
  process.exit(1);
97
54
  }
98
- // Note: version_number is only set after validation extracts it from package.json,
99
- // and only enforced at publish time (drafts don't require versions)
100
55
  // Publish version
101
- await client.post(`/versions/${currentVersion.id}/publish`, {});
56
+ currentVersion = await client.post(`/versions/${currentVersion.id}/publish`, {});
57
+ if (options.wait && currentVersion.status !== 'PUBLISHED') {
58
+ currentVersion = await waitForPublish(currentVersion.id, output);
59
+ }
102
60
  const details = {
103
61
  agent: `${currentVersion.agent?.name || config?.name || agentId}${config ? '' : ` (${agentId})`}`,
104
- status: 'DRAFT PUBLISHED',
62
+ status: currentVersion.status === 'PUBLISHED'
63
+ ? 'DRAFT → PUBLISHED'
64
+ : 'DRAFT → PUBLISHING',
105
65
  };
106
66
  if (currentVersion.version_number) {
107
67
  details.version = currentVersion.version_number;
@@ -3,6 +3,7 @@
3
3
  import { Command } from 'commander';
4
4
  import { GuildAPIClient } from '../../lib/api-client.js';
5
5
  import { handleAxiosError, ErrorCodes } from '../../lib/errors.js';
6
+ import { getOutputMode } from '../../lib/output-mode.js';
6
7
  import { createOutputWriter } from '../../lib/output.js';
7
8
  import * as fs from 'fs/promises';
8
9
  import * as path from 'path';
@@ -90,10 +91,12 @@ export function createAgentPullCommand() {
90
91
  if (errMessage.includes('no tracking information') ||
91
92
  errMessage.includes("couldn't find remote ref")) {
92
93
  output.progress('✓ Already up to date (no remote branch yet)');
93
- output.data({
94
- success: true,
95
- message: 'Already up to date (no remote branch yet)',
96
- });
94
+ if (getOutputMode() === 'json') {
95
+ output.data({
96
+ success: true,
97
+ message: 'Already up to date (no remote branch yet)',
98
+ });
99
+ }
97
100
  return;
98
101
  }
99
102
  // Unknown git error
@@ -109,22 +112,28 @@ export function createAgentPullCommand() {
109
112
  // Truly up to date — git pull + version match
110
113
  if (!gitPulledNewCommits) {
111
114
  output.progress('✓ Already up to date');
112
- output.data({ success: true, message: 'Already up to date' });
113
115
  }
114
- else {
115
- output.data({ success: true, message: 'Pulled remote changes' });
116
+ if (getOutputMode() === 'json') {
117
+ output.data({
118
+ success: true,
119
+ message: gitPulledNewCommits
120
+ ? 'Pulled remote changes'
121
+ : 'Already up to date',
122
+ });
116
123
  }
117
124
  }
118
125
  else if (latest.sha && latest.sha !== localHead) {
119
126
  // SHA mismatch — warn user
120
127
  output.progress(`⚠ Remote has a newer version (${latest.sha.slice(0, 7)}) not on this branch`);
121
128
  output.progress(' Try: git fetch origin && git log --oneline origin/main');
122
- output.data({
123
- success: true,
124
- message: 'SHA mismatch with latest version',
125
- latest_sha: latest.sha,
126
- local_sha: localHead,
127
- });
129
+ if (getOutputMode() === 'json') {
130
+ output.data({
131
+ success: true,
132
+ message: 'SHA mismatch with latest version',
133
+ latest_sha: latest.sha,
134
+ local_sha: localHead,
135
+ });
136
+ }
128
137
  }
129
138
  else {
130
139
  // Ephemeral version — download from API
@@ -142,21 +151,27 @@ export function createAgentPullCommand() {
142
151
  await fs.writeFile(filePath, file.content, 'utf-8');
143
152
  }
144
153
  output.progress(`✓ Downloaded ${files.length} files from latest draft version`);
145
- output.data({
146
- success: true,
147
- message: `Downloaded ${files.length} files from draft version`,
148
- files_updated: files.length,
149
- });
154
+ if (getOutputMode() === 'json') {
155
+ output.data({
156
+ success: true,
157
+ message: `Downloaded ${files.length} files from draft version`,
158
+ files_updated: files.length,
159
+ });
160
+ }
150
161
  }
151
162
  }
152
163
  else {
153
164
  // No versions exist yet — just report git pull result
154
165
  if (!gitPulledNewCommits) {
155
166
  output.progress('✓ Already up to date');
156
- output.data({ success: true, message: 'Already up to date' });
157
167
  }
158
- else {
159
- output.data({ success: true, message: 'Pulled remote changes' });
168
+ if (getOutputMode() === 'json') {
169
+ output.data({
170
+ success: true,
171
+ message: gitPulledNewCommits
172
+ ? 'Pulled remote changes'
173
+ : 'Already up to date',
174
+ });
160
175
  }
161
176
  }
162
177
  }
@@ -9,13 +9,13 @@ import * as fs from 'fs/promises';
9
9
  import * as path from 'path';
10
10
  import { getAuthenticatedUrl } from '../../lib/auth.js';
11
11
  import { runGit, GitError, formatGitError } from '../../lib/git.js';
12
- import { pollUntilComplete } from '../../lib/polling.js';
12
+ import { waitForValidation, waitForPublish } from '../../lib/version-helpers.js';
13
13
  export function createAgentSaveCommand() {
14
14
  const cmd = new Command('save');
15
15
  cmd
16
- .description('Push committed changes to Guild and create a version')
16
+ .description('Commit, push, and create a new agent version')
17
17
  .option('-A, --all', 'Stage all changes and commit before pushing', false)
18
- .option('--message <text>', 'Commit message (required with --all)')
18
+ .option('-m, --message <text>', 'Commit message (required with --all)')
19
19
  .option('--wait', 'Wait for validation to complete before returning', false)
20
20
  .option('--publish', 'Publish after validation passes (implies --wait)', false)
21
21
  .option('--bump [level]', 'Bump package.json version before saving (patch, or minor/major)', 'patch')
@@ -255,58 +255,18 @@ export function createAgentSaveCommand() {
255
255
  version_type: 'COMMITTED',
256
256
  });
257
257
  output.progress(`✓ Created version (${version.id})`);
258
- // --publish implies --wait
259
- const shouldWait = options.wait || options.publish;
260
- // If --wait or --publish, wait for validation to complete
261
- if (shouldWait) {
262
- const pollResult = await pollUntilComplete({
263
- resourceId: version.id,
264
- endpoint: `/versions/${version.id}`,
265
- isComplete: (response) => response.validation_status !== 'PENDING' &&
266
- response.validation_status !== 'RUNNING',
267
- message: 'Waiting for validation to complete...',
268
- successMessage: 'Validation complete',
269
- timeoutMessage: 'Validation timed out',
270
- maxAttempts: 120, // 2 minutes
271
- delayMs: 1000,
272
- });
273
- if (!pollResult.success || !pollResult.response) {
274
- output.error('Validation did not complete in time', 'Check status manually:\n guild agent versions');
275
- process.exit(1);
276
- }
277
- version = pollResult.response;
278
- // Check validation status
279
- if (version.validation_status === 'FAILED') {
280
- let failureDetails = '';
281
- // Fetch validation steps to show the actual error
282
- try {
283
- const stepsResponse = await client.get(`/versions/${version.id}/validation/steps`);
284
- const failedSteps = stepsResponse.steps.filter((step) => step.status === 'FAILED');
285
- if (failedSteps.length > 0) {
286
- const stepMessages = failedSteps.map((step) => step.content
287
- ? `Step "${step.name}" failed: ${step.content}`
288
- : `Step "${step.name}" failed`);
289
- failureDetails = stepMessages.join('\n');
290
- }
291
- else {
292
- failureDetails =
293
- 'No failed steps found. Check validation logs for details.';
294
- }
295
- }
296
- catch {
297
- failureDetails = 'Could not fetch validation details.';
298
- }
299
- failureDetails +=
300
- '\n\nFix the issues, commit, and save a new version:\n git add . && git commit -m "Fix validation errors"\n guild agent save';
301
- output.error('Validation failed', failureDetails);
302
- process.exit(1);
303
- }
258
+ if (options.wait) {
259
+ version = await waitForValidation(version.id, output);
304
260
  }
305
- // If --publish and validation passed, publish the version
306
261
  if (options.publish) {
307
262
  output.progress('Validation passed, publishing...');
308
263
  version = await client.post(`/versions/${version.id}/publish`, {});
309
- output.progress('✓ Published');
264
+ if (options.wait && version.status !== 'PUBLISHED') {
265
+ version = await waitForPublish(version.id, output);
266
+ }
267
+ else {
268
+ output.progress('✓ Published');
269
+ }
310
270
  }
311
271
  output.progress('');
312
272
  output.progress('Version details:');
@@ -317,10 +277,14 @@ export function createAgentSaveCommand() {
317
277
  output.progress(` Published at: ${version.published_at}`);
318
278
  }
319
279
  output.progress(` Summary: ${version.summary}`);
320
- if (options.publish) {
280
+ if (options.publish && version.status === 'PUBLISHED') {
321
281
  output.progress('');
322
282
  output.progress('Version is now published and available in the catalog.');
323
283
  }
284
+ else if (options.publish) {
285
+ output.progress('');
286
+ output.progress('Publish is in progress. Use --wait to wait for completion.');
287
+ }
324
288
  else {
325
289
  output.progress('');
326
290
  output.progress('To publish this version:');
@@ -303,9 +303,9 @@ export function createAgentTestCommand() {
303
303
  mode: 'json',
304
304
  content: inputData,
305
305
  });
306
- // Poll for response (starting from event 0)
306
+ // Poll for response (starting from beginning)
307
307
  // 3 minutes - allow time for agents that use LLM calls for input parsing
308
- const response = await pollForResponse(client, session.id, 0, 180000);
308
+ const { response } = await pollForResponse(client, session.id, undefined, 180000);
309
309
  if (!response) {
310
310
  console.error('Error: No response received from agent within timeout');
311
311
  console.error('');
@@ -365,7 +365,7 @@ export function createAgentTestCommand() {
365
365
  });
366
366
  let lineNumber = 0;
367
367
  let processedCount = 0;
368
- let lastEventCount = 0;
368
+ let lastEventId;
369
369
  for await (const line of rl) {
370
370
  lineNumber++;
371
371
  if (!line.trim())
@@ -380,18 +380,14 @@ export function createAgentTestCommand() {
380
380
  mode: 'json',
381
381
  content: jsonInput,
382
382
  });
383
- // Wait for response (looking for events after our last count)
384
- const response = await pollForResponse(client, session.id, lastEventCount, 180000);
385
- if (!response) {
383
+ // Wait for response (looking for events after last seen)
384
+ const result = await pollForResponse(client, session.id, lastEventId, 180000);
385
+ lastEventId = result.lastEventId;
386
+ if (!result.response) {
386
387
  console.error(`Timeout: No response for line ${lineNumber}`);
387
- // Update event count even if timeout
388
- const eventsAfterResponse = await client.get(`/sessions/${session.id}/events`);
389
- lastEventCount = eventsAfterResponse?.items?.length || 0;
390
388
  continue;
391
389
  }
392
- // Update last event count
393
- const eventsAfterResponse = await client.get(`/sessions/${session.id}/events`);
394
- lastEventCount = eventsAfterResponse?.items?.length || 0;
390
+ const response = result.response;
395
391
  // Output response
396
392
  if (quiet) {
397
393
  // In quiet mode, output just the message content (or as JSON if --json is used)
@@ -11,11 +11,11 @@ export function createAuthLoginCommand() {
11
11
  .description('Login to Guild.ai')
12
12
  .option('--return-url <url>', 'Custom URL to redirect to after authentication')
13
13
  .option('--return-label <text>', 'Friendly label for return button (e.g., "VSCode")')
14
- .option('--no-browser', 'Skip opening the browser (print URL only)')
14
+ .option('--non-interactive', 'Skip interactive prompts (for use with coding agents)')
15
15
  .action(async (options) => {
16
16
  const output = createOutputWriter();
17
- const noBrowser = options.browser === false;
18
- const success = await login(options.returnUrl, options.returnLabel, noBrowser);
17
+ const nonInteractive = options.nonInteractive || false;
18
+ const success = await login(options.returnUrl, options.returnLabel, nonInteractive);
19
19
  if (success) {
20
20
  try {
21
21
  await configureNpmrc();