@guildai/cli 0.7.0 → 0.7.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 (41) hide show
  1. package/dist/commands/agent/chat.js +29 -62
  2. package/dist/commands/agent/clone.js +1 -1
  3. package/dist/commands/agent/code.js +1 -1
  4. package/dist/commands/agent/fork.js +2 -2
  5. package/dist/commands/agent/get.js +1 -1
  6. package/dist/commands/agent/grep.js +2 -2
  7. package/dist/commands/agent/init.js +10 -3
  8. package/dist/commands/agent/list.js +9 -1
  9. package/dist/commands/agent/publish.js +1 -1
  10. package/dist/commands/agent/revalidate.js +1 -1
  11. package/dist/commands/agent/save.js +23 -2
  12. package/dist/commands/agent/test.js +59 -92
  13. package/dist/commands/agent/unpublish.js +1 -1
  14. package/dist/commands/agent/update.js +1 -1
  15. package/dist/commands/agent/versions.js +1 -1
  16. package/dist/commands/agent/workspaces.js +1 -1
  17. package/dist/commands/chat.js +28 -15
  18. package/dist/commands/config/list.js +2 -2
  19. package/dist/commands/integration/operation/create.js +2 -2
  20. package/dist/commands/integration/operation/list.js +2 -2
  21. package/dist/commands/integration/update.js +1 -1
  22. package/dist/commands/integration/version/get.js +2 -2
  23. package/dist/commands/integration/version/publish.js +2 -2
  24. package/dist/commands/integration/version/test.js +2 -2
  25. package/dist/commands/session/events.js +7 -3
  26. package/dist/commands/workspace/get.js +1 -1
  27. package/dist/commands/workspace/list.js +28 -6
  28. package/dist/commands/workspace/select.js +40 -9
  29. package/dist/components/TaskView.js +2 -2
  30. package/dist/lib/agent-helpers.d.ts +59 -2
  31. package/dist/lib/agent-helpers.js +153 -8
  32. package/dist/lib/alternate-screen.js +2 -0
  33. package/dist/lib/api-client.js +2 -1
  34. package/dist/lib/config.d.ts +3 -0
  35. package/dist/lib/config.js +33 -0
  36. package/dist/lib/session-events.d.ts +1 -1
  37. package/dist/lib/session-events.js +5 -3
  38. package/dist/lib/session-polling.d.ts +8 -0
  39. package/dist/lib/session-polling.js +49 -0
  40. package/dist/lib/spinners.js +4 -1
  41. package/package.json +1 -1
@@ -50,6 +50,8 @@ export function suppressScrollbackClear() {
50
50
  chunk = chunk.replace(CLEAR_TERMINAL, CLEAR_SUBSEQUENT);
51
51
  }
52
52
  }
53
+ if (!originalWrite)
54
+ return false;
53
55
  return originalWrite.apply(this, [chunk, ...args]);
54
56
  };
55
57
  process.stdout.write = patched;
@@ -3,7 +3,7 @@
3
3
  import axios from 'axios';
4
4
  import { getAuthToken, clearAuthToken } from './auth.js';
5
5
  import { retry, debug, GuildCLIError, ErrorCodes } from './errors.js';
6
- import { getGuildcoreUrl } from './config.js';
6
+ import { getUserAgent, getGuildcoreUrl } from './config.js';
7
7
  import { getIapHeaders } from './iap.js';
