@agentuity/cli 2.0.6 → 2.0.8
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/README.md +11 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +4 -2
- package/dist/cli.js.map +1 -1
- package/dist/cmd/build/vite/route-discovery.d.ts.map +1 -1
- package/dist/cmd/build/vite/route-discovery.js +6 -0
- package/dist/cmd/build/vite/route-discovery.js.map +1 -1
- package/dist/cmd/cloud/sandbox/fs/rm.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/fs/rm.js +9 -3
- 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 +9 -3
- package/dist/cmd/cloud/sandbox/fs/rmdir.js.map +1 -1
- package/dist/cmd/cloud/task/close.d.ts +3 -0
- package/dist/cmd/cloud/task/close.d.ts.map +1 -0
- package/dist/cmd/cloud/task/close.js +286 -0
- package/dist/cmd/cloud/task/close.js.map +1 -0
- package/dist/cmd/cloud/task/delete.d.ts +1 -5
- package/dist/cmd/cloud/task/delete.d.ts.map +1 -1
- package/dist/cmd/cloud/task/delete.js +15 -38
- package/dist/cmd/cloud/task/delete.js.map +1 -1
- package/dist/cmd/cloud/task/index.d.ts.map +1 -1
- package/dist/cmd/cloud/task/index.js +10 -0
- package/dist/cmd/cloud/task/index.js.map +1 -1
- package/dist/cmd/cloud/task/list.d.ts.map +1 -1
- package/dist/cmd/cloud/task/list.js +97 -3
- package/dist/cmd/cloud/task/list.js.map +1 -1
- package/dist/cmd/cloud/task/util.d.ts +10 -0
- package/dist/cmd/cloud/task/util.d.ts.map +1 -1
- package/dist/cmd/cloud/task/util.js +47 -3
- package/dist/cmd/cloud/task/util.js.map +1 -1
- package/dist/cmd/coder/archive.d.ts +2 -0
- package/dist/cmd/coder/archive.d.ts.map +1 -0
- package/dist/cmd/coder/archive.js +57 -0
- package/dist/cmd/coder/archive.js.map +1 -0
- package/dist/cmd/coder/create.d.ts +2 -0
- package/dist/cmd/coder/create.d.ts.map +1 -0
- package/dist/cmd/coder/create.js +245 -0
- package/dist/cmd/coder/create.js.map +1 -0
- package/dist/cmd/coder/delete.d.ts +2 -0
- package/dist/cmd/coder/delete.d.ts.map +1 -0
- package/dist/cmd/coder/delete.js +64 -0
- package/dist/cmd/coder/delete.js.map +1 -0
- package/dist/cmd/coder/events.d.ts +2 -0
- package/dist/cmd/coder/events.d.ts.map +1 -0
- package/dist/cmd/coder/events.js +99 -0
- package/dist/cmd/coder/events.js.map +1 -0
- package/dist/cmd/coder/extension-path.d.ts +8 -0
- package/dist/cmd/coder/extension-path.d.ts.map +1 -0
- package/dist/cmd/coder/extension-path.js +59 -0
- package/dist/cmd/coder/extension-path.js.map +1 -0
- package/dist/cmd/coder/get.d.ts +2 -0
- package/dist/cmd/coder/get.d.ts.map +1 -0
- package/dist/cmd/coder/{inspect.js → get.js} +37 -33
- package/dist/cmd/coder/get.js.map +1 -0
- package/dist/cmd/coder/index.d.ts.map +1 -1
- package/dist/cmd/coder/index.js +54 -4
- package/dist/cmd/coder/index.js.map +1 -1
- package/dist/cmd/coder/list.d.ts.map +1 -1
- package/dist/cmd/coder/list.js +25 -34
- package/dist/cmd/coder/list.js.map +1 -1
- package/dist/cmd/coder/loop.d.ts +2 -0
- package/dist/cmd/coder/loop.d.ts.map +1 -0
- package/dist/cmd/coder/loop.js +78 -0
- package/dist/cmd/coder/loop.js.map +1 -0
- package/dist/cmd/coder/participants.d.ts +2 -0
- package/dist/cmd/coder/participants.d.ts.map +1 -0
- package/dist/cmd/coder/participants.js +93 -0
- package/dist/cmd/coder/participants.js.map +1 -0
- package/dist/cmd/coder/replay.d.ts +2 -0
- package/dist/cmd/coder/replay.d.ts.map +1 -0
- package/dist/cmd/coder/replay.js +53 -0
- package/dist/cmd/coder/replay.js.map +1 -0
- package/dist/cmd/coder/resolve-repo.d.ts +27 -0
- package/dist/cmd/coder/resolve-repo.d.ts.map +1 -0
- package/dist/cmd/coder/resolve-repo.js +97 -0
- package/dist/cmd/coder/resolve-repo.js.map +1 -0
- package/dist/cmd/coder/skill/buckets.d.ts +2 -0
- package/dist/cmd/coder/skill/buckets.d.ts.map +1 -0
- package/dist/cmd/coder/skill/buckets.js +174 -0
- package/dist/cmd/coder/skill/buckets.js.map +1 -0
- package/dist/cmd/coder/skill/delete.d.ts +2 -0
- package/dist/cmd/coder/skill/delete.d.ts.map +1 -0
- package/dist/cmd/coder/skill/delete.js +64 -0
- package/dist/cmd/coder/skill/delete.js.map +1 -0
- package/dist/cmd/coder/skill/index.d.ts +2 -0
- package/dist/cmd/coder/skill/index.d.ts.map +1 -0
- package/dist/cmd/coder/skill/index.js +33 -0
- package/dist/cmd/coder/skill/index.js.map +1 -0
- package/dist/cmd/coder/skill/list.d.ts +2 -0
- package/dist/cmd/coder/skill/list.d.ts.map +1 -0
- package/dist/cmd/coder/skill/list.js +93 -0
- package/dist/cmd/coder/skill/list.js.map +1 -0
- package/dist/cmd/coder/skill/save.d.ts +2 -0
- package/dist/cmd/coder/skill/save.d.ts.map +1 -0
- package/dist/cmd/coder/skill/save.js +77 -0
- package/dist/cmd/coder/skill/save.js.map +1 -0
- package/dist/cmd/coder/start.d.ts.map +1 -1
- package/dist/cmd/coder/start.js +88 -117
- package/dist/cmd/coder/start.js.map +1 -1
- package/dist/cmd/coder/tui-init.d.ts +4 -1
- package/dist/cmd/coder/tui-init.d.ts.map +1 -1
- package/dist/cmd/coder/tui-init.js +9 -3
- package/dist/cmd/coder/tui-init.js.map +1 -1
- package/dist/cmd/coder/update.d.ts +2 -0
- package/dist/cmd/coder/update.d.ts.map +1 -0
- package/dist/cmd/coder/update.js +126 -0
- package/dist/cmd/coder/update.js.map +1 -0
- package/dist/cmd/coder/users.d.ts +2 -0
- package/dist/cmd/coder/users.d.ts.map +1 -0
- package/dist/cmd/coder/users.js +97 -0
- package/dist/cmd/coder/users.js.map +1 -0
- package/dist/cmd/coder/workspace/create.d.ts +2 -0
- package/dist/cmd/coder/workspace/create.d.ts.map +1 -0
- package/dist/cmd/coder/workspace/create.js +97 -0
- package/dist/cmd/coder/workspace/create.js.map +1 -0
- package/dist/cmd/coder/workspace/delete.d.ts +2 -0
- package/dist/cmd/coder/workspace/delete.d.ts.map +1 -0
- package/dist/cmd/coder/workspace/delete.js +64 -0
- package/dist/cmd/coder/workspace/delete.js.map +1 -0
- package/dist/cmd/coder/workspace/get.d.ts +2 -0
- package/dist/cmd/coder/workspace/get.d.ts.map +1 -0
- package/dist/cmd/coder/workspace/get.js +109 -0
- package/dist/cmd/coder/workspace/get.js.map +1 -0
- package/dist/cmd/coder/workspace/index.d.ts +2 -0
- package/dist/cmd/coder/workspace/index.d.ts.map +1 -0
- package/dist/cmd/coder/workspace/index.js +38 -0
- package/dist/cmd/coder/workspace/index.js.map +1 -0
- package/dist/cmd/coder/workspace/list.d.ts +2 -0
- package/dist/cmd/coder/workspace/list.d.ts.map +1 -0
- package/dist/cmd/coder/workspace/list.js +93 -0
- package/dist/cmd/coder/workspace/list.js.map +1 -0
- package/dist/cmd/dev/sync.js +5 -5
- package/dist/cmd/dev/sync.js.map +1 -1
- package/dist/coder-hub-url.d.ts +3 -0
- package/dist/coder-hub-url.d.ts.map +1 -0
- package/dist/coder-hub-url.js +32 -0
- package/dist/coder-hub-url.js.map +1 -0
- package/dist/config.d.ts +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +14 -3
- package/dist/config.js.map +1 -1
- package/dist/internal-logger.d.ts +4 -0
- package/dist/internal-logger.d.ts.map +1 -1
- package/dist/internal-logger.js +64 -2
- package/dist/internal-logger.js.map +1 -1
- package/dist/keychain.d.ts +3 -0
- package/dist/keychain.d.ts.map +1 -1
- package/dist/keychain.js +47 -28
- package/dist/keychain.js.map +1 -1
- package/dist/types.d.ts +1 -1
- package/package.json +7 -6
- package/src/cli.ts +4 -2
- package/src/cmd/ai/prompt/agent.md +6 -6
- package/src/cmd/build/vite/route-discovery.ts +8 -0
- package/src/cmd/cloud/sandbox/fs/rm.ts +8 -3
- package/src/cmd/cloud/sandbox/fs/rmdir.ts +8 -3
- package/src/cmd/cloud/task/close.ts +319 -0
- package/src/cmd/cloud/task/delete.ts +15 -43
- package/src/cmd/cloud/task/index.ts +10 -0
- package/src/cmd/cloud/task/list.ts +111 -4
- package/src/cmd/cloud/task/util.ts +59 -5
- package/src/cmd/coder/archive.ts +59 -0
- package/src/cmd/coder/create.ts +268 -0
- package/src/cmd/coder/delete.ts +67 -0
- package/src/cmd/coder/events.ts +106 -0
- package/src/cmd/coder/extension-path.ts +71 -0
- package/src/cmd/coder/{inspect.ts → get.ts} +44 -45
- package/src/cmd/coder/index.ts +54 -4
- package/src/cmd/coder/list.ts +28 -65
- package/src/cmd/coder/loop.ts +85 -0
- package/src/cmd/coder/participants.ts +100 -0
- package/src/cmd/coder/replay.ts +58 -0
- package/src/cmd/coder/resolve-repo.ts +119 -0
- package/src/cmd/coder/skill/buckets.ts +191 -0
- package/src/cmd/coder/skill/delete.ts +67 -0
- package/src/cmd/coder/skill/index.ts +35 -0
- package/src/cmd/coder/skill/list.ts +97 -0
- package/src/cmd/coder/skill/save.ts +84 -0
- package/src/cmd/coder/start.ts +104 -141
- package/src/cmd/coder/tui-init.ts +13 -4
- package/src/cmd/coder/update.ts +128 -0
- package/src/cmd/coder/users.ts +101 -0
- package/src/cmd/coder/workspace/create.ts +104 -0
- package/src/cmd/coder/workspace/delete.ts +70 -0
- package/src/cmd/coder/workspace/get.ts +112 -0
- package/src/cmd/coder/workspace/index.ts +38 -0
- package/src/cmd/coder/workspace/list.ts +101 -0
- package/src/cmd/dev/sync.ts +5 -5
- package/src/coder-hub-url.ts +32 -0
- package/src/config.ts +17 -3
- package/src/internal-logger.ts +83 -2
- package/src/keychain.ts +68 -39
- package/dist/cmd/coder/hub-url.d.ts +0 -36
- package/dist/cmd/coder/hub-url.d.ts.map +0 -1
- package/dist/cmd/coder/hub-url.js +0 -106
- package/dist/cmd/coder/hub-url.js.map +0 -1
- package/dist/cmd/coder/inspect.d.ts +0 -2
- package/dist/cmd/coder/inspect.d.ts.map +0 -1
- package/dist/cmd/coder/inspect.js.map +0 -1
- package/src/cmd/coder/hub-url.ts +0 -111
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import {
|
|
3
|
+
CoderClient,
|
|
4
|
+
CoderSessionArchivedError,
|
|
5
|
+
CoderSessionNotFoundError,
|
|
6
|
+
} from '@agentuity/core/coder';
|
|
7
|
+
import { ValidationOutputError } from '@agentuity/core';
|
|
8
|
+
|
|
2
9
|
import { createSubcommand } from '../../types';
|
|
3
10
|
import * as tui from '../../tui';
|
|
4
11
|
import { getCommand } from '../../command-prefix';
|
|
5
12
|
import { ErrorCode } from '../../errors';
|
|
6
|
-
import { resolveHubUrl, hubFetchHeaders } from './hub-url';
|
|
7
13
|
|
|
8
14
|
function formatRelativeTime(isoDate: string): string {
|
|
9
|
-
const
|
|
15
|
+
const parsed = new Date(isoDate).getTime();
|
|
16
|
+
if (Number.isNaN(parsed)) return 'unknown';
|
|
17
|
+
const diffMs = Math.max(0, Date.now() - parsed);
|
|
10
18
|
const seconds = Math.floor(diffMs / 1000);
|
|
11
19
|
if (seconds < 60) return `${seconds}s ago`;
|
|
12
20
|
const minutes = Math.floor(seconds / 60);
|
|
@@ -28,17 +36,19 @@ function formatDuration(ms: number): string {
|
|
|
28
36
|
return `${hours}h ${remainMin}m`;
|
|
29
37
|
}
|
|
30
38
|
|
|
31
|
-
export const
|
|
32
|
-
name: '
|
|
39
|
+
export const getSubcommand = createSubcommand({
|
|
40
|
+
name: 'get',
|
|
41
|
+
aliases: ['show', 'inspect'],
|
|
33
42
|
description: 'Show detailed information about a Coder Hub session',
|
|
34
43
|
tags: ['read-only', 'fast', 'requires-auth'],
|
|
44
|
+
requires: { auth: true, org: true },
|
|
35
45
|
examples: [
|
|
36
46
|
{
|
|
37
|
-
command: getCommand('coder
|
|
38
|
-
description: '
|
|
47
|
+
command: getCommand('coder get codesess_abc123'),
|
|
48
|
+
description: 'Get a session by ID',
|
|
39
49
|
},
|
|
40
50
|
{
|
|
41
|
-
command: getCommand('coder
|
|
51
|
+
command: getCommand('coder get codesess_abc123 --json'),
|
|
42
52
|
description: 'Get session details as JSON',
|
|
43
53
|
},
|
|
44
54
|
],
|
|
@@ -48,21 +58,17 @@ export const inspectSubcommand = createSubcommand({
|
|
|
48
58
|
session_id: z.string().describe('Coder session ID to inspect'),
|
|
49
59
|
}),
|
|
50
60
|
options: z.object({
|
|
51
|
-
|
|
61
|
+
url: z.string().optional().describe('Coder API URL override'),
|
|
52
62
|
}),
|
|
53
63
|
},
|
|
54
64
|
async handler(ctx) {
|
|
55
65
|
const { args, options, opts } = ctx;
|
|
56
66
|
const sessionId = args.session_id;
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
ErrorCode.NETWORK_ERROR
|
|
63
|
-
);
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
67
|
+
const client = new CoderClient({
|
|
68
|
+
apiKey: ctx.auth.apiKey,
|
|
69
|
+
url: opts?.url,
|
|
70
|
+
orgId: ctx.orgId,
|
|
71
|
+
});
|
|
66
72
|
|
|
67
73
|
let data: {
|
|
68
74
|
sessionId: string;
|
|
@@ -70,18 +76,18 @@ export const inspectSubcommand = createSubcommand({
|
|
|
70
76
|
status: string;
|
|
71
77
|
createdAt: string;
|
|
72
78
|
mode: string;
|
|
73
|
-
context
|
|
79
|
+
context?: {
|
|
74
80
|
branch?: string;
|
|
75
81
|
workingDirectory?: string;
|
|
76
82
|
};
|
|
77
|
-
participants
|
|
83
|
+
participants?: Array<{
|
|
78
84
|
id: string;
|
|
79
85
|
role: string;
|
|
80
86
|
transport: string;
|
|
81
87
|
connectedAt: string;
|
|
82
88
|
idle: boolean;
|
|
83
89
|
}>;
|
|
84
|
-
tasks
|
|
90
|
+
tasks?: Array<{
|
|
85
91
|
taskId: string;
|
|
86
92
|
agent: string;
|
|
87
93
|
status: string;
|
|
@@ -90,7 +96,7 @@ export const inspectSubcommand = createSubcommand({
|
|
|
90
96
|
startedAt: string;
|
|
91
97
|
completedAt?: string;
|
|
92
98
|
}>;
|
|
93
|
-
agentActivity
|
|
99
|
+
agentActivity?: Record<
|
|
94
100
|
string,
|
|
95
101
|
{
|
|
96
102
|
name: string;
|
|
@@ -103,32 +109,23 @@ export const inspectSubcommand = createSubcommand({
|
|
|
103
109
|
};
|
|
104
110
|
|
|
105
111
|
try {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
});
|
|
110
|
-
if (resp.status === 404) {
|
|
112
|
+
data = (await client.getSession(sessionId)) as unknown as typeof data;
|
|
113
|
+
} catch (err) {
|
|
114
|
+
if (err instanceof CoderSessionNotFoundError) {
|
|
111
115
|
tui.fatal(`Session not found: ${sessionId}`, ErrorCode.RESOURCE_NOT_FOUND);
|
|
112
116
|
return;
|
|
113
117
|
}
|
|
114
|
-
if (
|
|
118
|
+
if (err instanceof CoderSessionArchivedError) {
|
|
115
119
|
tui.fatal(`Session has shut down: ${sessionId}`, ErrorCode.RESOURCE_NOT_FOUND);
|
|
116
120
|
return;
|
|
117
121
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
);
|
|
123
|
-
return;
|
|
122
|
+
|
|
123
|
+
if (err instanceof ValidationOutputError) {
|
|
124
|
+
ctx.logger.trace('Validation response URL: %s', err.url ?? 'unknown');
|
|
125
|
+
ctx.logger.trace('Validation issues: %s', JSON.stringify(err.issues, null, 2));
|
|
124
126
|
}
|
|
125
|
-
data = (await resp.json()) as typeof data;
|
|
126
|
-
} catch (err) {
|
|
127
127
|
const msg = err instanceof Error ? err.message : String(err);
|
|
128
|
-
tui.fatal(
|
|
129
|
-
`Could not connect to Coder Hub at ${hubUrl}: ${msg}\n\nSet AGENTUITY_CODER_HUB_URL or start the Hub with: bun run dev`,
|
|
130
|
-
ErrorCode.NETWORK_ERROR
|
|
131
|
-
);
|
|
128
|
+
tui.fatal(`Failed to inspect Coder session ${sessionId}: ${msg}`, ErrorCode.NETWORK_ERROR);
|
|
132
129
|
return;
|
|
133
130
|
}
|
|
134
131
|
|
|
@@ -141,17 +138,18 @@ export const inspectSubcommand = createSubcommand({
|
|
|
141
138
|
console.log();
|
|
142
139
|
console.log(` Session: ${label} (${data.sessionId})`);
|
|
143
140
|
const parts = [`Status: ${data.status}`, `Mode: ${data.mode}`];
|
|
144
|
-
if (data.context
|
|
141
|
+
if (data.context?.branch) parts.push(`Branch: ${data.context.branch}`);
|
|
145
142
|
console.log(` ${parts.join(' | ')}`);
|
|
146
143
|
console.log(` Created: ${data.createdAt}`);
|
|
147
144
|
|
|
148
145
|
// Participants
|
|
149
146
|
console.log();
|
|
150
147
|
console.log(' Participants:');
|
|
151
|
-
|
|
148
|
+
const participants = data.participants ?? [];
|
|
149
|
+
if (participants.length === 0) {
|
|
152
150
|
console.log(' (none)');
|
|
153
151
|
} else {
|
|
154
|
-
for (const p of
|
|
152
|
+
for (const p of participants) {
|
|
155
153
|
const idle = p.idle ? ' (idle)' : '';
|
|
156
154
|
const connected = p.connectedAt
|
|
157
155
|
? ` connected ${formatRelativeTime(p.connectedAt)}`
|
|
@@ -163,10 +161,11 @@ export const inspectSubcommand = createSubcommand({
|
|
|
163
161
|
}
|
|
164
162
|
|
|
165
163
|
// Tasks
|
|
166
|
-
|
|
164
|
+
const tasks = data.tasks ?? [];
|
|
165
|
+
if (tasks.length > 0) {
|
|
167
166
|
console.log();
|
|
168
167
|
console.log(' Tasks:');
|
|
169
|
-
for (const t of
|
|
168
|
+
for (const t of tasks) {
|
|
170
169
|
const dur = t.duration ? formatDuration(t.duration) : '-';
|
|
171
170
|
const prompt = t.prompt.length > 40 ? t.prompt.slice(0, 37) + '...' : t.prompt;
|
|
172
171
|
console.log(
|
|
@@ -176,7 +175,7 @@ export const inspectSubcommand = createSubcommand({
|
|
|
176
175
|
}
|
|
177
176
|
|
|
178
177
|
// Agent Activity
|
|
179
|
-
const agents = Object.values(data.agentActivity);
|
|
178
|
+
const agents = Object.values(data.agentActivity ?? {});
|
|
180
179
|
if (agents.length > 0) {
|
|
181
180
|
console.log();
|
|
182
181
|
console.log(' Agent Activity:');
|
package/src/cmd/coder/index.ts
CHANGED
|
@@ -1,7 +1,18 @@
|
|
|
1
1
|
import { createCommand } from '../../types';
|
|
2
2
|
import { listSubcommand } from './list';
|
|
3
|
-
import {
|
|
3
|
+
import { getSubcommand } from './get';
|
|
4
4
|
import { startSubcommand } from './start';
|
|
5
|
+
import { createCoderSubcommand } from './create';
|
|
6
|
+
import { deleteSubcommand } from './delete';
|
|
7
|
+
import { archiveSubcommand } from './archive';
|
|
8
|
+
import { updateSubcommand } from './update';
|
|
9
|
+
import { usersSubcommand } from './users';
|
|
10
|
+
import { loopSubcommand } from './loop';
|
|
11
|
+
import { replaySubcommand } from './replay';
|
|
12
|
+
import { participantsSubcommand } from './participants';
|
|
13
|
+
import { eventsSubcommand } from './events';
|
|
14
|
+
import { workspaceCommand } from './workspace';
|
|
15
|
+
import { skillCommand } from './skill';
|
|
5
16
|
import { getCommand } from '../../command-prefix';
|
|
6
17
|
|
|
7
18
|
export const command = createCommand({
|
|
@@ -13,15 +24,54 @@ export const command = createCommand({
|
|
|
13
24
|
command: getCommand('coder start'),
|
|
14
25
|
description: 'Start a Pi session connected to the Coder Hub',
|
|
15
26
|
},
|
|
27
|
+
{
|
|
28
|
+
command: getCommand('coder create "Build a REST API"'),
|
|
29
|
+
description: 'Create a new Coder session with a task',
|
|
30
|
+
},
|
|
16
31
|
{
|
|
17
32
|
command: getCommand('coder ls'),
|
|
18
33
|
description: 'List all active Coder Hub sessions',
|
|
19
34
|
},
|
|
20
35
|
{
|
|
21
|
-
command: getCommand('coder
|
|
36
|
+
command: getCommand('coder get <session-id>'),
|
|
22
37
|
description: 'Show detailed session information',
|
|
23
38
|
},
|
|
39
|
+
{
|
|
40
|
+
command: getCommand('coder users'),
|
|
41
|
+
description: 'List known Coder Hub users',
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
command: getCommand('coder loop <session-id>'),
|
|
45
|
+
description: 'Get loop state for a session',
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
command: getCommand('coder events <session-id> --limit 100'),
|
|
49
|
+
description: 'Show recent event history for a session',
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
command: getCommand('coder workspace list'),
|
|
53
|
+
description: 'List Coder workspaces',
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
command: getCommand('coder skill list'),
|
|
57
|
+
description: 'List saved skills',
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
subcommands: [
|
|
61
|
+
startSubcommand,
|
|
62
|
+
createCoderSubcommand,
|
|
63
|
+
listSubcommand,
|
|
64
|
+
getSubcommand,
|
|
65
|
+
updateSubcommand,
|
|
66
|
+
deleteSubcommand,
|
|
67
|
+
archiveSubcommand,
|
|
68
|
+
usersSubcommand,
|
|
69
|
+
loopSubcommand,
|
|
70
|
+
replaySubcommand,
|
|
71
|
+
participantsSubcommand,
|
|
72
|
+
eventsSubcommand,
|
|
73
|
+
workspaceCommand,
|
|
74
|
+
skillCommand,
|
|
24
75
|
],
|
|
25
|
-
|
|
26
|
-
optional: { auth: true },
|
|
76
|
+
requires: { auth: true, org: true },
|
|
27
77
|
});
|
package/src/cmd/coder/list.ts
CHANGED
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import {
|
|
3
|
+
CoderClient,
|
|
4
|
+
type CoderSessionListItem,
|
|
5
|
+
CoderSessionListItemSchema,
|
|
6
|
+
} from '@agentuity/core/coder';
|
|
7
|
+
import { ValidationOutputError } from '@agentuity/core';
|
|
2
8
|
import { createSubcommand } from '../../types';
|
|
3
9
|
import * as tui from '../../tui';
|
|
4
10
|
import { getCommand } from '../../command-prefix';
|
|
5
11
|
import { ErrorCode } from '../../errors';
|
|
6
|
-
import { resolveHubUrl, hubFetchHeaders } from './hub-url';
|
|
7
12
|
|
|
8
13
|
function formatRelativeTime(isoDate: string): string {
|
|
9
|
-
const
|
|
14
|
+
const parsed = new Date(isoDate).getTime();
|
|
15
|
+
if (Number.isNaN(parsed)) return 'unknown';
|
|
16
|
+
const diffMs = Math.max(0, Date.now() - parsed);
|
|
10
17
|
const seconds = Math.floor(diffMs / 1000);
|
|
11
18
|
if (seconds < 60) return `${seconds}s ago`;
|
|
12
19
|
const minutes = Math.floor(seconds / 60);
|
|
@@ -17,20 +24,6 @@ function formatRelativeTime(isoDate: string): string {
|
|
|
17
24
|
return `${days}d ago`;
|
|
18
25
|
}
|
|
19
26
|
|
|
20
|
-
const SessionListResponseSchema = z.array(
|
|
21
|
-
z.object({
|
|
22
|
-
sessionId: z.string().describe('Session ID'),
|
|
23
|
-
label: z.string().describe('Human-readable session label'),
|
|
24
|
-
status: z.string().describe('Session status'),
|
|
25
|
-
mode: z.string().describe('Session mode (sandbox or tui)'),
|
|
26
|
-
createdAt: z.string().describe('Creation timestamp'),
|
|
27
|
-
taskCount: z.number().describe('Number of tasks'),
|
|
28
|
-
subAgentCount: z.number().describe('Number of sub-agents'),
|
|
29
|
-
observerCount: z.number().describe('Number of observers'),
|
|
30
|
-
participantCount: z.number().describe('Total participant count'),
|
|
31
|
-
})
|
|
32
|
-
);
|
|
33
|
-
|
|
34
27
|
export const listSubcommand = createSubcommand({
|
|
35
28
|
name: 'list',
|
|
36
29
|
description: 'List active Coder Hub sessions',
|
|
@@ -47,66 +40,34 @@ export const listSubcommand = createSubcommand({
|
|
|
47
40
|
],
|
|
48
41
|
aliases: ['ls'],
|
|
49
42
|
idempotent: true,
|
|
43
|
+
requires: { auth: true, org: true },
|
|
50
44
|
schema: {
|
|
51
45
|
options: z.object({
|
|
52
|
-
|
|
46
|
+
url: z.string().optional().describe('Coder API URL override'),
|
|
53
47
|
}),
|
|
54
|
-
response:
|
|
48
|
+
response: z.array(CoderSessionListItemSchema),
|
|
55
49
|
},
|
|
56
50
|
async handler(ctx) {
|
|
57
51
|
const { options, opts } = ctx;
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
ErrorCode.NETWORK_ERROR
|
|
64
|
-
);
|
|
65
|
-
return [];
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
let data: {
|
|
69
|
-
sessions: {
|
|
70
|
-
websocket: Array<{
|
|
71
|
-
sessionId: string;
|
|
72
|
-
label: string;
|
|
73
|
-
status: string;
|
|
74
|
-
mode: string;
|
|
75
|
-
createdAt: string;
|
|
76
|
-
taskCount: number;
|
|
77
|
-
subAgentCount: number;
|
|
78
|
-
observerCount: number;
|
|
79
|
-
participantCount: number;
|
|
80
|
-
}>;
|
|
81
|
-
sandbox: Array<Record<string, unknown>>;
|
|
82
|
-
};
|
|
83
|
-
total: number;
|
|
84
|
-
};
|
|
52
|
+
const client = new CoderClient({
|
|
53
|
+
apiKey: ctx.auth.apiKey,
|
|
54
|
+
url: opts?.url,
|
|
55
|
+
orgId: ctx.orgId,
|
|
56
|
+
});
|
|
85
57
|
|
|
58
|
+
let sessions: CoderSessionListItem[] = [];
|
|
86
59
|
try {
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
signal: AbortSignal.timeout(10_000),
|
|
90
|
-
});
|
|
91
|
-
if (!resp.ok) {
|
|
92
|
-
tui.fatal(
|
|
93
|
-
`Hub returned ${resp.status}: ${resp.statusText}. Is the Coder Hub running at ${hubUrl}?`,
|
|
94
|
-
ErrorCode.API_ERROR
|
|
95
|
-
);
|
|
96
|
-
return [];
|
|
97
|
-
}
|
|
98
|
-
data = (await resp.json()) as typeof data;
|
|
60
|
+
const response = await client.listSessions();
|
|
61
|
+
sessions = response.sessions;
|
|
99
62
|
} catch (err) {
|
|
63
|
+
if (err instanceof ValidationOutputError) {
|
|
64
|
+
ctx.logger.trace('Validation response URL: %s', err.url ?? 'unknown');
|
|
65
|
+
ctx.logger.trace('Validation issues: %s', JSON.stringify(err.issues, null, 2));
|
|
66
|
+
}
|
|
100
67
|
const msg = err instanceof Error ? err.message : String(err);
|
|
101
|
-
tui.fatal(
|
|
102
|
-
`Could not connect to Coder Hub at ${hubUrl}: ${msg}\n\nSet AGENTUITY_CODER_HUB_URL or start the Hub with: bun run dev`,
|
|
103
|
-
ErrorCode.NETWORK_ERROR
|
|
104
|
-
);
|
|
105
|
-
return [];
|
|
68
|
+
tui.fatal(`Failed to list Coder sessions: ${msg}`, ErrorCode.NETWORK_ERROR);
|
|
106
69
|
}
|
|
107
70
|
|
|
108
|
-
const sessions = data.sessions.websocket;
|
|
109
|
-
|
|
110
71
|
if (options.json) {
|
|
111
72
|
return sessions;
|
|
112
73
|
}
|
|
@@ -117,10 +78,11 @@ export const listSubcommand = createSubcommand({
|
|
|
117
78
|
}
|
|
118
79
|
|
|
119
80
|
const tableData = sessions.map((s) => ({
|
|
120
|
-
'Session ID': s.sessionId
|
|
81
|
+
'Session ID': s.sessionId,
|
|
121
82
|
Label: s.label || '-',
|
|
122
83
|
Status: s.status,
|
|
123
84
|
Mode: s.mode,
|
|
85
|
+
Owner: s.owner?.name ?? s.owner?.userId ?? '-',
|
|
124
86
|
Observers: String(s.observerCount),
|
|
125
87
|
Agents: String(s.subAgentCount),
|
|
126
88
|
Tasks: String(s.taskCount),
|
|
@@ -132,6 +94,7 @@ export const listSubcommand = createSubcommand({
|
|
|
132
94
|
{ name: 'Label', alignment: 'left' },
|
|
133
95
|
{ name: 'Status', alignment: 'center' },
|
|
134
96
|
{ name: 'Mode', alignment: 'center' },
|
|
97
|
+
{ name: 'Owner', alignment: 'left' },
|
|
135
98
|
{ name: 'Observers', alignment: 'right' },
|
|
136
99
|
{ name: 'Agents', alignment: 'right' },
|
|
137
100
|
{ name: 'Tasks', alignment: 'right' },
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { CoderClient } from '@agentuity/core/coder';
|
|
3
|
+
import { ValidationOutputError } from '@agentuity/core';
|
|
4
|
+
import { createSubcommand } from '../../types';
|
|
5
|
+
import * as tui from '../../tui';
|
|
6
|
+
import { getCommand } from '../../command-prefix';
|
|
7
|
+
import { ErrorCode } from '../../errors';
|
|
8
|
+
|
|
9
|
+
export const loopSubcommand = createSubcommand({
|
|
10
|
+
name: 'loop',
|
|
11
|
+
description: 'Get loop-mode state for a Coder Hub session',
|
|
12
|
+
tags: ['read-only', 'fast', 'requires-auth'],
|
|
13
|
+
idempotent: true,
|
|
14
|
+
requires: { auth: true, org: true },
|
|
15
|
+
examples: [
|
|
16
|
+
{
|
|
17
|
+
command: getCommand('coder loop codesess_abc123'),
|
|
18
|
+
description: 'Show loop state for a session',
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
command: getCommand('coder loop codesess_abc123 --json'),
|
|
22
|
+
description: 'Get loop state as JSON',
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
schema: {
|
|
26
|
+
args: z.object({
|
|
27
|
+
sessionId: z.string().describe('Session ID to inspect loop state for'),
|
|
28
|
+
}),
|
|
29
|
+
options: z.object({
|
|
30
|
+
url: z.string().optional().describe('Coder API URL override'),
|
|
31
|
+
}),
|
|
32
|
+
},
|
|
33
|
+
async handler(ctx) {
|
|
34
|
+
const { args, opts, options } = ctx;
|
|
35
|
+
const client = new CoderClient({
|
|
36
|
+
apiKey: ctx.auth.apiKey,
|
|
37
|
+
url: opts?.url,
|
|
38
|
+
orgId: ctx.orgId,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
const state = await client.getLoopState(args.sessionId);
|
|
43
|
+
|
|
44
|
+
if (options.json) {
|
|
45
|
+
return state;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const rows: Array<{ Field: string; Value: string }> = [
|
|
49
|
+
{ Field: 'Session ID', Value: state.sessionId },
|
|
50
|
+
{ Field: 'Workflow Mode', Value: state.workflowMode },
|
|
51
|
+
];
|
|
52
|
+
|
|
53
|
+
if (!state.loop) {
|
|
54
|
+
rows.push({ Field: 'Loop Status', Value: 'not active' });
|
|
55
|
+
} else {
|
|
56
|
+
rows.push({ Field: 'Loop Status', Value: state.loop.status });
|
|
57
|
+
rows.push({ Field: 'Iteration', Value: String(state.loop.iteration) });
|
|
58
|
+
rows.push({
|
|
59
|
+
Field: 'Max Iterations',
|
|
60
|
+
Value: String(state.loop.maxIterations ?? '-'),
|
|
61
|
+
});
|
|
62
|
+
rows.push({ Field: 'Goal', Value: state.loop.goal ?? '-' });
|
|
63
|
+
rows.push({ Field: 'Summary', Value: state.loop.summary ?? '-' });
|
|
64
|
+
rows.push({ Field: 'Next Action', Value: state.loop.nextAction ?? '-' });
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
tui.table(rows, [
|
|
68
|
+
{ name: 'Field', alignment: 'left' },
|
|
69
|
+
{ name: 'Value', alignment: 'left' },
|
|
70
|
+
]);
|
|
71
|
+
|
|
72
|
+
return state;
|
|
73
|
+
} catch (err) {
|
|
74
|
+
if (err instanceof ValidationOutputError) {
|
|
75
|
+
ctx.logger.trace('Validation response URL: %s', err.url ?? 'unknown');
|
|
76
|
+
ctx.logger.trace('Validation issues: %s', JSON.stringify(err.issues, null, 2));
|
|
77
|
+
}
|
|
78
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
79
|
+
tui.fatal(
|
|
80
|
+
`Failed to get loop state for ${args.sessionId}: ${msg}`,
|
|
81
|
+
ErrorCode.NETWORK_ERROR
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
});
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { CoderClient } from '@agentuity/core/coder';
|
|
3
|
+
import { ValidationOutputError } from '@agentuity/core';
|
|
4
|
+
import { createSubcommand } from '../../types';
|
|
5
|
+
import * as tui from '../../tui';
|
|
6
|
+
import { getCommand } from '../../command-prefix';
|
|
7
|
+
import { ErrorCode } from '../../errors';
|
|
8
|
+
|
|
9
|
+
function formatRelativeTime(isoDate: string): string {
|
|
10
|
+
const parsed = new Date(isoDate).getTime();
|
|
11
|
+
if (Number.isNaN(parsed)) return 'unknown';
|
|
12
|
+
const diffMs = Math.max(0, Date.now() - parsed);
|
|
13
|
+
const seconds = Math.floor(diffMs / 1000);
|
|
14
|
+
if (seconds < 60) return `${seconds}s ago`;
|
|
15
|
+
const minutes = Math.floor(seconds / 60);
|
|
16
|
+
if (minutes < 60) return `${minutes}m ago`;
|
|
17
|
+
const hours = Math.floor(minutes / 60);
|
|
18
|
+
if (hours < 24) return `${hours}h ago`;
|
|
19
|
+
const days = Math.floor(hours / 24);
|
|
20
|
+
return `${days}d ago`;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const participantsSubcommand = createSubcommand({
|
|
24
|
+
name: 'participants',
|
|
25
|
+
aliases: ['participant', 'members'],
|
|
26
|
+
description: 'List participants for a Coder Hub session',
|
|
27
|
+
tags: ['read-only', 'fast', 'requires-auth'],
|
|
28
|
+
idempotent: true,
|
|
29
|
+
requires: { auth: true, org: true },
|
|
30
|
+
examples: [
|
|
31
|
+
{
|
|
32
|
+
command: getCommand('coder participants codesess_abc123'),
|
|
33
|
+
description: 'List session participants',
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
command: getCommand('coder participants codesess_abc123 --json'),
|
|
37
|
+
description: 'Get session participants as JSON',
|
|
38
|
+
},
|
|
39
|
+
],
|
|
40
|
+
schema: {
|
|
41
|
+
args: z.object({
|
|
42
|
+
sessionId: z.string().describe('Session ID to list participants for'),
|
|
43
|
+
}),
|
|
44
|
+
options: z.object({
|
|
45
|
+
url: z.string().optional().describe('Coder API URL override'),
|
|
46
|
+
}),
|
|
47
|
+
},
|
|
48
|
+
async handler(ctx) {
|
|
49
|
+
const { args, opts, options } = ctx;
|
|
50
|
+
const client = new CoderClient({
|
|
51
|
+
apiKey: ctx.auth.apiKey,
|
|
52
|
+
url: opts?.url,
|
|
53
|
+
orgId: ctx.orgId,
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
try {
|
|
57
|
+
const data = await client.listParticipants(args.sessionId);
|
|
58
|
+
|
|
59
|
+
if (options.json) {
|
|
60
|
+
return data;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (data.participants.length === 0) {
|
|
64
|
+
tui.info(`No participants found for session ${args.sessionId}.`);
|
|
65
|
+
return data;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
tui.table(
|
|
69
|
+
data.participants.map((p) => ({
|
|
70
|
+
ID: p.id,
|
|
71
|
+
Role: p.role,
|
|
72
|
+
'Agent Role': p.agentRole ?? '-',
|
|
73
|
+
Transport: p.transport ?? '-',
|
|
74
|
+
Connected: p.connectedAt ? formatRelativeTime(p.connectedAt) : '-',
|
|
75
|
+
'Last Activity': p.lastActivityAt ? formatRelativeTime(p.lastActivityAt) : '-',
|
|
76
|
+
})),
|
|
77
|
+
[
|
|
78
|
+
{ name: 'ID', alignment: 'left' },
|
|
79
|
+
{ name: 'Role', alignment: 'left' },
|
|
80
|
+
{ name: 'Agent Role', alignment: 'left' },
|
|
81
|
+
{ name: 'Transport', alignment: 'center' },
|
|
82
|
+
{ name: 'Connected', alignment: 'right' },
|
|
83
|
+
{ name: 'Last Activity', alignment: 'right' },
|
|
84
|
+
]
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
return data;
|
|
88
|
+
} catch (err) {
|
|
89
|
+
if (err instanceof ValidationOutputError) {
|
|
90
|
+
ctx.logger.trace('Validation response URL: %s', err.url ?? 'unknown');
|
|
91
|
+
ctx.logger.trace('Validation issues: %s', JSON.stringify(err.issues, null, 2));
|
|
92
|
+
}
|
|
93
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
94
|
+
tui.fatal(
|
|
95
|
+
`Failed to list participants for session ${args.sessionId}: ${msg}`,
|
|
96
|
+
ErrorCode.NETWORK_ERROR
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
});
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { CoderClient } from '@agentuity/core/coder';
|
|
3
|
+
import { ValidationOutputError } from '@agentuity/core';
|
|
4
|
+
import { createSubcommand } from '../../types';
|
|
5
|
+
import * as tui from '../../tui';
|
|
6
|
+
import { getCommand } from '../../command-prefix';
|
|
7
|
+
import { ErrorCode } from '../../errors';
|
|
8
|
+
|
|
9
|
+
export const replaySubcommand = createSubcommand({
|
|
10
|
+
name: 'replay',
|
|
11
|
+
description: 'Get replay data for a Coder Hub session',
|
|
12
|
+
tags: ['read-only', 'requires-auth'],
|
|
13
|
+
idempotent: true,
|
|
14
|
+
requires: { auth: true, org: true },
|
|
15
|
+
examples: [
|
|
16
|
+
{
|
|
17
|
+
command: getCommand('coder replay codesess_abc123 --json'),
|
|
18
|
+
description: 'Get replay data as JSON',
|
|
19
|
+
},
|
|
20
|
+
],
|
|
21
|
+
schema: {
|
|
22
|
+
args: z.object({
|
|
23
|
+
sessionId: z.string().describe('Session ID to get replay data for'),
|
|
24
|
+
}),
|
|
25
|
+
options: z.object({
|
|
26
|
+
url: z.string().optional().describe('Coder API URL override'),
|
|
27
|
+
}),
|
|
28
|
+
},
|
|
29
|
+
async handler(ctx) {
|
|
30
|
+
const { args, opts, options } = ctx;
|
|
31
|
+
const client = new CoderClient({
|
|
32
|
+
apiKey: ctx.auth.apiKey,
|
|
33
|
+
url: opts?.url,
|
|
34
|
+
orgId: ctx.orgId,
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
try {
|
|
38
|
+
const replay = await client.getReplay(args.sessionId);
|
|
39
|
+
|
|
40
|
+
if (!options.json) {
|
|
41
|
+
tui.info('Replay data is shown as JSON because it is a complex payload.');
|
|
42
|
+
tui.output(JSON.stringify(replay, null, 2));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return replay;
|
|
46
|
+
} catch (err) {
|
|
47
|
+
if (err instanceof ValidationOutputError) {
|
|
48
|
+
ctx.logger.trace('Validation response URL: %s', err.url ?? 'unknown');
|
|
49
|
+
ctx.logger.trace('Validation issues: %s', JSON.stringify(err.issues, null, 2));
|
|
50
|
+
}
|
|
51
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
52
|
+
tui.fatal(
|
|
53
|
+
`Failed to get replay for session ${args.sessionId}: ${msg}`,
|
|
54
|
+
ErrorCode.NETWORK_ERROR
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
});
|