@guildai/cli 0.10.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auth-CRMO5O3N.js +29 -0
- package/dist/auth-CRMO5O3N.js.map +7 -0
- package/dist/chat-5VX2WJH2.js +303 -0
- package/dist/chat-5VX2WJH2.js.map +7 -0
- package/dist/chat-SIKDYZQK.js +31 -0
- package/dist/chat-SIKDYZQK.js.map +7 -0
- package/dist/chunk-56YCMGL3.js +522 -0
- package/dist/chunk-56YCMGL3.js.map +7 -0
- package/dist/chunk-6EX6E7WP.js +7042 -0
- package/dist/chunk-6EX6E7WP.js.map +7 -0
- package/dist/chunk-B7VAF5UG.js +532 -0
- package/dist/chunk-B7VAF5UG.js.map +7 -0
- package/dist/chunk-DOIYVBNY.js +3057 -0
- package/dist/chunk-DOIYVBNY.js.map +7 -0
- package/dist/chunk-ENKEEJ45.js +17 -0
- package/dist/chunk-ENKEEJ45.js.map +7 -0
- package/dist/chunk-IBRKVGMZ.js +97041 -0
- package/dist/chunk-IBRKVGMZ.js.map +7 -0
- package/dist/chunk-LFMQJOKC.js +19778 -0
- package/dist/chunk-LFMQJOKC.js.map +7 -0
- package/dist/chunk-M347HP6M.js +22896 -0
- package/dist/chunk-M347HP6M.js.map +7 -0
- package/dist/chunk-OYQ476FQ.js +44 -0
- package/dist/chunk-OYQ476FQ.js.map +7 -0
- package/dist/chunk-PNCUR4OB.js +257 -0
- package/dist/chunk-PNCUR4OB.js.map +7 -0
- package/dist/chunk-RIG2HZWM.js +317 -0
- package/dist/chunk-RIG2HZWM.js.map +7 -0
- package/dist/chunk-SPZPZXUN.js +826 -0
- package/dist/chunk-SPZPZXUN.js.map +7 -0
- package/dist/chunk-VVSOU6ON.js +53 -0
- package/dist/chunk-VVSOU6ON.js.map +7 -0
- package/dist/chunk-X3ADGWOF.js +3643 -0
- package/dist/chunk-X3ADGWOF.js.map +7 -0
- package/dist/commands/agent/logs.d.ts +3 -0
- package/dist/commands/setup.d.ts +16 -0
- package/dist/commands/skill/create.d.ts +3 -0
- package/dist/commands/skill/get.d.ts +3 -0
- package/dist/commands/skill/list.d.ts +3 -0
- package/dist/commands/skill/update.d.ts +3 -0
- package/dist/commands/skill/version/create.d.ts +3 -0
- package/dist/commands/skill/version/get.d.ts +3 -0
- package/dist/commands/skill/version/list.d.ts +3 -0
- package/dist/devtools-AO7YSDOD.js +67 -0
- package/dist/devtools-AO7YSDOD.js.map +7 -0
- package/dist/dist-4CBK6X5H.js +1566 -0
- package/dist/dist-4CBK6X5H.js.map +7 -0
- package/dist/esm-FRAVZP4J.js +13 -0
- package/dist/esm-FRAVZP4J.js.map +7 -0
- package/dist/execa-XQMWSABC.js +35 -0
- package/dist/execa-XQMWSABC.js.map +7 -0
- package/dist/index.js +8231 -253
- package/dist/index.js.map +7 -0
- package/dist/lib/api-types.d.ts +44 -0
- package/dist/lib/auth.d.ts +1 -1
- package/dist/lib/config.d.ts +9 -0
- package/dist/lib/errors.d.ts +1 -1
- package/dist/lib/output-mode.d.ts +9 -2
- package/dist/lib/output.d.ts +17 -1
- package/dist/lib/session-events.d.ts +14 -3
- package/dist/lib/session-polling.d.ts +24 -1
- package/dist/lib/session-resume.d.ts +15 -1
- package/dist/lib/stdin.d.ts +5 -1
- package/dist/lib/websocket-client.d.ts +46 -0
- package/dist/open-RF4X5MOP.js +13 -0
- package/dist/open-RF4X5MOP.js.map +7 -0
- package/dist/server-JYVH64FD.js +27659 -0
- package/dist/server-JYVH64FD.js.map +7 -0
- package/dist/test-SNIYRJ32.js +692 -0
- package/dist/test-SNIYRJ32.js.map +7 -0
- package/docs/skills/codex-agent-dev.md +2 -2
- package/package.json +8 -12
- package/dist/commands/agent/chat.js +0 -278
- package/dist/commands/agent/clone.js +0 -116
- package/dist/commands/agent/code.js +0 -87
- package/dist/commands/agent/fork.js +0 -218
- package/dist/commands/agent/get.js +0 -37
- package/dist/commands/agent/grep.js +0 -107
- package/dist/commands/agent/init.js +0 -390
- package/dist/commands/agent/list.js +0 -110
- package/dist/commands/agent/owners.js +0 -74
- package/dist/commands/agent/publish.js +0 -91
- package/dist/commands/agent/pull.js +0 -198
- package/dist/commands/agent/revalidate.js +0 -56
- package/dist/commands/agent/save.js +0 -346
- package/dist/commands/agent/search.js +0 -61
- package/dist/commands/agent/tags/add.js +0 -73
- package/dist/commands/agent/tags/list.js +0 -43
- package/dist/commands/agent/tags/remove.js +0 -84
- package/dist/commands/agent/tags/set.js +0 -71
- package/dist/commands/agent/test.js +0 -486
- package/dist/commands/agent/unpublish.js +0 -64
- package/dist/commands/agent/update.js +0 -110
- package/dist/commands/agent/versions.js +0 -55
- package/dist/commands/agent/workspaces.js +0 -54
- package/dist/commands/auth/login.js +0 -33
- package/dist/commands/auth/logout.js +0 -24
- package/dist/commands/auth/status.js +0 -38
- package/dist/commands/auth/token.js +0 -19
- package/dist/commands/chat.js +0 -1345
- package/dist/commands/config/get.js +0 -64
- package/dist/commands/config/list.js +0 -47
- package/dist/commands/config/path.js +0 -38
- package/dist/commands/config/set.js +0 -132
- package/dist/commands/credentials/endpoint-list.js +0 -88
- package/dist/commands/credentials/list.js +0 -50
- package/dist/commands/credentials/policy-create.js +0 -66
- package/dist/commands/credentials/policy-delete.js +0 -33
- package/dist/commands/credentials/policy-list.js +0 -45
- package/dist/commands/credentials/policy-update.js +0 -66
- package/dist/commands/doctor.js +0 -233
- package/dist/commands/integration/connect.js +0 -76
- package/dist/commands/integration/create.js +0 -298
- package/dist/commands/integration/get.js +0 -95
- package/dist/commands/integration/list.js +0 -62
- package/dist/commands/integration/operation/create.js +0 -164
- package/dist/commands/integration/operation/list.js +0 -92
- package/dist/commands/integration/update.js +0 -139
- package/dist/commands/integration/version/build.js +0 -86
- package/dist/commands/integration/version/create.js +0 -45
- package/dist/commands/integration/version/get.js +0 -72
- package/dist/commands/integration/version/list.js +0 -45
- package/dist/commands/integration/version/publish.js +0 -79
- package/dist/commands/integration/version/test.js +0 -104
- package/dist/commands/job/get-step.js +0 -40
- package/dist/commands/job/get.js +0 -44
- package/dist/commands/mcp.js +0 -34
- package/dist/commands/session/create.js +0 -59
- package/dist/commands/session/events.js +0 -56
- package/dist/commands/session/get.js +0 -33
- package/dist/commands/session/interrupt.js +0 -33
- package/dist/commands/session/list.js +0 -59
- package/dist/commands/session/send.js +0 -54
- package/dist/commands/session/tasks.js +0 -45
- package/dist/commands/setup.js +0 -230
- package/dist/commands/trigger/activate.js +0 -41
- package/dist/commands/trigger/create.js +0 -197
- package/dist/commands/trigger/deactivate.js +0 -41
- package/dist/commands/trigger/get.js +0 -33
- package/dist/commands/trigger/list.js +0 -57
- package/dist/commands/trigger/sessions.js +0 -48
- package/dist/commands/trigger/update.js +0 -128
- package/dist/commands/version.js +0 -24
- package/dist/commands/workspace/agent/add.js +0 -114
- package/dist/commands/workspace/agent/list.js +0 -78
- package/dist/commands/workspace/agent/remove.js +0 -78
- package/dist/commands/workspace/clear.js +0 -45
- package/dist/commands/workspace/context/edit.js +0 -107
- package/dist/commands/workspace/context/get.js +0 -47
- package/dist/commands/workspace/context/list.js +0 -51
- package/dist/commands/workspace/context/publish.js +0 -42
- package/dist/commands/workspace/create.js +0 -51
- package/dist/commands/workspace/current.js +0 -63
- package/dist/commands/workspace/get.js +0 -39
- package/dist/commands/workspace/list.js +0 -70
- package/dist/commands/workspace/select.js +0 -184
- package/dist/components/AgentInstallPrompt.js +0 -97
- package/dist/components/SplashAnimation.js +0 -321
- package/dist/components/TaskView.js +0 -268
- package/dist/lib/agent-helpers.js +0 -306
- package/dist/lib/alternate-screen.js +0 -59
- package/dist/lib/api-client.js +0 -154
- package/dist/lib/api-types.js +0 -10
- package/dist/lib/auth.js +0 -284
- package/dist/lib/braille-canvas.js +0 -321
- package/dist/lib/colors.js +0 -46
- package/dist/lib/config-cache.js +0 -45
- package/dist/lib/config.js +0 -153
- package/dist/lib/did-you-mean.js +0 -144
- package/dist/lib/errors.js +0 -375
- package/dist/lib/event-filter.js +0 -91
- package/dist/lib/generated-types.js +0 -56
- package/dist/lib/git.js +0 -176
- package/dist/lib/gk.js +0 -91
- package/dist/lib/guild-config.js +0 -178
- package/dist/lib/iap.js +0 -117
- package/dist/lib/integration-helpers.js +0 -38
- package/dist/lib/loading-messages.js +0 -72
- package/dist/lib/logo.js +0 -141
- package/dist/lib/lottie-serverside.js +0 -181
- package/dist/lib/markdown.js +0 -38
- package/dist/lib/npmrc.js +0 -59
- package/dist/lib/output-mode.js +0 -33
- package/dist/lib/output.js +0 -591
- package/dist/lib/owner-helpers.js +0 -112
- package/dist/lib/polling.js +0 -76
- package/dist/lib/progress.js +0 -324
- package/dist/lib/session-events-fetch.js +0 -25
- package/dist/lib/session-events.js +0 -112
- package/dist/lib/session-polling.js +0 -160
- package/dist/lib/session-resume.js +0 -96
- package/dist/lib/spinners.js +0 -770
- package/dist/lib/splash.js +0 -41
- package/dist/lib/stdin.js +0 -84
- package/dist/lib/svg-to-braille.js +0 -76
- package/dist/lib/table.js +0 -59
- package/dist/lib/update-check.js +0 -65
- package/dist/lib/validate-input-schema.js +0 -208
- package/dist/lib/version-helpers.js +0 -121
- package/dist/lib/workspace-helpers.js +0 -49
- package/dist/mcp/resources.js +0 -67
- package/dist/mcp/server.js +0 -64
- package/dist/mcp/tools.js +0 -753
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/commands/agent/test.ts", "../src/lib/validate-input-schema.ts"],
|
|
4
|
+
"sourcesContent": ["// Copyright 2026 Guild.ai\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Command, Option } from 'commander';\nimport { render } from 'ink';\nimport React from 'react';\nimport { access } from 'fs/promises';\nimport path from 'path';\nimport open from 'open';\nimport { hyperlink } from '../../lib/colors.js';\nimport { GuildAPIClient } from '../../lib/api-client.js';\nimport { handleAxiosError, ErrorCodes } from '../../lib/errors.js';\nimport { format } from '../../lib/progress.js';\nimport { parseEventFilter } from '../../lib/event-filter.js';\nimport { isQuietMode, getOutputMode } from '../../lib/output-mode.js';\nimport { Session } from '../../lib/session-events.js';\nimport {\n pollForResponse,\n pollForResponseWithEvents,\n} from '../../lib/session-polling.js';\nimport {\n readStdinAsJSON,\n readStdinAsText,\n ensureInteractiveStdin,\n} from '../../lib/stdin.js';\nimport {\n loadLocalConfig,\n getWorkspaceId,\n getWorkspaceSourceLabel,\n} from '../../lib/guild-config.js';\nimport { GitError, formatGitError } from '../../lib/git.js';\nimport {\n readAgentFiles,\n buildEphemeralVersion,\n buildBundledVersion,\n BundleNotFoundError,\n BuildTimeoutError,\n BuildFailedError,\n} from '../../lib/agent-helpers.js';\nimport type { AgentVersion } from '../../lib/api-types.js';\nimport { validateInputSchema } from '../../lib/validate-input-schema.js';\nimport { fetchSession, fetchSessionEvents } from '../../lib/session-resume.js';\nimport { ChatApp, ensureAuthenticated } from '../chat.js';\nimport { suppressScrollbackClear } from '../../lib/alternate-screen.js';\n\nimport { getCliVersion } from '../../lib/config.js';\n\nconst cliVersion = getCliVersion();\n\nexport function createAgentTestCommand(): Command {\n const cmd = new Command('test');\n\n cmd\n .description('Test agent in interactive REPL session')\n .option(\n '--workspace <identifier>',\n 'Workspace ID or full name (e.g., owner/workspace-name)'\n )\n .option('--agent-version <id>', 'Test a specific version (UUID or version number)')\n .option('--resume <session-id>', 'Resume an existing test session')\n .option('--open', 'Open session in web dashboard')\n .option(\n '--events <types>',\n 'Event types to stream (default: user). Shorthands: none, user, system, all, or comma-separated type names'\n )\n .option('--bundle <file>', 'Path to a pre-built gzip+base64 bundle file')\n .option('--no-cache', 'Skip ephemeral build cache (force a fresh build)')\n // Accept --mode so `guild agent test --mode json` works when re-parsed.\n // The actual value is read from process.argv by getOutputMode().\n .addOption(new Option('--mode <format>').hideHelp())\n .action(\n async (options: {\n workspace?: string;\n agentVersion?: string;\n bundle?: string;\n resume?: string;\n open?: boolean;\n events?: string;\n cache?: boolean;\n }) => {\n const cwd = process.cwd();\n\n // Parse --events filter once, before any branching\n const eventFilter = options.events\n ? parseEventFilter(options.events)\n : undefined;\n\n try {\n // Handle --resume: skip build, fetch existing session, hand off to ChatApp\n if (options.resume) {\n await ensureAuthenticated();\n const client = new GuildAPIClient();\n const resumeSession = await fetchSession(client, options.resume);\n const resumeEvents = await fetchSessionEvents(client, options.resume);\n const resumeCommand = 'guild agent test';\n\n const isInteractive = getOutputMode() === 'interactive' && !isQuietMode();\n\n if (isInteractive) {\n suppressScrollbackClear();\n }\n\n const { waitUntilExit } = render(\n React.createElement(ChatApp, {\n initialPrompt: '',\n version: cliVersion,\n showSplash: false,\n resumeSession,\n resumeEvents,\n resumeCommand,\n eventFilter,\n }),\n { exitOnCtrlC: false }\n );\n await waitUntilExit();\n return;\n }\n\n // Load local config (guild.json)\n const guildConfig = await loadLocalConfig(cwd);\n\n if (!guildConfig) {\n console.error('Error: Not in an agent directory');\n console.error('');\n console.error('guild.json not found in current directory.');\n console.error('');\n console.error('Initialize an agent directory:');\n console.error(' guild agent init --name my-agent');\n console.error('');\n console.error('Or clone an existing agent:');\n console.error(' guild agent clone <agent-id>');\n process.exit(1);\n }\n\n // If using JSON/JSONL input, read and validate it early (before auth/session creation)\n // This provides better UX - fail fast on bad input without needing auth\n const outputMode = getOutputMode();\n let inputData: unknown | undefined;\n let jsonlInputs: unknown[] | undefined;\n if (outputMode === 'json') {\n try {\n inputData = await readStdinAsJSON();\n } catch (error: unknown) {\n const err = error as Error;\n console.error(`Error: ${err.message}`);\n console.error('');\n console.error('Example usage:');\n console.error(\n ' echo \\'{\"prompt\": \"test\"}\\' | guild agent test --mode json'\n );\n console.error(' guild agent test --mode json < input.json');\n process.exit(1);\n }\n } else if (outputMode === 'jsonl') {\n try {\n const stdinContent = await readStdinAsText();\n jsonlInputs = [];\n const lines = stdinContent.split('\\n');\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i].trim();\n if (!line) continue;\n try {\n jsonlInputs.push(JSON.parse(line));\n } catch {\n console.error(`Error: Invalid JSON on line ${i + 1}`);\n console.error('');\n console.error('Each line must be valid JSON.');\n console.error(' cat inputs.jsonl | guild agent test --mode jsonl');\n process.exit(1);\n }\n }\n if (jsonlInputs.length === 0) {\n console.error('Error: No JSON input provided');\n console.error('');\n console.error('Example usage:');\n console.error(' cat inputs.jsonl | guild agent test --mode jsonl');\n process.exit(1);\n }\n } catch (error: unknown) {\n const err = error as Error;\n console.error(`Error: ${err.message}`);\n process.exit(1);\n }\n }\n\n // Validate input against agent's schema locally (before build)\n // Skip when --agent-version is set since local source may differ from that version\n const inputsToValidate =\n inputData !== undefined ? [inputData] : (jsonlInputs ?? []);\n if (inputsToValidate.length > 0 && !options.agentVersion) {\n const validationResult = await validateInputSchema(cwd, inputsToValidate);\n if (!validationResult.valid) {\n console.error('Input validation failed:');\n for (const err of validationResult.errors) {\n const pathStr = err.path?.length ? ` (at ${err.path.join('.')})` : '';\n console.error(` - ${err.message}${pathStr}`);\n }\n process.exit(1);\n }\n if ('skipped' in validationResult && validationResult.skipped) {\n format.warn(`Skipping local validation: ${validationResult.reason}`);\n }\n }\n\n // If using bundle, verify the file exists early (before auth/session creation)\n // so we fail fast without needing auth if the path is wrong.\n if (options.bundle) {\n try {\n await access(options.bundle);\n } catch {\n console.error(`Error: Bundle file not found: ${options.bundle}`);\n console.error('');\n console.error('Ensure the bundle file exists and the path is correct:');\n console.error(' npm run build');\n console.error(' guild agent test --bundle agent.js.gz');\n process.exit(1);\n }\n }\n\n // Determine workspace (priority: flag > local config > global config)\n let workspaceId = options.workspace;\n let workspaceSourceLabel: string | undefined;\n if (!workspaceId) {\n const resolved = await getWorkspaceId(cwd);\n workspaceId = resolved?.workspaceId;\n workspaceSourceLabel = resolved\n ? getWorkspaceSourceLabel(resolved.source)\n : undefined;\n\n if (!workspaceId) {\n console.error('Error: No default workspace configured');\n console.error('');\n console.error('Set a default workspace interactively:');\n console.error(' guild workspace select');\n console.error('');\n console.error('Or specify a workspace for this test:');\n console.error(' guild agent test --workspace <workspace-id>');\n console.error('');\n console.error('List available workspaces:');\n console.error(' guild workspace list');\n process.exit(1);\n }\n }\n\n // Validate auth before any API calls or UI rendering\n await ensureAuthenticated();\n\n // Resolve version for testing\n const client = new GuildAPIClient();\n\n let version: AgentVersion;\n let ephemeralCached = false;\n try {\n if (options.agentVersion) {\n // Explicit version: look it up by ID or version number\n const existingVersions = (await client.get(\n `/agents/${guildConfig.agent_id}/versions`\n )) as { items: AgentVersion[] };\n const match = existingVersions.items.find(\n (v) =>\n v.id === options.agentVersion ||\n v.version_number === options.agentVersion\n );\n\n if (!match) {\n console.error(`Error: Version not found: ${options.agentVersion}`);\n console.error('');\n console.error('List available versions:');\n console.error(` guild agent versions ${guildConfig.agent_id}`);\n process.exit(1);\n }\n\n version = match;\n } else if (options.bundle) {\n // Pre-built bundle: skip server-side compilation entirely.\n const result = await buildBundledVersion(\n client,\n guildConfig.agent_id,\n options.bundle,\n cwd,\n '[Test] Pre-built bundle'\n );\n version = result.version;\n } else {\n // Default: build ephemeral version from working directory,\n // reusing the last build if files haven't changed.\n const agentFiles = await readAgentFiles(cwd);\n const noCache = options.cache === false;\n const result = await buildEphemeralVersion(\n client,\n guildConfig.agent_id,\n agentFiles,\n cwd,\n '[Test] Ephemeral development version',\n { noCache }\n );\n version = result.version;\n ephemeralCached = result.cached;\n }\n } catch (error: unknown) {\n if (error instanceof BundleNotFoundError) {\n console.error(`Error: ${error.message}`);\n console.error('');\n console.error('Ensure the bundle file exists and the path is correct:');\n console.error(' npm run build');\n console.error(' guild agent test --bundle agent.js.gz');\n process.exit(1);\n }\n\n if (error instanceof BuildTimeoutError) {\n console.error('Error: Build did not complete');\n console.error('');\n console.error(error.message);\n console.error('');\n console.error('Check build status:');\n console.error(' guild agent versions');\n process.exit(1);\n }\n\n if (error instanceof BuildFailedError) {\n console.error(`Error: ${error.message}`);\n process.exit(1);\n }\n\n if (\n error instanceof Error &&\n error.message.startsWith('Missing required')\n ) {\n console.error('Error: Could not read agent files');\n console.error('');\n console.error(error.message);\n console.error('');\n console.error('Ensure you are in an agent directory with:');\n console.error(' - agent.ts (required)');\n console.error(' - package.json (required)');\n process.exit(1);\n }\n\n const formattedError = handleAxiosError(error);\n\n if (formattedError.code === ErrorCodes.NOT_FOUND) {\n console.error(`Error: Agent not found: ${guildConfig.agent_id}`);\n console.error('');\n console.error('This agent may have been deleted from the backend.');\n console.error('');\n console.error('Verify the agent exists:');\n console.error(` guild agent get ${guildConfig.agent_id}`);\n console.error('');\n console.error('Or initialize a new agent:');\n console.error(' guild agent init --name my-agent');\n process.exit(1);\n }\n\n throw error;\n }\n\n // Create test session\n let session: Session;\n try {\n session = (await client.post(`/workspaces/${workspaceId}/sessions`, {\n session_type: 'agent_test',\n agent_version_id: version.id,\n })) as Session;\n } catch (error: unknown) {\n const formattedError = handleAxiosError(error);\n\n if (formattedError.code === ErrorCodes.NOT_FOUND) {\n console.error(`Error: Workspace not found: ${workspaceId}`);\n console.error('');\n console.error('Set a different default workspace:');\n console.error(' guild workspace select');\n console.error('');\n console.error('Or list available workspaces:');\n console.error(' guild workspace list');\n process.exit(1);\n }\n\n throw error;\n }\n\n const quiet = isQuietMode();\n\n if (!quiet) {\n console.log(`\u2713 Agent: ${guildConfig.name} (${guildConfig.agent_id})`);\n const versionDisplay = options.agentVersion\n ? options.agentVersion\n : options.bundle\n ? `bundle (${path.basename(options.bundle)})`\n : ephemeralCached\n ? 'ephemeral (cached, no changes)'\n : 'ephemeral (working directory)';\n console.log(`\u2713 Version: ${versionDisplay}`);\n const workspaceDisplay = workspaceSourceLabel\n ? `${workspaceId} (from ${workspaceSourceLabel})`\n : workspaceId;\n console.log(`\u2713 Workspace: ${workspaceDisplay}`);\n const sessionLink = session.session_url\n ? hyperlink(session.id, session.session_url)\n : session.id;\n console.log(`\u2713 Session: ${sessionLink}`);\n console.log('');\n }\n\n if (options.open && session.session_url) {\n await open(session.session_url);\n }\n\n // Branch: JSON input mode vs interactive REPL\n if (outputMode === 'json' && inputData) {\n // JSON input mode: one-shot test\n try {\n // Send JSON as event content (inputData already read earlier)\n await client.post(`/sessions/${session.id}/events`, {\n mode: 'json',\n content: inputData,\n });\n\n // Poll for response (starting from beginning)\n // 3 minutes - allow time for agents that use LLM calls for input parsing\n const { response } = eventFilter\n ? await pollForResponseWithEvents(\n client,\n session.id,\n eventFilter,\n undefined,\n 180000\n )\n : await pollForResponse(client, session.id, undefined, 180000);\n\n if (!response) {\n console.error('Error: No response received from agent within timeout');\n console.error('');\n console.error('The agent did not produce a response in time.');\n console.error('');\n console.error('Possible causes:');\n console.error(\n ' - The agent is still processing (try a longer timeout)'\n );\n console.error(' - The agent encountered an error during execution');\n console.error(\n \" - The input format does not match the agent's input schema\"\n );\n console.error('');\n console.error(\n 'Check agent logs in the web UI or try interactive mode:'\n );\n console.error(' guild agent test');\n process.exit(1);\n }\n\n if (quiet) {\n console.log(response);\n } else {\n console.log(`< ${response}`);\n console.log('');\n }\n\n if (!quiet) {\n console.log('\u2713 Test complete');\n }\n process.exit(0);\n } catch (error: unknown) {\n const formattedErr = handleAxiosError(error);\n console.error(`Error: ${formattedErr.details}`);\n console.error('');\n if (formattedErr.code === ErrorCodes.SERVER_ERROR) {\n console.error(\n 'The server returned an error while processing the event.'\n );\n console.error('');\n console.error('Possible causes:');\n console.error(\n \" - The input format does not match the agent's input schema\"\n );\n console.error(' - The agent runtime encountered an error');\n console.error('');\n console.error('Try testing interactively to see more detail:');\n console.error(' guild agent test');\n } else {\n console.error('Failed to send event to agent session.');\n console.error('');\n console.error('Example usage:');\n console.error(\n ' echo \\'{\"type\":\"text\",\"text\":\"hello\"}\\' | guild agent test --mode json'\n );\n console.error(' guild agent test --mode json < input.json');\n }\n process.exit(1);\n }\n } else if (outputMode === 'jsonl' && jsonlInputs) {\n // JSONL input mode: line-by-line processing (inputs already parsed and validated)\n let processedCount = 0;\n let lastEventId: string | undefined;\n\n for (let inputIndex = 0; inputIndex < jsonlInputs.length; inputIndex++) {\n const jsonInput = jsonlInputs[inputIndex];\n\n if (!quiet) {\n console.error(\n `Processing input ${inputIndex + 1}/${jsonlInputs.length}...`\n );\n }\n\n try {\n // Send message\n await client.post(`/sessions/${session.id}/events`, {\n mode: 'json',\n content: jsonInput,\n });\n\n // Wait for response (looking for events after last seen)\n const result = eventFilter\n ? await pollForResponseWithEvents(\n client,\n session.id,\n eventFilter,\n lastEventId,\n 180000\n )\n : await pollForResponse(client, session.id, lastEventId, 180000);\n lastEventId = result.lastEventId;\n\n if (!result.response) {\n console.error(`Timeout: No response for input ${inputIndex + 1}`);\n continue;\n }\n\n const response = result.response;\n\n // Output response\n if (quiet) {\n console.log(response);\n } else {\n console.log(`< ${response}`);\n console.log('');\n }\n\n processedCount++;\n } catch (error: unknown) {\n const formattedErr = handleAxiosError(error);\n console.error(\n `Error processing input ${inputIndex + 1}: ${formattedErr.details}`\n );\n }\n }\n\n if (!quiet) {\n console.log(`\\n\u2713 Processed ${processedCount} messages`);\n }\n process.exit(0);\n }\n\n // Interactive mode: use shared ChatApp (spinner, progress, prompt)\n ensureInteractiveStdin('guild agent test');\n const resumeCommand = 'guild agent test';\n const isInteractive = getOutputMode() === 'interactive' && !isQuietMode();\n\n if (isInteractive) {\n suppressScrollbackClear();\n }\n\n // Pass the already-created test session as resumeSession so ChatApp\n // skips its own session creation and uses our agent_test session.\n const { waitUntilExit } = render(\n React.createElement(ChatApp, {\n initialPrompt: '',\n version: cliVersion,\n workspaceId,\n versionId: version.id,\n agentName: guildConfig.name,\n showSplash: false,\n resumeSession: session,\n resumeEvents: [],\n resumeCommand,\n eventFilter,\n }),\n { exitOnCtrlC: false }\n );\n await waitUntilExit();\n } catch (error: unknown) {\n if (error instanceof GitError) {\n console.error('Error: Git operation failed');\n console.error('');\n console.error(formatGitError(error));\n process.exit(1);\n }\n\n const formattedError = handleAxiosError(error);\n\n if (\n formattedError.code === ErrorCodes.AUTH_REQUIRED ||\n formattedError.code === ErrorCodes.AUTH_TOKEN_INVALID\n ) {\n format.error('Not authenticated. Run: guild auth login');\n process.exit(1);\n }\n\n console.error(`Error: ${formattedError.details}`);\n console.error('');\n console.error('Failed to start test session. Troubleshooting:');\n console.error(' - Verify the agent exists: guild agent get');\n console.error(' - Check your workspace: guild workspace list');\n if (formattedError.code) {\n console.error(` - Error code: ${formattedError.code}`);\n }\n process.exit(1);\n }\n }\n );\n\n return cmd;\n}\n\n// Thin wrapper for lazy-loading from index.ts (avoids importing React at startup)\nexport async function handleAgentTestAction(\n _options: Record<string, unknown>\n): Promise<void> {\n const cmd = createAgentTestCommand();\n await cmd.parseAsync(process.argv.slice(3), { from: 'user' });\n}\n", "// Copyright 2026 Guild.ai\n// SPDX-License-Identifier: Apache-2.0\n\nimport * as fs from 'fs/promises';\nimport * as path from 'path';\nimport * as os from 'os';\nimport { execFile } from 'child_process';\nimport { promisify } from 'util';\nimport { debug } from './errors.js';\n\nconst execFileAsync = promisify(execFile);\n\ninterface ValidationSuccess {\n valid: true;\n}\n\ninterface ValidationFailure {\n valid: false;\n errors: Array<{ message: string; path?: string[] }>;\n}\n\ninterface ValidationSkipped {\n valid: true;\n skipped: true;\n reason: string;\n}\n\nexport type ValidationResult =\n | ValidationSuccess\n | ValidationFailure\n | ValidationSkipped;\n\nfunction resolveSourceEntryPoint(\n agentDir: string,\n packageJson: Record<string, unknown>\n): string {\n const exports = packageJson.exports as Record<string, string> | undefined;\n if (exports?.['.']) {\n const distPath = exports['.'];\n const sourcePath = distPath\n .replace(/^\\.\\/dist\\//, '')\n .replace(/\\.compiled\\.js$/, '.ts')\n .replace(/\\.js$/, '.ts');\n return path.join(agentDir, sourcePath);\n }\n return path.join(agentDir, 'agent.ts');\n}\n\nasync function fileExists(filePath: string): Promise<boolean> {\n return fs\n .access(filePath)\n .then(() => true)\n .catch(() => false);\n}\n\n/**\n * Extract a single `const <name> = z.<call>(...)` declaration from source,\n * starting at the given regex match. Uses balanced parenthesis matching\n * with string literal awareness.\n */\nfunction extractZodDeclaration(source: string, match: RegExpExecArray): string | null {\n const startIndex = match.index;\n const afterEquals = match.index + match[0].length;\n\n let depth = 0;\n let foundOpen = false;\n let endIndex = afterEquals;\n let inString: string | null = null;\n\n for (let charIndex = afterEquals; charIndex < source.length; charIndex++) {\n const char = source[charIndex];\n\n if (inString) {\n if (char === '\\\\') {\n charIndex++;\n } else if (char === inString) {\n inString = null;\n }\n continue;\n }\n\n if (char === '\"' || char === \"'\" || char === '`') {\n inString = char;\n } else if (char === '(') {\n depth++;\n foundOpen = true;\n } else if (char === ')') {\n depth--;\n if (foundOpen && depth === 0) {\n endIndex = charIndex + 1;\n if (source[endIndex] === ';') endIndex++;\n break;\n }\n }\n }\n\n if (!foundOpen) return null;\n\n return source.substring(startIndex, endIndex);\n}\n\n/**\n * Extract inputSchema and any Zod schema dependencies from agent source.\n * Finds all `const <name> = z.<call>(...)` declarations that appear before\n * inputSchema (which may be referenced inside it), plus inputSchema itself.\n * Returns them in source order so dependencies are defined before use.\n */\nfunction extractInputSchema(source: string): string | null {\n const inputPattern = /const\\s+inputSchema\\s*=\\s*/;\n const inputMatch = inputPattern.exec(source);\n if (!inputMatch) return null;\n\n const inputBlock = extractZodDeclaration(source, inputMatch);\n if (!inputBlock) return null;\n\n const blocks: string[] = [];\n const zodDeclPattern = /const\\s+\\w+\\s*=\\s*z\\s*\\.\\s*/g;\n let declMatch: RegExpExecArray | null;\n\n while ((declMatch = zodDeclPattern.exec(source)) !== null) {\n if (declMatch.index >= inputMatch.index) break;\n const block = extractZodDeclaration(source, declMatch);\n if (block) blocks.push(block);\n }\n\n blocks.push(inputBlock);\n return blocks.join('\\n');\n}\n\nexport async function validateInputSchema(\n agentDir: string,\n inputs: unknown[]\n): Promise<ValidationResult> {\n const nodeModulesPath = path.join(agentDir, 'node_modules');\n if (!(await fileExists(nodeModulesPath))) {\n return {\n valid: true,\n skipped: true,\n reason: 'run npm install for pre-build input validation',\n };\n }\n\n const pkgJsonPath = path.join(agentDir, 'package.json');\n if (!(await fileExists(pkgJsonPath))) {\n return {\n valid: true,\n skipped: true,\n reason: 'no package.json found',\n };\n }\n\n const pkgJson = JSON.parse(await fs.readFile(pkgJsonPath, 'utf-8')) as Record<\n string,\n unknown\n >;\n let entryPoint = resolveSourceEntryPoint(agentDir, pkgJson);\n\n if (!(await fileExists(entryPoint))) {\n const fallback = path.join(agentDir, 'agent.ts');\n if (await fileExists(fallback)) {\n entryPoint = fallback;\n } else {\n return {\n valid: true,\n skipped: true,\n reason: `could not find agent source file (tried ${path.basename(entryPoint)})`,\n };\n }\n }\n\n const agentSource = await fs.readFile(entryPoint, 'utf-8');\n const schemaBlock = extractInputSchema(agentSource);\n\n if (!schemaBlock) {\n return {\n valid: true,\n skipped: true,\n reason: 'could not find inputSchema definition in agent source',\n };\n }\n\n const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'guild-validate-'));\n\n try {\n const extractorSource = [\n `import { z } from \"zod\";`,\n schemaBlock,\n `const inputs = JSON.parse(process.argv[2]);`,\n `const errors = [];`,\n `for (let i = 0; i < inputs.length; i++) {`,\n ` try {`,\n ` inputSchema.parse(inputs[i]);`,\n ` } catch (e) {`,\n ` const issues = e.issues || [{ message: e.message }];`,\n ` errors.push({ index: i, issues: issues.map(iss => ({ message: iss.message, path: iss.path })) });`,\n ` }`,\n `}`,\n `if (errors.length > 0) {`,\n ` console.log(JSON.stringify({ valid: false, errors }));`,\n `} else {`,\n ` console.log(JSON.stringify({ valid: true }));`,\n `}`,\n ].join('\\n');\n\n const extractorPath = path.join(tmpDir, 'validate.mjs');\n await fs.writeFile(extractorPath, extractorSource);\n\n const { build } = await import('esbuild');\n const bundlePath = path.join(tmpDir, 'validate-bundle.mjs');\n\n await build({\n entryPoints: [extractorPath],\n bundle: true,\n format: 'esm',\n target: 'esnext',\n platform: 'node',\n outfile: bundlePath,\n logLevel: 'silent',\n nodePaths: [path.join(agentDir, 'node_modules')],\n });\n\n const inputArg = JSON.stringify(inputs);\n const { stdout } = await execFileAsync('node', [bundlePath, inputArg], {\n cwd: agentDir,\n timeout: 10000,\n });\n\n const result = JSON.parse(stdout.trim()) as\n | { valid: true }\n | {\n valid: false;\n errors: Array<{\n index: number;\n issues: Array<{ message: string; path?: string[] }>;\n }>;\n };\n\n if (result.valid) {\n return { valid: true };\n }\n\n const flatErrors: Array<{ message: string; path?: string[] }> = [];\n for (const entry of result.errors) {\n for (const issue of entry.issues) {\n const prefix = inputs.length > 1 ? `Line ${entry.index + 1}: ` : '';\n flatErrors.push({\n message: `${prefix}${issue.message}`,\n path: issue.path,\n });\n }\n }\n\n return { valid: false, errors: flatErrors };\n } catch (error: unknown) {\n debug('Local input validation failed: %s', error);\n return {\n valid: true,\n skipped: true,\n reason:\n 'local validation encountered an error (server-side validation will still run)',\n };\n } finally {\n await fs.rm(tmpDir, { recursive: true, force: true }).catch(() => {});\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["access", "path", "client", "resumeCommand", "isInteractive", "waitUntilExit", "React", "access", "path"]
|
|
7
|
+
}
|
|
@@ -96,10 +96,10 @@ guild session events <session-id>
|
|
|
96
96
|
guild session tasks <session-id>
|
|
97
97
|
```
|
|
98
98
|
|
|
99
|
-
Use `--
|
|
99
|
+
Use `--events all` to see system events (runtime lifecycle, agent console, LLM start/done):
|
|
100
100
|
|
|
101
101
|
```bash
|
|
102
|
-
guild
|
|
102
|
+
guild agent test --ephemeral --events all
|
|
103
103
|
```
|
|
104
104
|
|
|
105
105
|
## Agent Code Patterns
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@guildai/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "Guild.ai CLI - Build, test, and deploy AI agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -10,22 +10,18 @@
|
|
|
10
10
|
},
|
|
11
11
|
"files": [
|
|
12
12
|
"bin/",
|
|
13
|
-
"dist
|
|
14
|
-
"dist
|
|
15
|
-
"dist/commands/**/*.js",
|
|
16
|
-
"dist/commands/**/*.d.ts",
|
|
17
|
-
"dist/components/**/*.js",
|
|
18
|
-
"dist/components/**/*.d.ts",
|
|
19
|
-
"dist/lib/**/*.js",
|
|
20
|
-
"dist/lib/**/*.d.ts",
|
|
21
|
-
"dist/mcp/**/*.js",
|
|
22
|
-
"dist/mcp/**/*.d.ts",
|
|
13
|
+
"dist/*.js",
|
|
14
|
+
"dist/*.js.map",
|
|
23
15
|
"dist/assets/",
|
|
16
|
+
"dist/**/*.d.ts",
|
|
24
17
|
"docs/"
|
|
25
18
|
],
|
|
26
19
|
"scripts": {
|
|
27
20
|
"prebuild": "python3 scripts/sync-types-from-python.py",
|
|
28
|
-
"build": "
|
|
21
|
+
"build": "npm run build:types && npm run build:bundle && cp -r src/assets dist/",
|
|
22
|
+
"build:types": "tsc --emitDeclarationOnly",
|
|
23
|
+
"build:bundle": "node scripts/bundle.mjs",
|
|
24
|
+
"build:tsc": "tsc && cp -r src/assets dist/",
|
|
29
25
|
"build:link": "npm run build && npm link",
|
|
30
26
|
"build:image": "${CONTAINER_PROVIDER:-docker} build -t guildcode/guild-runtime:latest -f ../guildai/packages/runtime/Dockerfile ../guildai/packages/runtime",
|
|
31
27
|
"dev": "tsx src/index.ts",
|
|
@@ -1,278 +0,0 @@
|
|
|
1
|
-
// Copyright 2026 Guild.ai
|
|
2
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
import { Command } from 'commander';
|
|
4
|
-
import { render } from 'ink';
|
|
5
|
-
import React from 'react';
|
|
6
|
-
import open from 'open';
|
|
7
|
-
import { hyperlink } from '../../lib/colors.js';
|
|
8
|
-
import { getAgentId, readAgentFiles, buildEphemeralVersion, BuildTimeoutError, BuildFailedError, } from '../../lib/agent-helpers.js';
|
|
9
|
-
import { ChatApp, createSession, ensureAuthenticated } from '../chat.js';
|
|
10
|
-
import { readFileSync } from 'fs';
|
|
11
|
-
import path from 'path';
|
|
12
|
-
import { fileURLToPath } from 'url';
|
|
13
|
-
import { GuildAPIClient } from '../../lib/api-client.js';
|
|
14
|
-
import { isQuietMode, getOutputMode } from '../../lib/output-mode.js';
|
|
15
|
-
import { handleAxiosError, ErrorCodes } from '../../lib/errors.js';
|
|
16
|
-
import { format } from '../../lib/progress.js';
|
|
17
|
-
import { suppressScrollbackClear } from '../../lib/alternate-screen.js';
|
|
18
|
-
import * as readline from 'readline';
|
|
19
|
-
import { pollForResponse } from '../../lib/session-polling.js';
|
|
20
|
-
import { readStdinAsJSON, ensureInteractiveStdin } from '../../lib/stdin.js';
|
|
21
|
-
import { fetchSession, fetchSessionEvents } from '../../lib/session-resume.js';
|
|
22
|
-
import { getWorkspaceId, getWorkspaceSourceLabel } from '../../lib/guild-config.js';
|
|
23
|
-
// ESM equivalent of __dirname
|
|
24
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
25
|
-
// Read version from package.json
|
|
26
|
-
const packageJson = JSON.parse(readFileSync(path.join(__dirname, '../../../package.json'), 'utf-8'));
|
|
27
|
-
export function createAgentChatCommand() {
|
|
28
|
-
const cmd = new Command('chat');
|
|
29
|
-
cmd
|
|
30
|
-
.description('Chat with the agent in current directory')
|
|
31
|
-
.argument('[prompt...]', 'Optional initial prompt for the agent')
|
|
32
|
-
.option('--path <dir>', 'Path to agent directory (defaults to current directory)')
|
|
33
|
-
.option('--workspace <identifier>', 'Workspace ID or full name (e.g., owner~workspace-name)')
|
|
34
|
-
.option('--mode <format>', 'Input mode: json (one-shot) or jsonl (line-by-line)')
|
|
35
|
-
.option('--agent-version <id>', 'Chat with a specific version (UUID or version number)')
|
|
36
|
-
.option('--no-splash', 'Skip the splash screen animation')
|
|
37
|
-
.option('--resume <session-id>', 'Resume an existing session')
|
|
38
|
-
.option('--open', 'Open session in web dashboard')
|
|
39
|
-
.option('--no-cache', 'Skip ephemeral build cache (force a fresh build)')
|
|
40
|
-
.addHelpText('after', '\nTo chat with a published agent by name: guild chat --agent owner~agent-name')
|
|
41
|
-
.action(async (promptArgs, options) => {
|
|
42
|
-
try {
|
|
43
|
-
// Get agent ID from guild.json in the specified path
|
|
44
|
-
const agentPath = options.path || '.';
|
|
45
|
-
const { agentId, config } = await getAgentId(undefined, agentPath);
|
|
46
|
-
const initialPrompt = promptArgs.length > 0 ? promptArgs.join(' ') : 'Hello';
|
|
47
|
-
// If using JSON input, read it early (before auth) for fast failure on bad input
|
|
48
|
-
let inputData;
|
|
49
|
-
if (options.mode === 'json') {
|
|
50
|
-
try {
|
|
51
|
-
inputData = await readStdinAsJSON();
|
|
52
|
-
}
|
|
53
|
-
catch (error) {
|
|
54
|
-
const err = error;
|
|
55
|
-
console.error(`Error: ${err.message}`);
|
|
56
|
-
console.error('');
|
|
57
|
-
console.error('Example usage:');
|
|
58
|
-
console.error(' echo \'{"prompt": "test"}\' | guild agent chat --mode json');
|
|
59
|
-
console.error(' guild agent chat --mode json < input.json');
|
|
60
|
-
process.exit(1);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
// Check authentication (uses shared function from chat.tsx)
|
|
64
|
-
await ensureAuthenticated();
|
|
65
|
-
const client = new GuildAPIClient();
|
|
66
|
-
const quiet = isQuietMode();
|
|
67
|
-
const resolvedPath = path.resolve(agentPath);
|
|
68
|
-
// Resolve the version to chat with.
|
|
69
|
-
// Default: create ephemeral version from working directory.
|
|
70
|
-
// --version: use a specific existing version.
|
|
71
|
-
let version;
|
|
72
|
-
let ephemeralCached = false;
|
|
73
|
-
if (options.agentVersion) {
|
|
74
|
-
// Explicit version: look it up by ID or version number
|
|
75
|
-
const existingVersions = (await client.get(`/agents/${agentId}/versions`));
|
|
76
|
-
const match = existingVersions.items.find((v) => v.id === options.agentVersion ||
|
|
77
|
-
v.version_number === options.agentVersion);
|
|
78
|
-
if (!match) {
|
|
79
|
-
console.error(`Error: Version not found: ${options.agentVersion}`);
|
|
80
|
-
console.error('');
|
|
81
|
-
console.error('List available versions:');
|
|
82
|
-
console.error(` guild agent versions ${agentId}`);
|
|
83
|
-
process.exit(1);
|
|
84
|
-
}
|
|
85
|
-
version = match;
|
|
86
|
-
}
|
|
87
|
-
else {
|
|
88
|
-
if (!quiet) {
|
|
89
|
-
console.error('Building agent...');
|
|
90
|
-
}
|
|
91
|
-
const agentFiles = await readAgentFiles(resolvedPath);
|
|
92
|
-
const noCache = options.cache === false;
|
|
93
|
-
const result = await buildEphemeralVersion(client, agentId, agentFiles, resolvedPath, '[Chat] Ephemeral development version', { noCache });
|
|
94
|
-
version = result.version;
|
|
95
|
-
ephemeralCached = result.cached;
|
|
96
|
-
if (ephemeralCached && !quiet) {
|
|
97
|
-
console.error('No changes detected, reusing cached build.');
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
// Branch: JSON/JSONL modes vs interactive
|
|
101
|
-
if (options.mode === 'json' || options.mode === 'jsonl') {
|
|
102
|
-
// For JSON mode with piped input, use the piped data as the initial prompt
|
|
103
|
-
// so the agent receives it as its input (not the default 'Hello')
|
|
104
|
-
const sessionPrompt = options.mode === 'json' && inputData
|
|
105
|
-
? JSON.stringify(inputData)
|
|
106
|
-
: initialPrompt;
|
|
107
|
-
// Pre-resolve workspace so we can show the source label in output.
|
|
108
|
-
// When --workspace is given explicitly, no source label is shown.
|
|
109
|
-
let resolvedWorkspaceId = options.workspace;
|
|
110
|
-
let workspaceSourceLabel;
|
|
111
|
-
if (!resolvedWorkspaceId) {
|
|
112
|
-
const wsResolved = await getWorkspaceId(resolvedPath);
|
|
113
|
-
resolvedWorkspaceId = wsResolved?.workspaceId;
|
|
114
|
-
workspaceSourceLabel = wsResolved
|
|
115
|
-
? getWorkspaceSourceLabel(wsResolved.source)
|
|
116
|
-
: undefined;
|
|
117
|
-
}
|
|
118
|
-
const session = await createSession(client, resolvedWorkspaceId, sessionPrompt, version.id);
|
|
119
|
-
if (!quiet) {
|
|
120
|
-
console.log(`✓ Agent: ${config?.name || agentId}`);
|
|
121
|
-
if (session.workspace_id) {
|
|
122
|
-
const workspaceDisplay = workspaceSourceLabel
|
|
123
|
-
? `${session.workspace_id} (from ${workspaceSourceLabel})`
|
|
124
|
-
: session.workspace_id;
|
|
125
|
-
console.log(`✓ Workspace: ${workspaceDisplay}`);
|
|
126
|
-
}
|
|
127
|
-
const sessionLink = session.session_url
|
|
128
|
-
? hyperlink(session.id, session.session_url)
|
|
129
|
-
: session.id;
|
|
130
|
-
console.log(`✓ Session: ${sessionLink}`);
|
|
131
|
-
console.log('');
|
|
132
|
-
}
|
|
133
|
-
if (options.open && session.session_url) {
|
|
134
|
-
await open(session.session_url);
|
|
135
|
-
}
|
|
136
|
-
if (options.mode === 'json' && inputData) {
|
|
137
|
-
// JSON one-shot mode — input was passed as initial_prompt during
|
|
138
|
-
// session creation, so the agent already has it. Just poll for the response.
|
|
139
|
-
try {
|
|
140
|
-
const { response } = await pollForResponse(client, session.id, undefined);
|
|
141
|
-
if (!response) {
|
|
142
|
-
console.error('Timeout: No response received from agent');
|
|
143
|
-
process.exit(1);
|
|
144
|
-
}
|
|
145
|
-
if (quiet) {
|
|
146
|
-
console.log(response);
|
|
147
|
-
}
|
|
148
|
-
else {
|
|
149
|
-
console.log(`< ${response}`);
|
|
150
|
-
console.log('');
|
|
151
|
-
console.log('✓ Chat complete');
|
|
152
|
-
}
|
|
153
|
-
process.exit(0);
|
|
154
|
-
}
|
|
155
|
-
catch (error) {
|
|
156
|
-
const formattedError = handleAxiosError(error);
|
|
157
|
-
console.error(`Error: ${formattedError.details}`);
|
|
158
|
-
process.exit(1);
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
else if (options.mode === 'jsonl') {
|
|
162
|
-
// JSONL line-by-line mode
|
|
163
|
-
const rl = readline.createInterface({
|
|
164
|
-
input: process.stdin,
|
|
165
|
-
output: process.stdout,
|
|
166
|
-
terminal: false,
|
|
167
|
-
});
|
|
168
|
-
let lineNumber = 0;
|
|
169
|
-
let processedCount = 0;
|
|
170
|
-
let lastEventId;
|
|
171
|
-
for await (const line of rl) {
|
|
172
|
-
lineNumber++;
|
|
173
|
-
if (!line.trim())
|
|
174
|
-
continue;
|
|
175
|
-
try {
|
|
176
|
-
const jsonInput = JSON.parse(line);
|
|
177
|
-
if (!quiet) {
|
|
178
|
-
console.error(`Processing line ${lineNumber}...`);
|
|
179
|
-
}
|
|
180
|
-
await client.post(`/sessions/${session.id}/events`, {
|
|
181
|
-
mode: 'json',
|
|
182
|
-
content: jsonInput,
|
|
183
|
-
});
|
|
184
|
-
const result = await pollForResponse(client, session.id, lastEventId);
|
|
185
|
-
lastEventId = result.lastEventId;
|
|
186
|
-
if (!result.response) {
|
|
187
|
-
console.error(`Timeout: No response for line ${lineNumber}`);
|
|
188
|
-
continue;
|
|
189
|
-
}
|
|
190
|
-
const response = result.response;
|
|
191
|
-
if (quiet) {
|
|
192
|
-
console.log(response);
|
|
193
|
-
}
|
|
194
|
-
else {
|
|
195
|
-
console.log(`< ${response}`);
|
|
196
|
-
console.log('');
|
|
197
|
-
}
|
|
198
|
-
processedCount++;
|
|
199
|
-
}
|
|
200
|
-
catch (error) {
|
|
201
|
-
const err = error;
|
|
202
|
-
console.error(`Error: Invalid JSON on line ${lineNumber}`);
|
|
203
|
-
console.error(`Failed to parse JSON: ${err.message}`);
|
|
204
|
-
console.error('Skipping line and continuing...');
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
if (!quiet) {
|
|
208
|
-
console.log(`\n✓ Processed ${processedCount} messages`);
|
|
209
|
-
}
|
|
210
|
-
process.exit(0);
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
else {
|
|
214
|
-
// Interactive mode: use shared ChatApp with full features
|
|
215
|
-
// (splash animation, task panel, status line, etc.)
|
|
216
|
-
ensureInteractiveStdin('guild agent chat');
|
|
217
|
-
const resumeCommand = 'guild agent chat';
|
|
218
|
-
// Handle --resume: fetch existing session + events
|
|
219
|
-
let resumeSession;
|
|
220
|
-
let resumeSessionEvents;
|
|
221
|
-
if (options.resume) {
|
|
222
|
-
resumeSession = await fetchSession(client, options.resume);
|
|
223
|
-
resumeSessionEvents = await fetchSessionEvents(client, options.resume);
|
|
224
|
-
}
|
|
225
|
-
const isInteractive = getOutputMode() === 'interactive' && !isQuietMode();
|
|
226
|
-
const shouldShowSplash = isInteractive && !options.noSplash && !options.resume;
|
|
227
|
-
if (shouldShowSplash) {
|
|
228
|
-
suppressScrollbackClear();
|
|
229
|
-
}
|
|
230
|
-
const { waitUntilExit } = render(React.createElement(ChatApp, {
|
|
231
|
-
initialPrompt,
|
|
232
|
-
version: packageJson.version,
|
|
233
|
-
workspaceId: options.workspace,
|
|
234
|
-
versionId: version.id,
|
|
235
|
-
agentName: config?.name,
|
|
236
|
-
showSplash: shouldShowSplash,
|
|
237
|
-
resumeSession,
|
|
238
|
-
resumeEvents: resumeSessionEvents,
|
|
239
|
-
resumeCommand,
|
|
240
|
-
openDashboard: options.open,
|
|
241
|
-
}), {
|
|
242
|
-
exitOnCtrlC: false, // We handle Ctrl-C in useInput (raw mode)
|
|
243
|
-
});
|
|
244
|
-
await waitUntilExit();
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
catch (error) {
|
|
248
|
-
if (error instanceof BuildTimeoutError) {
|
|
249
|
-
console.error('Error: Build did not complete');
|
|
250
|
-
console.error('');
|
|
251
|
-
console.error(error.message);
|
|
252
|
-
console.error('');
|
|
253
|
-
console.error('Check build status:');
|
|
254
|
-
console.error(' guild agent versions');
|
|
255
|
-
process.exit(1);
|
|
256
|
-
}
|
|
257
|
-
if (error instanceof BuildFailedError) {
|
|
258
|
-
console.error(`Error: ${error.message}`);
|
|
259
|
-
process.exit(1);
|
|
260
|
-
}
|
|
261
|
-
const formattedError = handleAxiosError(error);
|
|
262
|
-
if (formattedError.code === ErrorCodes.AUTH_REQUIRED ||
|
|
263
|
-
formattedError.code === ErrorCodes.AUTH_TOKEN_INVALID) {
|
|
264
|
-
format.error('Not authenticated. Run: guild auth login');
|
|
265
|
-
process.exit(1);
|
|
266
|
-
}
|
|
267
|
-
console.error(`Error: ${formattedError.details}`);
|
|
268
|
-
process.exit(1);
|
|
269
|
-
}
|
|
270
|
-
});
|
|
271
|
-
return cmd;
|
|
272
|
-
}
|
|
273
|
-
// Thin wrapper for lazy-loading from index.ts (avoids importing React at startup)
|
|
274
|
-
export async function handleAgentChatAction(_promptArgs, _options) {
|
|
275
|
-
const cmd = createAgentChatCommand();
|
|
276
|
-
await cmd.parseAsync(process.argv.slice(3), { from: 'user' });
|
|
277
|
-
}
|
|
278
|
-
//# sourceMappingURL=chat.js.map
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
// Copyright 2026 Guild.ai
|
|
2
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
import { Command } from 'commander';
|
|
4
|
-
import { GuildAPIClient } from '../../lib/api-client.js';
|
|
5
|
-
import { handleAxiosError, ErrorCodes } from '../../lib/errors.js';
|
|
6
|
-
import * as fs from 'fs/promises';
|
|
7
|
-
import * as path from 'path';
|
|
8
|
-
import { getAuthenticatedUrl } from '../../lib/auth.js';
|
|
9
|
-
import { runGit, GitError, formatGitError, installPrePushHook } from '../../lib/git.js';
|
|
10
|
-
import { createOutputWriter } from '../../lib/output.js';
|
|
11
|
-
import { resolveAgentRef } from '../../lib/agent-helpers.js';
|
|
12
|
-
async function isDirectoryEmpty(dirPath) {
|
|
13
|
-
try {
|
|
14
|
-
const files = await fs.readdir(dirPath);
|
|
15
|
-
return files.length === 0;
|
|
16
|
-
}
|
|
17
|
-
catch {
|
|
18
|
-
// Directory doesn't exist, that's fine
|
|
19
|
-
return true;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
export function createAgentCloneCommand() {
|
|
23
|
-
const cmd = new Command('clone');
|
|
24
|
-
cmd
|
|
25
|
-
.description('Clone an existing agent repository')
|
|
26
|
-
.argument('<identifier>', 'Agent ID or full name to clone (e.g., owner~agent-name)')
|
|
27
|
-
.option('--directory <path>', 'Target directory for clone')
|
|
28
|
-
.option('--force', 'Clone even if directory is not empty', false)
|
|
29
|
-
.action(async (agentId, options) => {
|
|
30
|
-
const output = createOutputWriter();
|
|
31
|
-
try {
|
|
32
|
-
// Fetch agent details
|
|
33
|
-
const client = new GuildAPIClient();
|
|
34
|
-
const resolvedId = await resolveAgentRef(client, agentId);
|
|
35
|
-
const agent = await client.get(`/agents/${resolvedId}`);
|
|
36
|
-
if (!agent.git_url) {
|
|
37
|
-
output.error('Error: Agent does not have a git repository', 'This agent may not have been initialized with git.');
|
|
38
|
-
process.exit(1);
|
|
39
|
-
}
|
|
40
|
-
output.progress(`✓ Fetched agent '${agent.name}' (${agent.id})`);
|
|
41
|
-
// Determine target directory (default to agent name, like git clone)
|
|
42
|
-
const targetDir = options.directory || agent.name;
|
|
43
|
-
// Check if directory exists and is not empty
|
|
44
|
-
const dirExists = await fs
|
|
45
|
-
.access(targetDir)
|
|
46
|
-
.then(() => true)
|
|
47
|
-
.catch(() => false);
|
|
48
|
-
if (dirExists) {
|
|
49
|
-
const isEmpty = await isDirectoryEmpty(targetDir);
|
|
50
|
-
if (!isEmpty && !options.force) {
|
|
51
|
-
output.error(`Error: Directory '${targetDir}' is not empty`, `To clone anyway, use: guild agent clone ${agentId} --force\n\nOr choose a different directory:\n guild agent clone ${agentId} --directory ./path/to/dir`);
|
|
52
|
-
process.exit(1);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
// Clone repository
|
|
56
|
-
const cloneUrl = await getAuthenticatedUrl(agent.git_url);
|
|
57
|
-
if (!cloneUrl) {
|
|
58
|
-
output.error('Error: Not authenticated', 'Run: guild auth login');
|
|
59
|
-
process.exit(1);
|
|
60
|
-
}
|
|
61
|
-
await runGit(['clone', cloneUrl, targetDir]);
|
|
62
|
-
output.progress(`✓ Cloned repository to ${targetDir}`);
|
|
63
|
-
await installPrePushHook(targetDir);
|
|
64
|
-
output.progress('✓ Installed pre-push hook');
|
|
65
|
-
// Create guild.json if it doesn't exist
|
|
66
|
-
const guildJsonPath = path.join(targetDir, 'guild.json');
|
|
67
|
-
const guildJsonExists = await fs
|
|
68
|
-
.access(guildJsonPath)
|
|
69
|
-
.then(() => true)
|
|
70
|
-
.catch(() => false);
|
|
71
|
-
if (guildJsonExists) {
|
|
72
|
-
output.progress('✓ Verified guild.json');
|
|
73
|
-
}
|
|
74
|
-
else {
|
|
75
|
-
// Create guild.json for local development
|
|
76
|
-
const guildConfig = {
|
|
77
|
-
agent_id: agent.id,
|
|
78
|
-
name: agent.name,
|
|
79
|
-
};
|
|
80
|
-
await fs.writeFile(guildJsonPath, JSON.stringify(guildConfig, null, 2) + '\n');
|
|
81
|
-
output.progress('✓ Created guild.json');
|
|
82
|
-
}
|
|
83
|
-
// Display next steps
|
|
84
|
-
output.progress('');
|
|
85
|
-
output.progress('Next steps:');
|
|
86
|
-
output.progress(` 1. cd ${targetDir}`);
|
|
87
|
-
output.progress(' 2. Make your changes to the code');
|
|
88
|
-
output.progress(' 3. git add . && git commit -m "your changes"');
|
|
89
|
-
output.progress(" 4. Run 'guild agent save' to push and create a version");
|
|
90
|
-
output.progress(` 5. Run 'guild agent test' to test your changes`);
|
|
91
|
-
}
|
|
92
|
-
catch (error) {
|
|
93
|
-
if (error instanceof GitError) {
|
|
94
|
-
output.error('Error: Failed to clone repository', formatGitError(error));
|
|
95
|
-
process.exit(1);
|
|
96
|
-
}
|
|
97
|
-
const formattedError = handleAxiosError(error);
|
|
98
|
-
if (formattedError.code === ErrorCodes.AUTH_REQUIRED) {
|
|
99
|
-
output.error('Not authenticated. Please log in first.', 'Run: guild auth login');
|
|
100
|
-
process.exit(1);
|
|
101
|
-
}
|
|
102
|
-
if (formattedError.code === ErrorCodes.NOT_FOUND) {
|
|
103
|
-
output.error(`Error: Agent not found: ${agentId}`, 'Check the agent ID:\n guild agent list');
|
|
104
|
-
process.exit(1);
|
|
105
|
-
}
|
|
106
|
-
if (formattedError.code === ErrorCodes.CONN_REFUSED) {
|
|
107
|
-
output.error('Cannot connect to Guild servers');
|
|
108
|
-
process.exit(1);
|
|
109
|
-
}
|
|
110
|
-
output.error(`Failed to clone agent: ${formattedError.details}`);
|
|
111
|
-
process.exit(1);
|
|
112
|
-
}
|
|
113
|
-
});
|
|
114
|
-
return cmd;
|
|
115
|
-
}
|
|
116
|
-
//# sourceMappingURL=clone.js.map
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
// Copyright 2026 Guild.ai
|
|
2
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
import { Command } from 'commander';
|
|
4
|
-
import { GuildAPIClient } from '../../lib/api-client.js';
|
|
5
|
-
import { handleAxiosError, ErrorCodes } from '../../lib/errors.js';
|
|
6
|
-
import { getAgentId, resolveAgentRef } from '../../lib/agent-helpers.js';
|
|
7
|
-
import { createOutputWriter } from '../../lib/output.js';
|
|
8
|
-
import * as fs from 'fs/promises';
|
|
9
|
-
import * as path from 'path';
|
|
10
|
-
export function createAgentCodeCommand() {
|
|
11
|
-
const cmd = new Command('code');
|
|
12
|
-
cmd
|
|
13
|
-
.description('Fetch the latest code for an agent')
|
|
14
|
-
.argument('[identifier]', 'Agent ID or full name (e.g., owner~agent-name)')
|
|
15
|
-
.option('--draft', 'Include draft versions (default: only published)', false)
|
|
16
|
-
.option('--output <directory>', 'Write files to directory instead of printing JSON')
|
|
17
|
-
.action(async (agentIdArg, options) => {
|
|
18
|
-
const output = createOutputWriter();
|
|
19
|
-
// Get agent ID from argument or guild.json
|
|
20
|
-
const { agentId } = await getAgentId(agentIdArg);
|
|
21
|
-
const client = new GuildAPIClient();
|
|
22
|
-
const includeDraft = options.draft ? '1' : '0';
|
|
23
|
-
let files;
|
|
24
|
-
try {
|
|
25
|
-
const resolvedId = await resolveAgentRef(client, agentId);
|
|
26
|
-
files = await client.get(`/agents/${resolvedId}/code?include_unpublished=${includeDraft}`);
|
|
27
|
-
}
|
|
28
|
-
catch (error) {
|
|
29
|
-
const formattedError = handleAxiosError(error);
|
|
30
|
-
if (formattedError.code === ErrorCodes.AUTH_REQUIRED) {
|
|
31
|
-
output.error('Not logged in.', 'Please authenticate first:\n guild auth login');
|
|
32
|
-
}
|
|
33
|
-
else if (formattedError.code === ErrorCodes.CONN_REFUSED) {
|
|
34
|
-
output.error('Cannot connect to Guild servers');
|
|
35
|
-
}
|
|
36
|
-
else if (formattedError.code === ErrorCodes.NOT_FOUND) {
|
|
37
|
-
output.error(`Agent not found: ${agentId}`, 'Check the agent ID:\n guild agent list');
|
|
38
|
-
}
|
|
39
|
-
else {
|
|
40
|
-
output.error(`Failed to fetch agent code: ${formattedError.details}`);
|
|
41
|
-
}
|
|
42
|
-
process.exit(1);
|
|
43
|
-
}
|
|
44
|
-
if (files.length === 0) {
|
|
45
|
-
if (options.draft) {
|
|
46
|
-
output.error('No code found for this agent.', 'This agent has no versions saved yet.\n\nTo save code: cd <agent-directory> && guild agent save --message "..."');
|
|
47
|
-
}
|
|
48
|
-
else {
|
|
49
|
-
output.error('No code found for this agent.', 'This agent has no published versions.\n\nTo see draft versions: guild agent code <agent-id> --draft\nTo publish a version: cd <agent-directory> && guild agent save --message "..." --publish');
|
|
50
|
-
}
|
|
51
|
-
process.exit(1);
|
|
52
|
-
}
|
|
53
|
-
// If output directory specified, write files
|
|
54
|
-
if (options.output) {
|
|
55
|
-
try {
|
|
56
|
-
await fs.mkdir(options.output, { recursive: true });
|
|
57
|
-
for (const file of files) {
|
|
58
|
-
const filePath = path.join(options.output, file.path);
|
|
59
|
-
const fileDir = path.dirname(filePath);
|
|
60
|
-
// Create subdirectories if needed
|
|
61
|
-
await fs.mkdir(fileDir, { recursive: true });
|
|
62
|
-
// Write file
|
|
63
|
-
await fs.writeFile(filePath, file.content, 'utf-8');
|
|
64
|
-
}
|
|
65
|
-
output.data({
|
|
66
|
-
success: 'Code written to directory',
|
|
67
|
-
directory: options.output,
|
|
68
|
-
files_written: files.length,
|
|
69
|
-
files: files.map((f) => f.path),
|
|
70
|
-
});
|
|
71
|
-
process.exit(0);
|
|
72
|
-
}
|
|
73
|
-
catch (error) {
|
|
74
|
-
const err = error;
|
|
75
|
-
output.error(`Could not write files to directory: ${options.output}`, `Error: ${err.message || 'Unknown error'}\n\nCheck that:\n • Directory is writable\n • You have permission to create files\n • Disk space is available`);
|
|
76
|
-
process.exit(1);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
// Just print JSON
|
|
81
|
-
output.data({ files });
|
|
82
|
-
process.exit(0);
|
|
83
|
-
}
|
|
84
|
-
});
|
|
85
|
-
return cmd;
|
|
86
|
-
}
|
|
87
|
-
//# sourceMappingURL=code.js.map
|