8
8
  /**
9
9
  * HTTP client for Guild API
@@ -24,6 +24,7 @@ export class GuildAPIClient {
24
24
  headers: {
25
25
  'Content-Type': 'application/json',
26
26
  Accept: 'application/json',
27
+ 'User-Agent': getUserAgent(),
27
28
  },
28
29
  });
29
30
  debug(`API Client initialized: ${this.baseUrl}, retry: ${this.enableRetry}, max retries: ${this.maxRetries}`);
@@ -1,3 +1,6 @@
1
+ export declare function getCliVersion(): string;
2
+ export declare function isDevBuild(): boolean;
3
+ export declare function getUserAgent(): string;
1
4
  /**
2
5
  * IAP (Identity-Aware Proxy) configuration for internal *.guildai.dev hosts.
3
6
  * Users must run `gcloud auth login` with an authorized Google account to access.
@@ -1,5 +1,38 @@
1
1
  // Copyright 2026 Guild.ai
2
2
  // SPDX-License-Identifier: Apache-2.0
3
+ import { readFileSync } from 'fs';
4
+ import path from 'path';
5
+ const FALLBACK_VERSION = 'unknown';
6
+ let cachedVersion;
7
+ export function getCliVersion() {
8
+ if (!cachedVersion) {
9
+ try {
10
+ const pkg = JSON.parse(readFileSync(path.join(__dirname, '../package.json'), 'utf-8'));
11
+ cachedVersion = pkg.version ?? FALLBACK_VERSION;
12
+ }
13
+ catch {
14
+ cachedVersion = FALLBACK_VERSION;
15
+ }
16
+ }
17
+ return cachedVersion;
18
+ }
19
+ export function isDevBuild() {
20
+ try {
21
+ return !__dirname.includes('node_modules');
22
+ }
23
+ catch {
24
+ return false;
25
+ }
26
+ }
27
+ export function getUserAgent() {
28
+ try {
29
+ const base = `GuildCLI/${getCliVersion()}`;
30
+ return isDevBuild() ? `${base}/dev` : base;
31
+ }
32
+ catch {
33
+ return 'GuildCLI';
34
+ }
35
+ }
3
36
  /**
4
37
  * IAP configuration for shared.guildai.dev
5
38
  */
@@ -54,7 +54,7 @@ export declare function getAgentName(agent: AgentRef | null | undefined): string
54
54
  * Check if a task's agent matches a target agent identifier.
55
55
  *
56
56
  * Target format: "@scope/owner~name" (e.g. "@guildai/guildai~agent-builder") or simple name ("assistant")
57
- * AgentRef format: { name: "agent-builder", full_name: "guildai/agent-builder", ... }
57
+ * AgentRef format: { name: "agent-builder", full_name: "guildai~agent-builder", ... }
58
58
  */
59
59
  export declare function matchesAgent(taskAgent: AgentRef | null | undefined, targetAgent: string): boolean;
60
60
  /** Get display name for a task - agent name or tool name */
