@agentuity/cli 2.0.11 → 2.0.12
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/cache/resource-region.d.ts.map +1 -1
- package/dist/cache/resource-region.js +48 -25
- package/dist/cache/resource-region.js.map +1 -1
- package/dist/cmd/build/vite/bun-dev-server.d.ts +20 -0
- package/dist/cmd/build/vite/bun-dev-server.d.ts.map +1 -1
- package/dist/cmd/build/vite/bun-dev-server.js +62 -4
- package/dist/cmd/build/vite/bun-dev-server.js.map +1 -1
- package/dist/cmd/build/vite/index.d.ts +0 -1
- package/dist/cmd/build/vite/index.d.ts.map +1 -1
- package/dist/cmd/build/vite/index.js +0 -1
- package/dist/cmd/build/vite/index.js.map +1 -1
- package/dist/cmd/build/vite/static-renderer.d.ts +17 -0
- package/dist/cmd/build/vite/static-renderer.d.ts.map +1 -1
- package/dist/cmd/build/vite/static-renderer.js +18 -6
- package/dist/cmd/build/vite/static-renderer.js.map +1 -1
- package/dist/cmd/build/vite/vite-asset-server-config.d.ts.map +1 -1
- package/dist/cmd/build/vite/vite-asset-server-config.js +34 -27
- package/dist/cmd/build/vite/vite-asset-server-config.js.map +1 -1
- package/dist/cmd/build/vite/vite-asset-server.d.ts +9 -0
- package/dist/cmd/build/vite/vite-asset-server.d.ts.map +1 -1
- package/dist/cmd/build/vite/vite-asset-server.js +5 -1
- package/dist/cmd/build/vite/vite-asset-server.js.map +1 -1
- package/dist/cmd/build/vite/vite-builder.d.ts.map +1 -1
- package/dist/cmd/build/vite/vite-builder.js +12 -1
- package/dist/cmd/build/vite/vite-builder.js.map +1 -1
- package/dist/cmd/build/vite/ws-proxy.d.ts +15 -1
- package/dist/cmd/build/vite/ws-proxy.d.ts.map +1 -1
- package/dist/cmd/build/vite/ws-proxy.js +33 -0
- package/dist/cmd/build/vite/ws-proxy.js.map +1 -1
- package/dist/cmd/cloud/deploy.d.ts.map +1 -1
- package/dist/cmd/cloud/deploy.js +98 -39
- package/dist/cmd/cloud/deploy.js.map +1 -1
- package/dist/cmd/cloud/sandbox/checkpoint/create.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/checkpoint/create.js +3 -4
- package/dist/cmd/cloud/sandbox/checkpoint/create.js.map +1 -1
- package/dist/cmd/cloud/sandbox/checkpoint/delete.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/checkpoint/delete.js +3 -4
- package/dist/cmd/cloud/sandbox/checkpoint/delete.js.map +1 -1
- package/dist/cmd/cloud/sandbox/checkpoint/list.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/checkpoint/list.js +3 -4
- package/dist/cmd/cloud/sandbox/checkpoint/list.js.map +1 -1
- package/dist/cmd/cloud/sandbox/checkpoint/restore.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/checkpoint/restore.js +3 -4
- package/dist/cmd/cloud/sandbox/checkpoint/restore.js.map +1 -1
- package/dist/cmd/cloud/sandbox/create.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/create.js +13 -4
- package/dist/cmd/cloud/sandbox/create.js.map +1 -1
- package/dist/cmd/cloud/sandbox/delete.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/delete.js +3 -4
- package/dist/cmd/cloud/sandbox/delete.js.map +1 -1
- package/dist/cmd/cloud/sandbox/env.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/env.js +3 -5
- package/dist/cmd/cloud/sandbox/env.js.map +1 -1
- package/dist/cmd/cloud/sandbox/exec.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/exec.js +114 -41
- package/dist/cmd/cloud/sandbox/exec.js.map +1 -1
- package/dist/cmd/cloud/sandbox/execution/list.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/execution/list.js +3 -5
- package/dist/cmd/cloud/sandbox/execution/list.js.map +1 -1
- package/dist/cmd/cloud/sandbox/fs/cp.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/fs/cp.js +61 -113
- package/dist/cmd/cloud/sandbox/fs/cp.js.map +1 -1
- package/dist/cmd/cloud/sandbox/fs/download.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/fs/download.js +11 -22
- package/dist/cmd/cloud/sandbox/fs/download.js.map +1 -1
- package/dist/cmd/cloud/sandbox/fs/ls.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/fs/ls.js +3 -5
- package/dist/cmd/cloud/sandbox/fs/ls.js.map +1 -1
- package/dist/cmd/cloud/sandbox/fs/mkdir.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/fs/mkdir.js +3 -5
- package/dist/cmd/cloud/sandbox/fs/mkdir.js.map +1 -1
- package/dist/cmd/cloud/sandbox/fs/rm.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/fs/rm.js +3 -5
- package/dist/cmd/cloud/sandbox/fs/rm.js.map +1 -1
- package/dist/cmd/cloud/sandbox/fs/rmdir.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/fs/rmdir.js +3 -5
- package/dist/cmd/cloud/sandbox/fs/rmdir.js.map +1 -1
- package/dist/cmd/cloud/sandbox/fs/upload.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/fs/upload.js +7 -8
- package/dist/cmd/cloud/sandbox/fs/upload.js.map +1 -1
- package/dist/cmd/cloud/sandbox/get.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/get.js +21 -7
- package/dist/cmd/cloud/sandbox/get.js.map +1 -1
- package/dist/cmd/cloud/sandbox/job/create.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/job/create.js +3 -4
- package/dist/cmd/cloud/sandbox/job/create.js.map +1 -1
- package/dist/cmd/cloud/sandbox/job/destroy.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/job/destroy.js +3 -4
- package/dist/cmd/cloud/sandbox/job/destroy.js.map +1 -1
- package/dist/cmd/cloud/sandbox/job/get.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/job/get.js +3 -4
- package/dist/cmd/cloud/sandbox/job/get.js.map +1 -1
- package/dist/cmd/cloud/sandbox/job/list.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/job/list.js +3 -4
- package/dist/cmd/cloud/sandbox/job/list.js.map +1 -1
- package/dist/cmd/cloud/sandbox/job/logs.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/job/logs.js +4 -4
- package/dist/cmd/cloud/sandbox/job/logs.js.map +1 -1
- package/dist/cmd/cloud/sandbox/pause.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/pause.js +21 -5
- package/dist/cmd/cloud/sandbox/pause.js.map +1 -1
- package/dist/cmd/cloud/sandbox/resume.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/resume.js +3 -4
- package/dist/cmd/cloud/sandbox/resume.js.map +1 -1
- package/dist/cmd/cloud/sandbox/run.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/run.js +36 -7
- package/dist/cmd/cloud/sandbox/run.js.map +1 -1
- package/dist/cmd/cloud/sandbox/util.d.ts +19 -0
- package/dist/cmd/cloud/sandbox/util.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/util.js +40 -2
- package/dist/cmd/cloud/sandbox/util.js.map +1 -1
- package/dist/cmd/coder/create.js +7 -7
- package/dist/cmd/coder/create.js.map +1 -1
- package/dist/cmd/coder/start.d.ts.map +1 -1
- package/dist/cmd/coder/start.js +3 -0
- package/dist/cmd/coder/start.js.map +1 -1
- package/dist/cmd/coder/tui-init.js +1 -1
- package/dist/cmd/coder/tui-init.js.map +1 -1
- package/dist/cmd/coder/update.js +8 -8
- package/dist/cmd/coder/update.js.map +1 -1
- package/dist/cmd/coder/workspace/create.d.ts.map +1 -1
- package/dist/cmd/coder/workspace/create.js +49 -21
- package/dist/cmd/coder/workspace/create.js.map +1 -1
- package/dist/cmd/coder/workspace/index.d.ts.map +1 -1
- package/dist/cmd/coder/workspace/index.js +1 -1
- package/dist/cmd/coder/workspace/index.js.map +1 -1
- package/dist/cmd/dev/dev-lock.d.ts.map +1 -1
- package/dist/cmd/dev/dev-lock.js +43 -17
- package/dist/cmd/dev/dev-lock.js.map +1 -1
- package/dist/cmd/dev/index.d.ts.map +1 -1
- package/dist/cmd/dev/index.js +211 -125
- package/dist/cmd/dev/index.js.map +1 -1
- package/dist/cmd/dev/process-manager.d.ts +41 -1
- package/dist/cmd/dev/process-manager.d.ts.map +1 -1
- package/dist/cmd/dev/process-manager.js +160 -31
- package/dist/cmd/dev/process-manager.js.map +1 -1
- package/dist/cmd/project/create.d.ts.map +1 -1
- package/dist/cmd/project/create.js +0 -2
- package/dist/cmd/project/create.js.map +1 -1
- package/dist/cmd/project/index.d.ts.map +1 -1
- package/dist/cmd/project/index.js +0 -3
- package/dist/cmd/project/index.js.map +1 -1
- package/dist/cmd/project/template-flow.d.ts +0 -1
- package/dist/cmd/project/template-flow.d.ts.map +1 -1
- package/dist/cmd/project/template-flow.js +1 -124
- package/dist/cmd/project/template-flow.js.map +1 -1
- package/package.json +7 -7
- package/src/cache/resource-region.ts +68 -44
- package/src/cmd/ai/prompt/web.md +43 -17
- package/src/cmd/build/vite/bun-dev-server.ts +92 -6
- package/src/cmd/build/vite/index.ts +0 -1
- package/src/cmd/build/vite/static-renderer.ts +18 -7
- package/src/cmd/build/vite/vite-asset-server-config.ts +37 -27
- package/src/cmd/build/vite/vite-asset-server.ts +5 -1
- package/src/cmd/build/vite/vite-builder.ts +12 -1
- package/src/cmd/build/vite/ws-proxy.ts +52 -3
- package/src/cmd/cloud/deploy.ts +117 -49
- package/src/cmd/cloud/sandbox/checkpoint/create.ts +10 -4
- package/src/cmd/cloud/sandbox/checkpoint/delete.ts +10 -4
- package/src/cmd/cloud/sandbox/checkpoint/list.ts +10 -4
- package/src/cmd/cloud/sandbox/checkpoint/restore.ts +10 -4
- package/src/cmd/cloud/sandbox/create.ts +14 -4
- package/src/cmd/cloud/sandbox/delete.ts +10 -4
- package/src/cmd/cloud/sandbox/env.ts +10 -5
- package/src/cmd/cloud/sandbox/exec.ts +157 -42
- package/src/cmd/cloud/sandbox/execution/list.ts +10 -5
- package/src/cmd/cloud/sandbox/fs/cp.ts +94 -126
- package/src/cmd/cloud/sandbox/fs/download.ts +18 -25
- package/src/cmd/cloud/sandbox/fs/ls.ts +10 -5
- package/src/cmd/cloud/sandbox/fs/mkdir.ts +10 -5
- package/src/cmd/cloud/sandbox/fs/rm.ts +10 -5
- package/src/cmd/cloud/sandbox/fs/rmdir.ts +10 -5
- package/src/cmd/cloud/sandbox/fs/upload.ts +14 -8
- package/src/cmd/cloud/sandbox/get.ts +28 -7
- package/src/cmd/cloud/sandbox/job/create.ts +10 -4
- package/src/cmd/cloud/sandbox/job/destroy.ts +10 -4
- package/src/cmd/cloud/sandbox/job/get.ts +10 -4
- package/src/cmd/cloud/sandbox/job/list.ts +10 -4
- package/src/cmd/cloud/sandbox/job/logs.ts +11 -4
- package/src/cmd/cloud/sandbox/pause.ts +31 -5
- package/src/cmd/cloud/sandbox/resume.ts +10 -4
- package/src/cmd/cloud/sandbox/run.ts +49 -11
- package/src/cmd/cloud/sandbox/util.ts +63 -2
- package/src/cmd/coder/create.ts +8 -8
- package/src/cmd/coder/start.ts +3 -0
- package/src/cmd/coder/tui-init.ts +1 -1
- package/src/cmd/coder/update.ts +7 -7
- package/src/cmd/coder/workspace/create.ts +77 -26
- package/src/cmd/coder/workspace/index.ts +3 -1
- package/src/cmd/dev/dev-lock.ts +50 -16
- package/src/cmd/dev/index.ts +249 -134
- package/src/cmd/dev/process-manager.ts +173 -33
- package/src/cmd/project/create.ts +0 -2
- package/src/cmd/project/index.ts +0 -3
- package/src/cmd/project/template-flow.ts +0 -147
- package/dist/cmd/build/vite/public-asset-path-plugin.d.ts +0 -45
- package/dist/cmd/build/vite/public-asset-path-plugin.d.ts.map +0 -1
- package/dist/cmd/build/vite/public-asset-path-plugin.js +0 -166
- package/dist/cmd/build/vite/public-asset-path-plugin.js.map +0 -1
- package/dist/cmd/project/auth/generate.d.ts +0 -5
- package/dist/cmd/project/auth/generate.d.ts.map +0 -1
- package/dist/cmd/project/auth/generate.js +0 -102
- package/dist/cmd/project/auth/generate.js.map +0 -1
- package/dist/cmd/project/auth/index.d.ts +0 -2
- package/dist/cmd/project/auth/index.d.ts.map +0 -1
- package/dist/cmd/project/auth/index.js +0 -21
- package/dist/cmd/project/auth/index.js.map +0 -1
- package/dist/cmd/project/auth/init.d.ts +0 -2
- package/dist/cmd/project/auth/init.d.ts.map +0 -1
- package/dist/cmd/project/auth/init.js +0 -213
- package/dist/cmd/project/auth/init.js.map +0 -1
- package/dist/cmd/project/auth/shared.d.ts +0 -93
- package/dist/cmd/project/auth/shared.d.ts.map +0 -1
- package/dist/cmd/project/auth/shared.js +0 -475
- package/dist/cmd/project/auth/shared.js.map +0 -1
- package/src/cmd/build/vite/public-asset-path-plugin.ts +0 -209
- package/src/cmd/project/auth/generate.ts +0 -116
- package/src/cmd/project/auth/index.ts +0 -21
- package/src/cmd/project/auth/init.ts +0 -256
- package/src/cmd/project/auth/shared.ts +0 -591
|
@@ -1,17 +1,69 @@
|
|
|
1
|
-
import { readFileSync } from 'node:fs';
|
|
1
|
+
import { fstatSync, readFileSync, statSync } from 'node:fs';
|
|
2
2
|
import { resolve } from 'node:path';
|
|
3
3
|
import type { FileToWrite, Logger } from '@agentuity/core';
|
|
4
|
-
import { APIClient, getServiceUrls, sandboxGet } from '@agentuity/server';
|
|
4
|
+
import { APIClient, getServiceUrls, sandboxGet, sandboxResolve } from '@agentuity/server';
|
|
5
5
|
import { deleteResourceRegion, getResourceInfo, setResourceInfo } from '../../../cache';
|
|
6
6
|
import { getGlobalCatalystAPIClient } from '../../../config';
|
|
7
7
|
import { ErrorCode } from '../../../errors';
|
|
8
8
|
import * as tui from '../../../tui';
|
|
9
9
|
import type { AuthData, Config } from '../../../types';
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Detect if a file descriptor is redirected to /dev/null (or NUL on Windows).
|
|
13
|
+
* Used to optimize stream creation - when output goes to /dev/null, we can
|
|
14
|
+
* skip creating the stream entirely on the server.
|
|
15
|
+
*
|
|
16
|
+
* @param fd - File descriptor (1 for stdout, 2 for stderr)
|
|
17
|
+
* @returns true if the fd points to /dev/null
|
|
18
|
+
*/
|
|
19
|
+
export function detectNullStream(fd: number): boolean {
|
|
20
|
+
try {
|
|
21
|
+
const fdStat = fstatSync(fd);
|
|
22
|
+
const nullPath = process.platform === 'win32' ? 'NUL' : '/dev/null';
|
|
23
|
+
const nullStat = statSync(nullPath);
|
|
24
|
+
return fdStat.dev === nullStat.dev && fdStat.ino === nullStat.ino;
|
|
25
|
+
} catch {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
11
30
|
export function createSandboxClient(logger: Logger, auth: AuthData, region: string): APIClient {
|
|
12
31
|
return new APIClient(getServiceUrls(region).catalyst, logger, auth.apiKey);
|
|
13
32
|
}
|
|
14
33
|
|
|
34
|
+
export interface ResolvedSandboxTarget {
|
|
35
|
+
region: string;
|
|
36
|
+
orgId: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Resolve sandbox routing context using cache-first lookup.
|
|
41
|
+
* Falls back to the CLI resolve endpoint on cache miss or partial cache.
|
|
42
|
+
*/
|
|
43
|
+
export async function resolveSandboxTarget(
|
|
44
|
+
logger: Logger,
|
|
45
|
+
auth: AuthData,
|
|
46
|
+
apiClient: APIClient | null = null,
|
|
47
|
+
sandboxId: string,
|
|
48
|
+
profileName = 'production',
|
|
49
|
+
config?: Config | null
|
|
50
|
+
): Promise<ResolvedSandboxTarget> {
|
|
51
|
+
const cachedInfo = await getResourceInfo('sandbox', profileName, sandboxId);
|
|
52
|
+
if (cachedInfo?.region && cachedInfo?.orgId) {
|
|
53
|
+
logger.trace(
|
|
54
|
+
`[sandbox] Found cached target for ${sandboxId}: ${cachedInfo.region}/${cachedInfo.orgId}`
|
|
55
|
+
);
|
|
56
|
+
return { region: cachedInfo.region, orgId: cachedInfo.orgId };
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
logger.trace(`[sandbox] Cache miss for target ${sandboxId}, resolving via CLI API`);
|
|
60
|
+
const globalClient =
|
|
61
|
+
apiClient ?? (await getGlobalCatalystAPIClient(logger, auth, profileName, undefined, config));
|
|
62
|
+
const sandbox = await sandboxResolve(globalClient, sandboxId);
|
|
63
|
+
await setResourceInfo('sandbox', profileName, sandboxId, sandbox.region, sandbox.orgId);
|
|
64
|
+
return { region: sandbox.region, orgId: sandbox.orgId };
|
|
65
|
+
}
|
|
66
|
+
|
|
15
67
|
/**
|
|
16
68
|
* Look up the region for a sandbox, using cache-first strategy.
|
|
17
69
|
* Falls back to API lookup if not in cache.
|
|
@@ -64,6 +116,15 @@ export async function cacheSandboxRegion(
|
|
|
64
116
|
await setResourceInfo('sandbox', profileName, sandboxId, region);
|
|
65
117
|
}
|
|
66
118
|
|
|
119
|
+
export async function cacheSandboxTarget(
|
|
120
|
+
profileName = 'production',
|
|
121
|
+
sandboxId: string,
|
|
122
|
+
region: string,
|
|
123
|
+
orgId?: string
|
|
124
|
+
): Promise<void> {
|
|
125
|
+
await setResourceInfo('sandbox', profileName, sandboxId, region, orgId);
|
|
126
|
+
}
|
|
127
|
+
|
|
67
128
|
/**
|
|
68
129
|
* Clear cached region for a sandbox after delete
|
|
69
130
|
*/
|
package/src/cmd/coder/create.ts
CHANGED
|
@@ -46,9 +46,9 @@ export const createCoderSubcommand = createSubcommand({
|
|
|
46
46
|
},
|
|
47
47
|
{
|
|
48
48
|
command: getCommand(
|
|
49
|
-
'coder create "Review this change" --default-agent code-review --
|
|
49
|
+
'coder create "Review this change" --default-agent code-review --enabled-agents code-review'
|
|
50
50
|
),
|
|
51
|
-
description: 'Create with
|
|
51
|
+
description: 'Create with a selected agent roster and a custom default route target',
|
|
52
52
|
},
|
|
53
53
|
],
|
|
54
54
|
schema: {
|
|
@@ -96,10 +96,10 @@ export const createCoderSubcommand = createSubcommand({
|
|
|
96
96
|
// Resources
|
|
97
97
|
workspaceId: z.string().optional().describe('Workspace ID to use'),
|
|
98
98
|
tags: z.string().optional().describe('Comma-separated tags'),
|
|
99
|
-
|
|
99
|
+
enabledAgents: z
|
|
100
100
|
.string()
|
|
101
101
|
.optional()
|
|
102
|
-
.describe('Comma-separated
|
|
102
|
+
.describe('Comma-separated built-in/custom agents to include'),
|
|
103
103
|
env: z
|
|
104
104
|
.string()
|
|
105
105
|
.optional()
|
|
@@ -121,7 +121,7 @@ export const createCoderSubcommand = createSubcommand({
|
|
|
121
121
|
// Build the create session request body from flags
|
|
122
122
|
const body: CoderCreateSessionRequest & {
|
|
123
123
|
defaultAgent?: string;
|
|
124
|
-
|
|
124
|
+
enabledAgents?: string[];
|
|
125
125
|
} = {
|
|
126
126
|
task: args.task,
|
|
127
127
|
...(opts?.label && { label: opts.label }),
|
|
@@ -167,10 +167,10 @@ export const createCoderSubcommand = createSubcommand({
|
|
|
167
167
|
.split(',')
|
|
168
168
|
.map((t) => t.trim())
|
|
169
169
|
.filter(Boolean);
|
|
170
|
-
if (opts?.
|
|
171
|
-
body.
|
|
170
|
+
if (opts?.enabledAgents)
|
|
171
|
+
body.enabledAgents = opts.enabledAgents
|
|
172
172
|
.split(',')
|
|
173
|
-
.map((
|
|
173
|
+
.map((name) => name.trim())
|
|
174
174
|
.filter(Boolean);
|
|
175
175
|
if (opts?.savedSkillIds)
|
|
176
176
|
body.savedSkillIds = opts.savedSkillIds
|
package/src/cmd/coder/start.ts
CHANGED
|
@@ -128,6 +128,8 @@ export const startSubcommand = createSubcommand({
|
|
|
128
128
|
},
|
|
129
129
|
async handler(ctx) {
|
|
130
130
|
const { opts, options } = ctx;
|
|
131
|
+
// Keep Pi's interactive install telemetry disabled for Agentuity CLI sessions.
|
|
132
|
+
process.env.PI_TELEMETRY = '0';
|
|
131
133
|
|
|
132
134
|
// Resolve working directory from optional --dir option
|
|
133
135
|
let cwd = process.cwd();
|
|
@@ -388,6 +390,7 @@ export const startSubcommand = createSubcommand({
|
|
|
388
390
|
AGENTUITY_CODER_HUB_URL: hubWsUrl,
|
|
389
391
|
};
|
|
390
392
|
env.AGENTUITY_CODER_API_KEY = ctx.auth.apiKey;
|
|
393
|
+
env.AGENTUITY_ORGID = ctx.orgId;
|
|
391
394
|
|
|
392
395
|
if (opts?.agent) {
|
|
393
396
|
env.AGENTUITY_CODER_AGENT = opts.agent;
|
package/src/cmd/coder/update.ts
CHANGED
|
@@ -54,10 +54,10 @@ export const updateSubcommand = createSubcommand({
|
|
|
54
54
|
loopAutoContinue: z.boolean().optional().describe('Auto-continue loop'),
|
|
55
55
|
loopAllowDetached: z.boolean().optional().describe('Allow detached loop execution'),
|
|
56
56
|
tags: z.string().optional().describe('Comma-separated tags (replaces existing)'),
|
|
57
|
-
|
|
57
|
+
enabledAgents: z
|
|
58
58
|
.string()
|
|
59
59
|
.optional()
|
|
60
|
-
.describe('Comma-separated
|
|
60
|
+
.describe('Comma-separated built-in/custom agents (replaces existing)'),
|
|
61
61
|
}),
|
|
62
62
|
},
|
|
63
63
|
async handler(ctx) {
|
|
@@ -81,10 +81,10 @@ export const updateSubcommand = createSubcommand({
|
|
|
81
81
|
.map((t) => t.trim())
|
|
82
82
|
.filter(Boolean);
|
|
83
83
|
}
|
|
84
|
-
if (opts?.
|
|
85
|
-
body.
|
|
84
|
+
if (opts?.enabledAgents) {
|
|
85
|
+
body.enabledAgents = opts.enabledAgents
|
|
86
86
|
.split(',')
|
|
87
|
-
.map((
|
|
87
|
+
.map((name) => name.trim())
|
|
88
88
|
.filter(Boolean);
|
|
89
89
|
}
|
|
90
90
|
|
|
@@ -105,7 +105,7 @@ export const updateSubcommand = createSubcommand({
|
|
|
105
105
|
|
|
106
106
|
if (Object.keys(body).length === 0) {
|
|
107
107
|
tui.fatal(
|
|
108
|
-
'No update fields provided. Use --label, --visibility, --tags, --agent, --default-agent, --
|
|
108
|
+
'No update fields provided. Use --label, --visibility, --tags, --agent, --default-agent, --enabled-agents, --workflow-mode, or loop options.',
|
|
109
109
|
ErrorCode.VALIDATION_FAILED
|
|
110
110
|
);
|
|
111
111
|
}
|
|
@@ -125,7 +125,7 @@ export const updateSubcommand = createSubcommand({
|
|
|
125
125
|
if (opts?.tags) fields.push(`Tags: ${(body.tags as string[]).join(', ')}`);
|
|
126
126
|
if (opts?.agent) fields.push(`Agent: ${opts.agent}`);
|
|
127
127
|
if (opts?.defaultAgent) fields.push(`Default agent: ${opts.defaultAgent}`);
|
|
128
|
-
if (opts?.
|
|
128
|
+
if (opts?.enabledAgents) fields.push(`Enabled agents: ${opts.enabledAgents}`);
|
|
129
129
|
if (opts?.workflowMode || body.loop) fields.push(`Workflow: ${body.workflowMode}`);
|
|
130
130
|
|
|
131
131
|
for (const f of fields) {
|
|
@@ -1,37 +1,66 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { APIError, ValidationInputError, ValidationOutputError } from '@agentuity/core';
|
|
3
|
+
import {
|
|
4
|
+
CoderClient,
|
|
5
|
+
CoderCreateWorkspaceRequestSchema,
|
|
6
|
+
type CoderCreateWorkspaceRequest,
|
|
7
|
+
} from '@agentuity/core/coder';
|
|
4
8
|
import { createSubcommand } from '../../../types';
|
|
5
9
|
import * as tui from '../../../tui';
|
|
6
10
|
import { getCommand } from '../../../command-prefix';
|
|
7
11
|
import { ErrorCode } from '../../../errors';
|
|
8
12
|
import { resolveGitHubRepo } from '../resolve-repo';
|
|
9
13
|
|
|
14
|
+
const EMPTY_WORKSPACE_ERROR =
|
|
15
|
+
'A workspace needs at least one repo, saved skill, skill bucket, or agent';
|
|
16
|
+
|
|
17
|
+
function hasWorkspaceSelections(input: CoderCreateWorkspaceRequest): boolean {
|
|
18
|
+
return (
|
|
19
|
+
(input.repos?.length ?? 0) > 0 ||
|
|
20
|
+
(input.savedSkillIds?.length ?? 0) > 0 ||
|
|
21
|
+
(input.skillBucketIds?.length ?? 0) > 0 ||
|
|
22
|
+
(input.enabledAgents?.length ?? 0) > 0
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function formatWorkspaceValidationMessage(issues: Array<{ message: string }>): string {
|
|
27
|
+
const messages = [...new Set(issues.map((issue) => issue.message).filter(Boolean))];
|
|
28
|
+
if (messages.length === 0) {
|
|
29
|
+
return 'Invalid workspace configuration';
|
|
30
|
+
}
|
|
31
|
+
if (messages.includes(EMPTY_WORKSPACE_ERROR)) {
|
|
32
|
+
return `${EMPTY_WORKSPACE_ERROR}. Use --repo or --enabled-agents.`;
|
|
33
|
+
}
|
|
34
|
+
return messages.join('; ');
|
|
35
|
+
}
|
|
36
|
+
|
|
10
37
|
export const createWorkspaceSubcommand = createSubcommand({
|
|
11
38
|
name: 'create',
|
|
12
39
|
aliases: ['new', 'add'],
|
|
13
|
-
description: 'Create a new Coder workspace',
|
|
40
|
+
description: 'Create a new Coder workspace with at least one repo or agent',
|
|
14
41
|
tags: ['mutating', 'requires-auth'],
|
|
15
42
|
requires: { auth: true, org: true },
|
|
16
43
|
examples: [
|
|
17
|
-
{
|
|
18
|
-
command: getCommand('coder workspace create "My Workspace"'),
|
|
19
|
-
description: 'Create a workspace with a name',
|
|
20
|
-
},
|
|
21
44
|
{
|
|
22
45
|
command: getCommand(
|
|
23
|
-
'coder workspace create "My Workspace" --
|
|
46
|
+
'coder workspace create "My Workspace" --repo https://github.com/org/repo --repo-branch main'
|
|
24
47
|
),
|
|
25
|
-
description: 'Create
|
|
48
|
+
description: 'Create a workspace with a repository',
|
|
26
49
|
},
|
|
27
50
|
{
|
|
28
51
|
command: getCommand(
|
|
29
|
-
'coder workspace create "My Workspace" --
|
|
52
|
+
'coder workspace create "My Workspace" --enabled-agents code-review --description "For frontend work" --scope org'
|
|
30
53
|
),
|
|
31
|
-
description: 'Create
|
|
54
|
+
description: 'Create an org-scoped workspace with description and agents',
|
|
32
55
|
},
|
|
33
56
|
{
|
|
34
|
-
command: getCommand('coder workspace create "My Workspace" --
|
|
57
|
+
command: getCommand('coder workspace create "My Workspace" --enabled-agents code-review'),
|
|
58
|
+
description: 'Create a workspace with an agent roster',
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
command: getCommand(
|
|
62
|
+
'coder workspace create "My Workspace" --enabled-agents code-review --json'
|
|
63
|
+
),
|
|
35
64
|
description: 'Create a workspace and return JSON output',
|
|
36
65
|
},
|
|
37
66
|
],
|
|
@@ -45,10 +74,10 @@ export const createWorkspaceSubcommand = createSubcommand({
|
|
|
45
74
|
scope: z.string().optional().describe('Workspace scope: user or org'),
|
|
46
75
|
repo: z.string().optional().describe('Repository URL to add'),
|
|
47
76
|
repoBranch: z.string().optional().describe('Branch for the repository'),
|
|
48
|
-
|
|
77
|
+
enabledAgents: z
|
|
49
78
|
.string()
|
|
50
79
|
.optional()
|
|
51
|
-
.describe('Comma-separated
|
|
80
|
+
.describe('Comma-separated built-in/custom agents to include'),
|
|
52
81
|
}),
|
|
53
82
|
},
|
|
54
83
|
async handler(ctx) {
|
|
@@ -59,9 +88,7 @@ export const createWorkspaceSubcommand = createSubcommand({
|
|
|
59
88
|
orgId: ctx.orgId,
|
|
60
89
|
});
|
|
61
90
|
|
|
62
|
-
const body: CoderCreateWorkspaceRequest
|
|
63
|
-
agentSlugs?: string[];
|
|
64
|
-
} = {
|
|
91
|
+
const body: CoderCreateWorkspaceRequest = {
|
|
65
92
|
name: args.name,
|
|
66
93
|
...(opts?.description && { description: opts.description }),
|
|
67
94
|
...(opts?.scope && { scope: opts.scope as 'user' | 'org' }),
|
|
@@ -78,17 +105,35 @@ export const createWorkspaceSubcommand = createSubcommand({
|
|
|
78
105
|
return;
|
|
79
106
|
}
|
|
80
107
|
}
|
|
81
|
-
if (opts?.
|
|
82
|
-
body.
|
|
108
|
+
if (opts?.enabledAgents) {
|
|
109
|
+
body.enabledAgents = opts.enabledAgents
|
|
83
110
|
.split(',')
|
|
84
|
-
.map((
|
|
111
|
+
.map((name) => name.trim())
|
|
85
112
|
.filter(Boolean);
|
|
86
113
|
}
|
|
114
|
+
if (!hasWorkspaceSelections(body)) {
|
|
115
|
+
tui.fatal(
|
|
116
|
+
`Failed to create workspace: ${EMPTY_WORKSPACE_ERROR}. Use --repo or --enabled-agents.`,
|
|
117
|
+
ErrorCode.VALIDATION_FAILED
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const validationResult = CoderCreateWorkspaceRequestSchema.safeParse(body);
|
|
122
|
+
if (!validationResult.success) {
|
|
123
|
+
ctx.logger.trace(
|
|
124
|
+
'Validation issues: %s',
|
|
125
|
+
JSON.stringify(validationResult.error.issues, null, 2)
|
|
126
|
+
);
|
|
127
|
+
tui.fatal(
|
|
128
|
+
`Failed to create workspace: ${formatWorkspaceValidationMessage(validationResult.error.issues)}`,
|
|
129
|
+
ErrorCode.VALIDATION_FAILED
|
|
130
|
+
);
|
|
131
|
+
}
|
|
87
132
|
|
|
88
133
|
try {
|
|
89
|
-
const created = await client.createWorkspace(
|
|
90
|
-
const
|
|
91
|
-
? created.
|
|
134
|
+
const created = await client.createWorkspace(validationResult.data);
|
|
135
|
+
const createdEnabledAgents = Array.isArray(created.enabledAgents)
|
|
136
|
+
? created.enabledAgents.filter((name): name is string => typeof name === 'string')
|
|
92
137
|
: [];
|
|
93
138
|
|
|
94
139
|
if (options.json) {
|
|
@@ -104,15 +149,21 @@ export const createWorkspaceSubcommand = createSubcommand({
|
|
|
104
149
|
tui.output(` Scope: ${created.scope}`);
|
|
105
150
|
tui.output(` Repos: ${created.repoCount}`);
|
|
106
151
|
tui.output(` Selections: ${created.selectionCount}`);
|
|
107
|
-
if (
|
|
108
|
-
tui.output(` Agents: ${
|
|
152
|
+
if (createdEnabledAgents.length > 0) {
|
|
153
|
+
tui.output(` Agents: ${createdEnabledAgents.join(', ')}`);
|
|
109
154
|
}
|
|
110
155
|
|
|
111
156
|
return created;
|
|
112
157
|
} catch (err) {
|
|
113
|
-
if (err instanceof ValidationOutputError) {
|
|
158
|
+
if (err instanceof ValidationInputError || err instanceof ValidationOutputError) {
|
|
114
159
|
ctx.logger.trace('Validation response URL: %s', err.url ?? 'unknown');
|
|
115
160
|
ctx.logger.trace('Validation issues: %s', JSON.stringify(err.issues, null, 2));
|
|
161
|
+
tui.fatal(
|
|
162
|
+
`Failed to create workspace: ${formatWorkspaceValidationMessage(err.issues)}`,
|
|
163
|
+
ErrorCode.VALIDATION_FAILED
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
if (err instanceof APIError && err.status >= 400 && err.status < 500) {
|
|
116
167
|
tui.fatal(`Failed to create workspace: ${err.message}`, ErrorCode.VALIDATION_FAILED);
|
|
117
168
|
}
|
|
118
169
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -17,7 +17,9 @@ export const workspaceCommand = createCommand({
|
|
|
17
17
|
description: 'List all workspaces',
|
|
18
18
|
},
|
|
19
19
|
{
|
|
20
|
-
command: getCommand(
|
|
20
|
+
command: getCommand(
|
|
21
|
+
'coder workspace create "My Workspace" --repo https://github.com/org/repo'
|
|
22
|
+
),
|
|
21
23
|
description: 'Create a new workspace',
|
|
22
24
|
},
|
|
23
25
|
{
|
package/src/cmd/dev/dev-lock.ts
CHANGED
|
@@ -71,35 +71,69 @@ function pidExists(pid: number): boolean {
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
/**
|
|
74
|
-
*
|
|
74
|
+
* Send a signal to a process group (negative PID) with fallback to direct PID.
|
|
75
|
+
* Returns true if the signal was sent successfully.
|
|
75
76
|
*/
|
|
76
|
-
|
|
77
|
-
|
|
77
|
+
function killProcessTree(pid: number, signal: NodeJS.Signals, logger: LoggerLike): boolean {
|
|
78
|
+
// Safety: never send signals to PID 0 (own process group), PID 1 (init/systemd),
|
|
79
|
+
// or other dangerously low PIDs. process.kill(-1) would signal every process
|
|
80
|
+
// the user owns, which would crash the entire desktop session.
|
|
81
|
+
if (pid <= 1) {
|
|
82
|
+
logger.debug('Refusing to kill dangerous pid %d, skipping process tree kill', pid);
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
78
85
|
|
|
86
|
+
// Try process group kill first (kills all children too)
|
|
79
87
|
try {
|
|
80
|
-
process.kill(pid,
|
|
81
|
-
logger.debug('Sent
|
|
88
|
+
process.kill(-pid, signal);
|
|
89
|
+
logger.debug('Sent %s to process group -%d', signal, pid);
|
|
90
|
+
return true;
|
|
82
91
|
} catch (err: unknown) {
|
|
83
92
|
const error = err as NodeJS.ErrnoException;
|
|
84
|
-
if (error.code
|
|
85
|
-
|
|
93
|
+
if (error.code !== 'ESRCH') {
|
|
94
|
+
logger.debug(
|
|
95
|
+
'Process group kill failed for pid %d (%s), falling back to direct',
|
|
96
|
+
pid,
|
|
97
|
+
error.code
|
|
98
|
+
);
|
|
99
|
+
}
|
|
86
100
|
}
|
|
87
101
|
|
|
88
|
-
//
|
|
89
|
-
await new Promise((r) => setTimeout(r, 500));
|
|
90
|
-
|
|
91
|
-
if (!pidExists(pid)) return;
|
|
92
|
-
|
|
93
|
-
// Force kill
|
|
102
|
+
// Fall back to direct PID kill
|
|
94
103
|
try {
|
|
95
|
-
process.kill(pid,
|
|
96
|
-
logger.debug('Sent
|
|
104
|
+
process.kill(pid, signal);
|
|
105
|
+
logger.debug('Sent %s to pid %d (direct)', signal, pid);
|
|
106
|
+
return true;
|
|
97
107
|
} catch (err: unknown) {
|
|
98
108
|
const error = err as NodeJS.ErrnoException;
|
|
99
109
|
if (error.code !== 'ESRCH') {
|
|
100
|
-
logger.debug('
|
|
110
|
+
logger.debug('Direct kill failed for pid %d: %s', pid, error.code);
|
|
101
111
|
}
|
|
112
|
+
return false;
|
|
102
113
|
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Kill a process by PID with SIGTERM, then SIGKILL if still alive.
|
|
118
|
+
* Targets the entire process tree to prevent orphaned child processes.
|
|
119
|
+
*/
|
|
120
|
+
async function killPid(pid: number, logger: LoggerLike): Promise<void> {
|
|
121
|
+
if (!pidExists(pid)) return;
|
|
122
|
+
|
|
123
|
+
// Send SIGTERM to process tree
|
|
124
|
+
const sent = killProcessTree(pid, 'SIGTERM', logger);
|
|
125
|
+
if (!sent) return;
|
|
126
|
+
|
|
127
|
+
// Give it a moment to exit gracefully
|
|
128
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
129
|
+
|
|
130
|
+
// Always attempt SIGKILL on the process tree even if the leader has exited.
|
|
131
|
+
// On Unix, process groups persist after the leader exits and signaling via
|
|
132
|
+
// negative PGID still reaches remaining members. killProcessTree() handles
|
|
133
|
+
// ESRCH gracefully if the group no longer exists.
|
|
134
|
+
|
|
135
|
+
// Force kill the entire process tree
|
|
136
|
+
killProcessTree(pid, 'SIGKILL', logger);
|
|
103
137
|
|
|
104
138
|
// Wait for process to fully terminate
|
|
105
139
|
await new Promise((r) => setTimeout(r, 100));
|