@guildai/cli 0.11.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/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 +8230 -263
- package/dist/index.js.map +7 -0
- package/dist/lib/api-types.d.ts +44 -0
- package/dist/lib/config.d.ts +9 -0
- package/dist/lib/errors.d.ts +1 -1
- package/dist/lib/output.d.ts +11 -1
- package/dist/lib/session-events.d.ts +1 -1
- package/dist/lib/session-polling.d.ts +24 -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 -281
- package/dist/commands/agent/clone.js +0 -118
- package/dist/commands/agent/code.js +0 -87
- package/dist/commands/agent/fork.js +0 -220
- package/dist/commands/agent/get.js +0 -37
- package/dist/commands/agent/grep.js +0 -107
- package/dist/commands/agent/init.js +0 -403
- package/dist/commands/agent/list.js +0 -110
- package/dist/commands/agent/logs.js +0 -62
- package/dist/commands/agent/owners.js +0 -74
- package/dist/commands/agent/publish.js +0 -91
- package/dist/commands/agent/pull.js +0 -194
- package/dist/commands/agent/revalidate.js +0 -56
- package/dist/commands/agent/save.js +0 -345
- 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 -489
- package/dist/commands/agent/unpublish.js +0 -64
- package/dist/commands/agent/update.js +0 -118
- package/dist/commands/agent/versions.js +0 -55
- package/dist/commands/agent/workspaces.js +0 -54
- package/dist/commands/auth/login.js +0 -31
- 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 -1416
- package/dist/commands/config/get.js +0 -64
- package/dist/commands/config/list.js +0 -46
- package/dist/commands/config/path.js +0 -37
- 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 -260
- 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 -54
- package/dist/lib/output.js +0 -622
- 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 -126
- package/dist/lib/session-polling.js +0 -166
- package/dist/lib/session-resume.js +0 -229
- package/dist/lib/spinners.js +0 -770
- package/dist/lib/splash.js +0 -42
- package/dist/lib/stdin.js +0 -91
- 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 -137
- 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
|
@@ -1,345 +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 { isMachineReadable } from '../../lib/output-mode.js';
|
|
7
|
-
import { createOutputWriter } from '../../lib/output.js';
|
|
8
|
-
import * as fs from 'fs/promises';
|
|
9
|
-
import * as path from 'path';
|
|
10
|
-
import { getAuthenticatedUrl } from '../../lib/auth.js';
|
|
11
|
-
import { runGit, GitError, formatGitError } from '../../lib/git.js';
|
|
12
|
-
import { waitForValidation, waitForPublish } from '../../lib/version-helpers.js';
|
|
13
|
-
export function createAgentSaveCommand() {
|
|
14
|
-
const cmd = new Command('save');
|
|
15
|
-
cmd
|
|
16
|
-
.description('Commit, push, and create a new agent version')
|
|
17
|
-
.option('-A, --all', 'Stage all changes and commit before pushing', false)
|
|
18
|
-
.option('-m, --message <text>', 'Commit message (required with --all)')
|
|
19
|
-
.option('--wait', 'Wait for validation to complete before returning (default: returns immediately)', false)
|
|
20
|
-
.option('--publish', 'Publish after validation passes (implies --wait) (default: does not publish)', false)
|
|
21
|
-
.option('--bump [level]', 'Bump package.json version before saving (patch, or minor/major) (default: patch)', 'patch')
|
|
22
|
-
.option('--no-bump', 'Skip automatic version bump')
|
|
23
|
-
.action(async (options) => {
|
|
24
|
-
const cwd = process.cwd();
|
|
25
|
-
let guildConfig = null;
|
|
26
|
-
const output = createOutputWriter();
|
|
27
|
-
// Resolve bump level: bare --bump defaults to 'patch', --no-bump skips
|
|
28
|
-
const bumpLevel = options.bump === true || options.bump === 'patch'
|
|
29
|
-
? 'patch'
|
|
30
|
-
: options.bump === 'minor'
|
|
31
|
-
? 'minor'
|
|
32
|
-
: options.bump === 'major'
|
|
33
|
-
? 'major'
|
|
34
|
-
: options.bump === false
|
|
35
|
-
? null
|
|
36
|
-
: null;
|
|
37
|
-
if (options.bump !== false && bumpLevel === null) {
|
|
38
|
-
output.error(`Invalid bump level: ${String(options.bump)}`, 'Valid levels are: patch, minor, major\n guild agent save --bump minor');
|
|
39
|
-
process.exit(1);
|
|
40
|
-
}
|
|
41
|
-
// With --all, a commit message is required (unless bump auto-generates one)
|
|
42
|
-
if (options.all && !options.message && !bumpLevel) {
|
|
43
|
-
output.error('Commit message is required with --all', 'Provide a message describing your changes:\n guild agent save -A --message "Add new feature"');
|
|
44
|
-
process.exit(1);
|
|
45
|
-
}
|
|
46
|
-
let versionNumber;
|
|
47
|
-
try {
|
|
48
|
-
// Check for guild.json
|
|
49
|
-
const guildJsonPath = path.join(cwd, 'guild.json');
|
|
50
|
-
const guildJsonExists = await fs
|
|
51
|
-
.access(guildJsonPath)
|
|
52
|
-
.then(() => true)
|
|
53
|
-
.catch(() => false);
|
|
54
|
-
if (!guildJsonExists) {
|
|
55
|
-
output.error('Not in an agent directory', 'guild.json not found in current directory.\n\nInitialize an agent directory:\n guild agent init --name my-agent\n\nOr clone an existing agent:\n guild agent clone <agent-id>');
|
|
56
|
-
process.exit(1);
|
|
57
|
-
}
|
|
58
|
-
// Read guild.json
|
|
59
|
-
guildConfig = JSON.parse(await fs.readFile(guildJsonPath, 'utf-8'));
|
|
60
|
-
// Handle --bump: bump package.json version before git operations
|
|
61
|
-
if (bumpLevel) {
|
|
62
|
-
const packageJsonPath = path.join(cwd, 'package.json');
|
|
63
|
-
let packageJsonContent;
|
|
64
|
-
try {
|
|
65
|
-
packageJsonContent = await fs.readFile(packageJsonPath, 'utf-8');
|
|
66
|
-
}
|
|
67
|
-
catch {
|
|
68
|
-
output.error('package.json not found', 'A package.json file is required in the agent directory to use --bump.');
|
|
69
|
-
process.exit(1);
|
|
70
|
-
}
|
|
71
|
-
const packageJson = JSON.parse(packageJsonContent);
|
|
72
|
-
const currentVersion = packageJson.version || '0.0.0';
|
|
73
|
-
const parts = currentVersion.split('.').map(Number);
|
|
74
|
-
if (parts.length !== 3 || parts.some((p) => isNaN(p))) {
|
|
75
|
-
output.error(`Cannot bump invalid version: ${currentVersion}`, 'package.json version must be in MAJOR.MINOR.PATCH format (e.g. 1.0.0)');
|
|
76
|
-
process.exit(1);
|
|
77
|
-
}
|
|
78
|
-
const [major, minor, patch] = parts;
|
|
79
|
-
let newVersion;
|
|
80
|
-
if (bumpLevel === 'major') {
|
|
81
|
-
newVersion = `${major + 1}.0.0`;
|
|
82
|
-
}
|
|
83
|
-
else if (bumpLevel === 'minor') {
|
|
84
|
-
newVersion = `${major}.${minor + 1}.0`;
|
|
85
|
-
}
|
|
86
|
-
else {
|
|
87
|
-
newVersion = `${major}.${minor}.${patch + 1}`;
|
|
88
|
-
}
|
|
89
|
-
packageJson.version = newVersion;
|
|
90
|
-
await fs.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n');
|
|
91
|
-
versionNumber = newVersion;
|
|
92
|
-
output.progress(`✓ Bumped version: ${currentVersion} → ${newVersion}`);
|
|
93
|
-
}
|
|
94
|
-
else {
|
|
95
|
-
// No bump — read version from package.json if it exists
|
|
96
|
-
const packageJsonPath = path.join(cwd, 'package.json');
|
|
97
|
-
try {
|
|
98
|
-
const pkg = JSON.parse(await fs.readFile(packageJsonPath, 'utf-8'));
|
|
99
|
-
if (pkg.version) {
|
|
100
|
-
versionNumber = pkg.version;
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
catch {
|
|
104
|
-
// No package.json or unreadable — version stays undefined
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
// Check for uncommitted changes and unpushed commits
|
|
108
|
-
const { stdout: statusOutput } = await runGit(['status', '--porcelain'], {
|
|
109
|
-
cwd,
|
|
110
|
-
});
|
|
111
|
-
const hasUncommittedChanges = statusOutput.trim().length > 0;
|
|
112
|
-
let hasUnpushedCommits = false;
|
|
113
|
-
// Check for unpushed commits
|
|
114
|
-
try {
|
|
115
|
-
const { stdout: branchForCheck } = await runGit(['rev-parse', '--abbrev-ref', 'HEAD'], { cwd });
|
|
116
|
-
const { stdout: unpushed } = await runGit(['log', `origin/${branchForCheck.trim()}..HEAD`, '--oneline'], { cwd });
|
|
117
|
-
hasUnpushedCommits = unpushed.trim().length > 0;
|
|
118
|
-
}
|
|
119
|
-
catch {
|
|
120
|
-
// No remote tracking branch yet — if HEAD has commits, treat
|
|
121
|
-
// as unpushed so the push flow can create the remote branch.
|
|
122
|
-
try {
|
|
123
|
-
const { stdout: logOutput } = await runGit(['log', '--oneline', '-1'], {
|
|
124
|
-
cwd,
|
|
125
|
-
});
|
|
126
|
-
hasUnpushedCommits = logOutput.trim().length > 0;
|
|
127
|
-
}
|
|
128
|
-
catch {
|
|
129
|
-
hasUnpushedCommits = false;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
// --bump implies --all (the version change needs to be committed)
|
|
133
|
-
const shouldStageAll = options.all || !!bumpLevel;
|
|
134
|
-
if (shouldStageAll) {
|
|
135
|
-
// Stage and commit before pushing
|
|
136
|
-
if (hasUncommittedChanges) {
|
|
137
|
-
await runGit(['add', '-A'], { cwd });
|
|
138
|
-
output.progress('✓ Staged changes');
|
|
139
|
-
const commitMsg = options.message || (bumpLevel ? `Bump version` : '');
|
|
140
|
-
await runGit(['commit', '-m', commitMsg], { cwd });
|
|
141
|
-
output.progress('✓ Committed locally');
|
|
142
|
-
hasUnpushedCommits = true;
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
else {
|
|
146
|
-
// Default: push-only, no staging or committing
|
|
147
|
-
if (!hasUnpushedCommits && hasUncommittedChanges) {
|
|
148
|
-
output.error('Uncommitted changes', 'You have uncommitted changes. Either commit them first:\n git add . && git commit -m "your message"\n\nOr use --all to stage and commit automatically:\n guild agent save -A --message "your message"');
|
|
149
|
-
process.exit(1);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
if (!hasUnpushedCommits) {
|
|
153
|
-
output.error('No changes to save', 'Working tree is clean and there are no unpushed commits.');
|
|
154
|
-
process.exit(1);
|
|
155
|
-
}
|
|
156
|
-
// Resolve version summary: use --message if provided, otherwise
|
|
157
|
-
// extract the latest commit message.
|
|
158
|
-
let versionMessage = options.message;
|
|
159
|
-
if (!versionMessage) {
|
|
160
|
-
const { stdout: commitMsg } = await runGit(['log', '-1', '--pretty=%s'], {
|
|
161
|
-
cwd,
|
|
162
|
-
});
|
|
163
|
-
versionMessage = commitMsg.trim();
|
|
164
|
-
}
|
|
165
|
-
// Get remote URL with auth credentials
|
|
166
|
-
const { stdout: remoteUrl } = await runGit(['remote', 'get-url', 'origin'], {
|
|
167
|
-
cwd,
|
|
168
|
-
});
|
|
169
|
-
const authenticatedUrl = await getAuthenticatedUrl(remoteUrl.trim());
|
|
170
|
-
if (!authenticatedUrl) {
|
|
171
|
-
output.error('Not authenticated.', 'Run: guild auth login');
|
|
172
|
-
process.exit(1);
|
|
173
|
-
}
|
|
174
|
-
// Get current branch name
|
|
175
|
-
const { stdout: branchName } = await runGit(['rev-parse', '--abbrev-ref', 'HEAD'], {
|
|
176
|
-
cwd,
|
|
177
|
-
});
|
|
178
|
-
const currentBranch = branchName.trim();
|
|
179
|
-
// Pull remote changes first (rebase to avoid merge commits)
|
|
180
|
-
const gitEnv = { GUILD_AGENT_SAVE: '1' };
|
|
181
|
-
try {
|
|
182
|
-
const { stdout: pullOutput } = await runGit(['pull', '--rebase', authenticatedUrl, currentBranch], { cwd, env: gitEnv });
|
|
183
|
-
if (pullOutput.includes('Updating') ||
|
|
184
|
-
pullOutput.includes('Fast-forward')) {
|
|
185
|
-
output.progress('✓ Synced with remote');
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
catch (pullError) {
|
|
189
|
-
const errMessage = pullError instanceof GitError
|
|
190
|
-
? pullError.stderr || pullError.stdout
|
|
191
|
-
: String(pullError);
|
|
192
|
-
// Check for rebase conflicts
|
|
193
|
-
if (errMessage.includes('CONFLICT') ||
|
|
194
|
-
errMessage.includes('could not apply')) {
|
|
195
|
-
output.error('Merge conflict detected', 'Your changes conflict with remote changes.\n\nTo resolve:\n 1. Fix conflicts in the listed files\n 2. git add <resolved-files>\n 3. git rebase --continue\n 4. guild agent save --message "..."\n\nOr abort the rebase:\n git rebase --abort');
|
|
196
|
-
process.exit(1);
|
|
197
|
-
}
|
|
198
|
-
// If pull fails, check if it's because there's no upstream
|
|
199
|
-
if (!errMessage.includes('no tracking information') &&
|
|
200
|
-
!errMessage.includes("couldn't find remote ref")) {
|
|
201
|
-
// Real error we don't understand
|
|
202
|
-
output.error('Failed to sync with remote', errMessage);
|
|
203
|
-
process.exit(1);
|
|
204
|
-
}
|
|
205
|
-
// No upstream branch yet, that's fine - first push will set it
|
|
206
|
-
}
|
|
207
|
-
// Push to remote using authenticated URL
|
|
208
|
-
// Note: We push to the URL directly (not via origin remote) because
|
|
209
|
-
// origin doesn't have auth credentials. This means we must manually
|
|
210
|
-
// update the remote-tracking ref afterward.
|
|
211
|
-
//
|
|
212
|
-
// Retry on transient server-side errors (e.g. GitHub returning
|
|
213
|
-
// "fatal error in commit_refs" when the repo isn't fully ready).
|
|
214
|
-
const maxPushAttempts = 3;
|
|
215
|
-
for (let attempt = 1; attempt <= maxPushAttempts; attempt++) {
|
|
216
|
-
try {
|
|
217
|
-
await runGit(['push', authenticatedUrl, `HEAD:${currentBranch}`], {
|
|
218
|
-
cwd,
|
|
219
|
-
env: gitEnv,
|
|
220
|
-
});
|
|
221
|
-
break;
|
|
222
|
-
}
|
|
223
|
-
catch (pushError) {
|
|
224
|
-
const msg = pushError instanceof GitError
|
|
225
|
-
? pushError.stderr || pushError.stdout
|
|
226
|
-
: String(pushError);
|
|
227
|
-
const isTransient = msg.includes('commit_refs') ||
|
|
228
|
-
msg.includes('remote rejected') ||
|
|
229
|
-
msg.includes('Service Unavailable') ||
|
|
230
|
-
msg.includes('502') ||
|
|
231
|
-
msg.includes('503');
|
|
232
|
-
if (!isTransient || attempt === maxPushAttempts) {
|
|
233
|
-
throw pushError;
|
|
234
|
-
}
|
|
235
|
-
const delaySec = attempt * 2;
|
|
236
|
-
output.progress(`Push failed (attempt ${attempt}/${maxPushAttempts}), retrying in ${delaySec}s...`);
|
|
237
|
-
await new Promise((resolve) => setTimeout(resolve, delaySec * 1000));
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
// Update origin's remote-tracking ref so git status stays consistent.
|
|
241
|
-
// Pushing via URL doesn't update refs/remotes/origin/*, which causes
|
|
242
|
-
// "branch is ahead of origin/<branch>" confusion.
|
|
243
|
-
try {
|
|
244
|
-
await runGit(['update-ref', `refs/remotes/origin/${currentBranch}`, 'HEAD'], { cwd });
|
|
245
|
-
}
|
|
246
|
-
catch {
|
|
247
|
-
// Non-fatal: git status will be stale but save still succeeded
|
|
248
|
-
}
|
|
249
|
-
// Set up tracking for future operations
|
|
250
|
-
try {
|
|
251
|
-
await runGit(['branch', '--set-upstream-to', `origin/${currentBranch}`], {
|
|
252
|
-
cwd,
|
|
253
|
-
});
|
|
254
|
-
}
|
|
255
|
-
catch {
|
|
256
|
-
// Ignore if branch tracking already set or doesn't exist on remote yet
|
|
257
|
-
}
|
|
258
|
-
output.progress('✓ Pushed to remote');
|
|
259
|
-
// Get final commit SHA (after potential rebase)
|
|
260
|
-
const { stdout: shaOutput } = await runGit(['rev-parse', 'HEAD'], {
|
|
261
|
-
cwd,
|
|
262
|
-
});
|
|
263
|
-
const commitSha = shaOutput.trim();
|
|
264
|
-
// Create version in guildcore (always as DRAFT, publish happens separately)
|
|
265
|
-
const client = new GuildAPIClient();
|
|
266
|
-
const agentId = guildConfig?.agent_id;
|
|
267
|
-
if (!agentId) {
|
|
268
|
-
output.error('Not in an agent directory');
|
|
269
|
-
process.exit(1);
|
|
270
|
-
}
|
|
271
|
-
let version = await client.post(`/agents/${agentId}/versions`, {
|
|
272
|
-
commit_sha: commitSha,
|
|
273
|
-
summary: versionMessage,
|
|
274
|
-
version_type: 'COMMITTED',
|
|
275
|
-
...(versionNumber ? { version_number: versionNumber } : {}),
|
|
276
|
-
});
|
|
277
|
-
output.progress(`✓ Created version (${version.id})`);
|
|
278
|
-
if (options.wait || options.publish) {
|
|
279
|
-
version = await waitForValidation(version.id, output);
|
|
280
|
-
}
|
|
281
|
-
if (options.publish) {
|
|
282
|
-
output.progress('Validation passed, publishing...');
|
|
283
|
-
version = await client.post(`/versions/${version.id}/publish`, {});
|
|
284
|
-
if (options.wait && version.status !== 'PUBLISHED') {
|
|
285
|
-
version = await waitForPublish(version.id, output);
|
|
286
|
-
}
|
|
287
|
-
else {
|
|
288
|
-
output.progress('✓ Published');
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
output.progress('');
|
|
292
|
-
output.progress('Version details:');
|
|
293
|
-
output.progress(` ID: ${version.id}`);
|
|
294
|
-
output.progress(` SHA: ${version.sha ? version.sha.substring(0, 12) : '-'}`);
|
|
295
|
-
output.progress(` Status: ${version.status}`);
|
|
296
|
-
if (version.published_at) {
|
|
297
|
-
output.progress(` Published at: ${version.published_at}`);
|
|
298
|
-
}
|
|
299
|
-
output.progress(` Summary: ${version.summary}`);
|
|
300
|
-
if (options.publish && version.status === 'PUBLISHED') {
|
|
301
|
-
output.progress('');
|
|
302
|
-
output.progress('Version is now published and available in the catalog.');
|
|
303
|
-
}
|
|
304
|
-
else if (options.publish) {
|
|
305
|
-
output.progress('');
|
|
306
|
-
output.progress('Publish is in progress. Use --wait to wait for completion.');
|
|
307
|
-
}
|
|
308
|
-
else {
|
|
309
|
-
output.progress('');
|
|
310
|
-
output.progress('To publish this version:');
|
|
311
|
-
output.progress(' guild agent save --message "..." --publish');
|
|
312
|
-
}
|
|
313
|
-
// Output JSON to stdout only in --json mode.
|
|
314
|
-
// In interactive mode the progress messages above already
|
|
315
|
-
// show version details; dumping raw JSON is noise.
|
|
316
|
-
if (isMachineReadable()) {
|
|
317
|
-
output.data({ version });
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
catch (error) {
|
|
321
|
-
if (error instanceof GitError) {
|
|
322
|
-
output.error('Git operation failed', formatGitError(error));
|
|
323
|
-
process.exit(1);
|
|
324
|
-
}
|
|
325
|
-
// Handle API errors
|
|
326
|
-
const formattedError = handleAxiosError(error);
|
|
327
|
-
if (formattedError.code === ErrorCodes.AUTH_REQUIRED) {
|
|
328
|
-
output.error('Not authenticated. Please log in first.', 'Run: guild auth login');
|
|
329
|
-
process.exit(1);
|
|
330
|
-
}
|
|
331
|
-
if (formattedError.code === ErrorCodes.NOT_FOUND) {
|
|
332
|
-
output.error(`Agent not found${guildConfig ? ': ' + guildConfig.agent_id : ''}`, 'The agent may have been deleted.');
|
|
333
|
-
process.exit(1);
|
|
334
|
-
}
|
|
335
|
-
if (formattedError.details.includes('does not exist')) {
|
|
336
|
-
output.error('Commit not found in repository', "This might mean:\n • The commit wasn't pushed to the remote repository\n • The git remote is configured incorrectly\n • There's a sync issue with the backend\n\nVerify the commit exists:\n git log --oneline\n\nVerify the remote:\n git remote -v");
|
|
337
|
-
process.exit(1);
|
|
338
|
-
}
|
|
339
|
-
output.error(`Failed to save agent: ${formattedError.details}`);
|
|
340
|
-
process.exit(1);
|
|
341
|
-
}
|
|
342
|
-
});
|
|
343
|
-
return cmd;
|
|
344
|
-
}
|
|
345
|
-
//# sourceMappingURL=save.js.map
|
|
@@ -1,61 +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 { getAuthToken } from '../../lib/auth.js';
|
|
6
|
-
import { handleAxiosError } from '../../lib/errors.js';
|
|
7
|
-
import { isMachineReadable } from '../../lib/output-mode.js';
|
|
8
|
-
import { createOutputWriter, formatAgentTable } from '../../lib/output.js';
|
|
9
|
-
import { DEFAULT_PAGE_LIMIT } from '../../lib/api-types.js';
|
|
10
|
-
const SORT_MAP = {
|
|
11
|
-
updated: 'updated_at',
|
|
12
|
-
newest: 'created_at',
|
|
13
|
-
name: 'name',
|
|
14
|
-
popular: 'cached_likes_count',
|
|
15
|
-
};
|
|
16
|
-
export function createAgentSearchCommand() {
|
|
17
|
-
const cmd = new Command('search');
|
|
18
|
-
cmd
|
|
19
|
-
.description('Search agents')
|
|
20
|
-
.argument('<query>', 'Search query')
|
|
21
|
-
.option('--sort <field>', 'Sort by: updated, newest, name, popular (default: updated)', 'updated')
|
|
22
|
-
.option('--published', 'Only show published agents')
|
|
23
|
-
.option('--limit <number>', `Number of results to return (default: ${DEFAULT_PAGE_LIMIT})`, String(DEFAULT_PAGE_LIMIT))
|
|
24
|
-
.option('--offset <number>', 'Offset for pagination (default: 0)', '0')
|
|
25
|
-
.action(async (query, options) => {
|
|
26
|
-
const output = createOutputWriter();
|
|
27
|
-
try {
|
|
28
|
-
const token = await getAuthToken();
|
|
29
|
-
if (!token) {
|
|
30
|
-
output.error('Not authenticated. Please log in first.', 'Run: guild auth login');
|
|
31
|
-
process.exit(1);
|
|
32
|
-
}
|
|
33
|
-
const client = new GuildAPIClient();
|
|
34
|
-
const params = new URLSearchParams();
|
|
35
|
-
params.append('search', query);
|
|
36
|
-
params.append('limit', options.limit);
|
|
37
|
-
params.append('offset', options.offset);
|
|
38
|
-
if (options.published) {
|
|
39
|
-
params.append('published_only', 'true');
|
|
40
|
-
}
|
|
41
|
-
const sortField = SORT_MAP[options.sort];
|
|
42
|
-
if (sortField) {
|
|
43
|
-
params.append('sort_by', sortField);
|
|
44
|
-
}
|
|
45
|
-
const response = await client.get(`/agents?${params.toString()}`);
|
|
46
|
-
if (isMachineReadable()) {
|
|
47
|
-
output.data(response);
|
|
48
|
-
}
|
|
49
|
-
else {
|
|
50
|
-
formatAgentTable(response.items, response.pagination);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
catch (error) {
|
|
54
|
-
const formattedError = handleAxiosError(error);
|
|
55
|
-
output.error(`Failed to search agents: ${formattedError.details}`);
|
|
56
|
-
process.exit(1);
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
return cmd;
|
|
60
|
-
}
|
|
61
|
-
//# sourceMappingURL=search.js.map
|
|
@@ -1,73 +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 { getAgentId, resolveAgentRef } from '../../../lib/agent-helpers.js';
|
|
6
|
-
import { handleAxiosError, ErrorCodes } from '../../../lib/errors.js';
|
|
7
|
-
import { createOutputWriter } from '../../../lib/output.js';
|
|
8
|
-
export function createAgentTagsAddCommand() {
|
|
9
|
-
const cmd = new Command('add');
|
|
10
|
-
cmd
|
|
11
|
-
.description('Add tags to an agent')
|
|
12
|
-
.argument('[agent-id]', 'Agent ID (optional if in agent directory)')
|
|
13
|
-
.argument('<tags...>', 'Tags to add')
|
|
14
|
-
.action(async (agentIdOrFirstTag, remainingTags) => {
|
|
15
|
-
const output = createOutputWriter();
|
|
16
|
-
try {
|
|
17
|
-
const client = new GuildAPIClient();
|
|
18
|
-
// Parse arguments - need to determine if first arg is agent-id or tag
|
|
19
|
-
let agentIdArg;
|
|
20
|
-
let tagsToAdd;
|
|
21
|
-
// Try to resolve agent ID from first argument
|
|
22
|
-
try {
|
|
23
|
-
await getAgentId(agentIdOrFirstTag);
|
|
24
|
-
// If successful, first arg was agent-id
|
|
25
|
-
agentIdArg = agentIdOrFirstTag;
|
|
26
|
-
tagsToAdd = remainingTags;
|
|
27
|
-
}
|
|
28
|
-
catch {
|
|
29
|
-
// First arg is not agent-id, must be a tag
|
|
30
|
-
// Try to get agent-id from guild.json
|
|
31
|
-
await getAgentId(undefined);
|
|
32
|
-
agentIdArg = undefined;
|
|
33
|
-
tagsToAdd = [agentIdOrFirstTag, ...remainingTags];
|
|
34
|
-
}
|
|
35
|
-
// Now resolve agent ID properly
|
|
36
|
-
const { agentId, config } = await getAgentId(agentIdArg);
|
|
37
|
-
const resolvedId = await resolveAgentRef(client, agentId);
|
|
38
|
-
if (tagsToAdd.length === 0) {
|
|
39
|
-
output.error('At least one tag is required.', 'Usage: guild agent tags add [agent-id] <tag...>');
|
|
40
|
-
process.exit(1);
|
|
41
|
-
}
|
|
42
|
-
// Fetch current tags
|
|
43
|
-
const response = await client.get(`/agents/${resolvedId}/tags`);
|
|
44
|
-
const currentTags = response.names;
|
|
45
|
-
// Add new tags (deduplicate)
|
|
46
|
-
const updatedTags = Array.from(new Set([...currentTags, ...tagsToAdd]));
|
|
47
|
-
// Update tags
|
|
48
|
-
await client.post(`/agents/${resolvedId}/tags`, { names: updatedTags });
|
|
49
|
-
const agentName = config?.name || `agent ${agentId}`;
|
|
50
|
-
const label = `${agentName}${config ? '' : ` (${agentId})`}`;
|
|
51
|
-
output.success(`Updated tags for agent: ${label}`);
|
|
52
|
-
output.data({ names: updatedTags });
|
|
53
|
-
}
|
|
54
|
-
catch (error) {
|
|
55
|
-
const formattedError = handleAxiosError(error);
|
|
56
|
-
if (formattedError.code === ErrorCodes.AUTH_REQUIRED) {
|
|
57
|
-
output.error('Not authenticated.', 'Run: guild auth login');
|
|
58
|
-
}
|
|
59
|
-
else if (formattedError.code === ErrorCodes.NOT_FOUND) {
|
|
60
|
-
output.error('Agent not found.', 'Run: guild agent list');
|
|
61
|
-
}
|
|
62
|
-
else if (formattedError.code === ErrorCodes.CONN_REFUSED) {
|
|
63
|
-
output.error('Cannot connect to Guild servers');
|
|
64
|
-
}
|
|
65
|
-
else {
|
|
66
|
-
output.error(`Failed to add tags: ${formattedError.details}`);
|
|
67
|
-
}
|
|
68
|
-
process.exit(1);
|
|
69
|
-
}
|
|
70
|
-
});
|
|
71
|
-
return cmd;
|
|
72
|
-
}
|
|
73
|
-
//# sourceMappingURL=add.js.map
|
|
@@ -1,43 +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 { getAgentId, resolveAgentRef } from '../../../lib/agent-helpers.js';
|
|
6
|
-
import { handleAxiosError, ErrorCodes } from '../../../lib/errors.js';
|
|
7
|
-
import { createOutputWriter } from '../../../lib/output.js';
|
|
8
|
-
export function createAgentTagsListCommand() {
|
|
9
|
-
const cmd = new Command('list');
|
|
10
|
-
cmd
|
|
11
|
-
.description('List tags for an agent')
|
|
12
|
-
.argument('[agent-id]', 'Agent ID (optional if in agent directory)')
|
|
13
|
-
.action(async (agentIdArg) => {
|
|
14
|
-
const output = createOutputWriter();
|
|
15
|
-
try {
|
|
16
|
-
const client = new GuildAPIClient();
|
|
17
|
-
// Resolve agent ID
|
|
18
|
-
const { agentId } = await getAgentId(agentIdArg);
|
|
19
|
-
const resolvedId = await resolveAgentRef(client, agentId);
|
|
20
|
-
// Fetch tags
|
|
21
|
-
const response = await client.get(`/agents/${resolvedId}/tags`);
|
|
22
|
-
output.data(response);
|
|
23
|
-
}
|
|
24
|
-
catch (error) {
|
|
25
|
-
const formattedError = handleAxiosError(error);
|
|
26
|
-
if (formattedError.code === ErrorCodes.AUTH_REQUIRED) {
|
|
27
|
-
output.error('Not authenticated.', 'Run: guild auth login');
|
|
28
|
-
}
|
|
29
|
-
else if (formattedError.code === ErrorCodes.NOT_FOUND) {
|
|
30
|
-
output.error('Agent not found.', 'Run: guild agent list');
|
|
31
|
-
}
|
|
32
|
-
else if (formattedError.code === ErrorCodes.CONN_REFUSED) {
|
|
33
|
-
output.error('Cannot connect to Guild servers');
|
|
34
|
-
}
|
|
35
|
-
else {
|
|
36
|
-
output.error(`Failed to fetch tags: ${formattedError.details}`);
|
|
37
|
-
}
|
|
38
|
-
process.exit(1);
|
|
39
|
-
}
|
|
40
|
-
});
|
|
41
|
-
return cmd;
|
|
42
|
-
}
|
|
43
|
-
//# sourceMappingURL=list.js.map
|
|
@@ -1,84 +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 { getAgentId, resolveAgentRef } from '../../../lib/agent-helpers.js';
|
|
6
|
-
import { handleAxiosError, ErrorCodes } from '../../../lib/errors.js';
|
|
7
|
-
import { createOutputWriter } from '../../../lib/output.js';
|
|
8
|
-
export function createAgentTagsRemoveCommand() {
|
|
9
|
-
const cmd = new Command('remove');
|
|
10
|
-
cmd
|
|
11
|
-
.description('Remove tags from an agent')
|
|
12
|
-
.argument('[agent-id]', 'Agent ID (optional if in agent directory)')
|
|
13
|
-
.argument('<tags...>', 'Tags to remove')
|
|
14
|
-
.action(async (agentIdOrFirstTag, remainingTags) => {
|
|
15
|
-
const output = createOutputWriter();
|
|
16
|
-
try {
|
|
17
|
-
const client = new GuildAPIClient();
|
|
18
|
-
// Parse arguments - need to determine if first arg is agent-id or tag
|
|
19
|
-
let agentIdArg;
|
|
20
|
-
let tagsToRemove;
|
|
21
|
-
// Try to resolve agent ID from first argument
|
|
22
|
-
try {
|
|
23
|
-
await getAgentId(agentIdOrFirstTag);
|
|
24
|
-
// If successful, first arg was agent-id
|
|
25
|
-
agentIdArg = agentIdOrFirstTag;
|
|
26
|
-
tagsToRemove = remainingTags;
|
|
27
|
-
}
|
|
28
|
-
catch {
|
|
29
|
-
// First arg is not agent-id, must be a tag
|
|
30
|
-
// Try to get agent-id from guild.json
|
|
31
|
-
await getAgentId(undefined);
|
|
32
|
-
agentIdArg = undefined;
|
|
33
|
-
tagsToRemove = [agentIdOrFirstTag, ...remainingTags];
|
|
34
|
-
}
|
|
35
|
-
// Now resolve agent ID properly
|
|
36
|
-
const { agentId, config } = await getAgentId(agentIdArg);
|
|
37
|
-
const resolvedId = await resolveAgentRef(client, agentId);
|
|
38
|
-
if (tagsToRemove.length === 0) {
|
|
39
|
-
output.error('At least one tag is required.', 'Usage: guild agent tags remove [agent-id] <tag...>');
|
|
40
|
-
process.exit(1);
|
|
41
|
-
}
|
|
42
|
-
// Fetch current tags
|
|
43
|
-
const response = await client.get(`/agents/${resolvedId}/tags`);
|
|
44
|
-
const currentTags = response.names;
|
|
45
|
-
// Remove specified tags
|
|
46
|
-
const updatedTags = currentTags.filter((tag) => !tagsToRemove.includes(tag));
|
|
47
|
-
// Track which tags were not present
|
|
48
|
-
const notPresentTags = tagsToRemove.filter((tag) => !currentTags.includes(tag));
|
|
49
|
-
// Update tags
|
|
50
|
-
await client.post(`/agents/${resolvedId}/tags`, { names: updatedTags });
|
|
51
|
-
const agentName = config?.name || `agent ${agentId}`;
|
|
52
|
-
const label = `${agentName}${config ? '' : ` (${agentId})`}`;
|
|
53
|
-
output.success(`Updated tags for agent: ${label}`);
|
|
54
|
-
output.data({ names: updatedTags });
|
|
55
|
-
// Show warning for tags that weren't present
|
|
56
|
-
if (notPresentTags.length > 0) {
|
|
57
|
-
if (notPresentTags.length === 1) {
|
|
58
|
-
output.progress(`Note: Tag '${notPresentTags[0]}' was not present`);
|
|
59
|
-
}
|
|
60
|
-
else {
|
|
61
|
-
output.progress(`Note: Tags not present: ${notPresentTags.map((t) => `'${t}'`).join(', ')}`);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
catch (error) {
|
|
66
|
-
const formattedError = handleAxiosError(error);
|
|
67
|
-
if (formattedError.code === ErrorCodes.AUTH_REQUIRED) {
|
|
68
|
-
output.error('Not authenticated.', 'Run: guild auth login');
|
|
69
|
-
}
|
|
70
|
-
else if (formattedError.code === ErrorCodes.NOT_FOUND) {
|
|
71
|
-
output.error('Agent not found.', 'Run: guild agent list');
|
|
72
|
-
}
|
|
73
|
-
else if (formattedError.code === ErrorCodes.CONN_REFUSED) {
|
|
74
|
-
output.error('Cannot connect to Guild servers');
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
output.error(`Failed to remove tags: ${formattedError.details}`);
|
|
78
|
-
}
|
|
79
|
-
process.exit(1);
|
|
80
|
-
}
|
|
81
|
-
});
|
|
82
|
-
return cmd;
|
|
83
|
-
}
|
|
84
|
-
//# sourceMappingURL=remove.js.map
|