@@ -41,7 +41,7 @@ export function getAgentName(agent) {
41
41
  * Check if a task's agent matches a target agent identifier.
42
42
  *
43
43
  * Target format: "@scope/owner~name" (e.g. "@guildai/guildai~agent-builder") or simple name ("assistant")
44
- * AgentRef format: { name: "agent-builder", full_name: "guildai/agent-builder", ... }
44
+ * AgentRef format: { name: "agent-builder", full_name: "guildai~agent-builder", ... }
45
45
  */
46
46
  export function matchesAgent(taskAgent, targetAgent) {
47
47
  if (!taskAgent)
@@ -49,9 +49,11 @@ export function matchesAgent(taskAgent, targetAgent) {
49
49
  // Direct name match for simple identifiers like "assistant"
50
50
  if (taskAgent.name === targetAgent)
51
51
  return true;
52
- // Normalize "@scope/owner~name" -> "owner/name" for full_name comparison
52
+ // Normalize target to match full_name format:
53
+ // 1. Strip npm scope prefix: "@scope/owner~name" -> "owner~name"
54
+ // 2. Convert slash separator to tilde: "owner/name" -> "owner~name"
53
55
  if (taskAgent.full_name) {
54
- const normalized = targetAgent.replace(/^@[^/]+\//, '').replace('~', '/');
56
+ const normalized = targetAgent.replace(/^@[^/]+\//, '').replace('/', '~');
55
57
  if (taskAgent.full_name === normalized)
56
58
  return true;
57
59
  }
@@ -16,4 +16,12 @@ export interface PollResult {
16
16
  * 3. runtime_error from agent tasks — fail fast
17
17
  */
18
18
  export declare function pollForResponse(client: GuildAPIClient, sessionId: string, afterEventId: string | undefined, maxWaitTime?: number): Promise<PollResult>;
19
+ /**
20
+ * Poll for agent response while streaming matching events to stdout as JSONL.
21
+ *
22
+ * Same completion logic as pollForResponse(), but writes each event that
23
+ * passes the filter to stdout so callers get intermediate output (console.log,
24
+ * progress, etc.) in JSON/JSONL automation modes.
25
+ */
26
+ export declare function pollForResponseWithEvents(client: GuildAPIClient, sessionId: string, eventFilter: Set<string>, afterEventId: string | undefined, maxWaitTime?: number): Promise<PollResult>;
19
27
  //# sourceMappingURL=session-polling.d.ts.map
@@ -1,6 +1,7 @@
1
1
  // Copyright 2026 Guild.ai
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
  import { debug, isDebugMode } from './errors.js';
4
+ import { shouldShowEvent } from './event-filter.js';
4
5
  import { fetchEvents } from './session-events-fetch.js';
5
6
  /**
6
7
  * Poll for agent response using from_id cursor.
@@ -50,4 +51,52 @@ export async function pollForResponse(client, sessionId, afterEventId, maxWaitTi
50
51
  }
51
52
  return { response: null, lastEventId: fromId };
52
53
  }
54
+ /**
55
+ * Poll for agent response while streaming matching events to stdout as JSONL.
56
+ *
57
+ * Same completion logic as pollForResponse(), but writes each event that
58
+ * passes the filter to stdout so callers get intermediate output (console.log,
59
+ * progress, etc.) in JSON/JSONL automation modes.
60
+ */
61
+ export async function pollForResponseWithEvents(client, sessionId, eventFilter, afterEventId, maxWaitTime = 60000) {
62
+ const startTime = Date.now();
63
+ let fromId = afterEventId;
64
+ while (Date.now() - startTime < maxWaitTime) {
65
+ const events = await fetchEvents(client, sessionId, { fromId });
66
+ let lastAgentRuntimeDone = null;
67
+ for (const event of events) {
68
+ debug(`pollForResponseWithEvents event: ${event.type}`);
69
+ // Stream matching events to stdout as JSONL
70
+ if (shouldShowEvent(event.type, eventFilter)) {
71
+ process.stdout.write(JSON.stringify(event) + '\n');
72
+ }
73
+ if (event.type === 'agent_notification_message') {
74
+ return { response: event.content.data, lastEventId: event.id };
75
+ }
76
+ if (event.type === 'runtime_done' &&
77
+ event.content !== undefined &&
78
+ event.task &&
79
+ 'agent' in event.task) {
80
+ lastAgentRuntimeDone = JSON.stringify(event.content);
81
+ }
82
+ if (event.type === 'runtime_error' && event.task && 'agent' in event.task) {
83
+ return {
84
+ response: JSON.stringify({ error: event.content }),
85
+ lastEventId: event.id,
86
+ };
87
+ }
88
+ if (event.type === 'agent_console' && isDebugMode()) {
89
+ process.stderr.write(`[console.${event.level}] ${event.content}\n`);
90
+ }
91
+ }
92
+ if (events.length > 0) {
93
+ fromId = events[events.length - 1].id;
94
+ }
95
+ if (lastAgentRuntimeDone !== null) {
96
+ return { response: lastAgentRuntimeDone, lastEventId: fromId };
97
+ }
98
+ await new Promise((resolve) => setTimeout(resolve, 2000));
99
+ }
100
+ return { response: null, lastEventId: fromId };
101
+ }
53
102
  //# sourceMappingURL=session-polling.js.map
@@ -751,7 +751,10 @@ export function getSpinnerThemes() {
751
751
  * @deprecated Use createSpinner() instead
752
752
  */
753
753
  export function getActiveTheme() {
754
- return getSpinnerThemes().get('classic');
754
+ const theme = getSpinnerThemes().get('classic');
755
+ if (!theme)
756
+ throw new Error('Missing classic spinner theme');
757
+ return theme;
755
758
  }
756
759
  /**
757
760
  * @deprecated Use createSpinner() instead
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@guildai/cli",
3
- "version": "0.7.0",
3
+ "version": "0.7.1",
4
4
  "description": "Guild.ai CLI - Build, test, and deploy AI agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",