@agentuity/cli 0.1.11 → 0.1.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/auth.d.ts.map +1 -1
- package/dist/auth.js +6 -10
- package/dist/auth.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +89 -41
- package/dist/cli.js.map +1 -1
- package/dist/cmd/auth/login.d.ts.map +1 -1
- package/dist/cmd/auth/login.js +49 -5
- package/dist/cmd/auth/login.js.map +1 -1
- package/dist/cmd/build/patch/_util.d.ts.map +1 -1
- package/dist/cmd/build/patch/_util.js +6 -2
- package/dist/cmd/build/patch/_util.js.map +1 -1
- package/dist/cmd/cloud/agent/get.d.ts.map +1 -1
- package/dist/cmd/cloud/agent/get.js +10 -6
- package/dist/cmd/cloud/agent/get.js.map +1 -1
- package/dist/cmd/cloud/db/create.d.ts.map +1 -1
- package/dist/cmd/cloud/db/create.js +14 -3
- package/dist/cmd/cloud/db/create.js.map +1 -1
- package/dist/cmd/cloud/db/get.d.ts.map +1 -1
- package/dist/cmd/cloud/db/get.js +13 -3
- package/dist/cmd/cloud/db/get.js.map +1 -1
- package/dist/cmd/cloud/db/list.d.ts.map +1 -1
- package/dist/cmd/cloud/db/list.js +17 -25
- package/dist/cmd/cloud/db/list.js.map +1 -1
- package/dist/cmd/cloud/deployment/show.d.ts.map +1 -1
- package/dist/cmd/cloud/deployment/show.js +50 -37
- package/dist/cmd/cloud/deployment/show.js.map +1 -1
- package/dist/cmd/cloud/sandbox/create.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/create.js +19 -2
- package/dist/cmd/cloud/sandbox/create.js.map +1 -1
- package/dist/cmd/cloud/sandbox/execution/get.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/execution/get.js +14 -11
- package/dist/cmd/cloud/sandbox/execution/get.js.map +1 -1
- package/dist/cmd/cloud/sandbox/get.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/get.js +48 -39
- package/dist/cmd/cloud/sandbox/get.js.map +1 -1
- package/dist/cmd/cloud/sandbox/list.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/list.js +6 -1
- package/dist/cmd/cloud/sandbox/list.js.map +1 -1
- package/dist/cmd/cloud/sandbox/run.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/run.js +5 -1
- package/dist/cmd/cloud/sandbox/run.js.map +1 -1
- package/dist/cmd/cloud/sandbox/snapshot/build.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/snapshot/build.js +39 -23
- package/dist/cmd/cloud/sandbox/snapshot/build.js.map +1 -1
- package/dist/cmd/cloud/sandbox/snapshot/generate.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/snapshot/generate.js +2 -0
- package/dist/cmd/cloud/sandbox/snapshot/generate.js.map +1 -1
- package/dist/cmd/cloud/sandbox/snapshot/get.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/snapshot/get.js +10 -7
- package/dist/cmd/cloud/sandbox/snapshot/get.js.map +1 -1
- package/dist/cmd/cloud/session/get.d.ts.map +1 -1
- package/dist/cmd/cloud/session/get.js +24 -23
- package/dist/cmd/cloud/session/get.js.map +1 -1
- package/dist/cmd/cloud/session/list.d.ts.map +1 -1
- package/dist/cmd/cloud/session/list.js +7 -2
- package/dist/cmd/cloud/session/list.js.map +1 -1
- package/dist/cmd/cloud/thread/get.d.ts.map +1 -1
- package/dist/cmd/cloud/thread/get.js +11 -8
- package/dist/cmd/cloud/thread/get.js.map +1 -1
- package/dist/cmd/cloud/thread/list.d.ts.map +1 -1
- package/dist/cmd/cloud/thread/list.js +6 -1
- package/dist/cmd/cloud/thread/list.js.map +1 -1
- package/dist/cmd/dev/file-watcher.d.ts.map +1 -1
- package/dist/cmd/dev/file-watcher.js +2 -0
- package/dist/cmd/dev/file-watcher.js.map +1 -1
- package/dist/cmd/dev/index.d.ts.map +1 -1
- package/dist/cmd/dev/index.js +62 -4
- package/dist/cmd/dev/index.js.map +1 -1
- package/dist/cmd/project/template-flow.d.ts.map +1 -1
- package/dist/cmd/project/template-flow.js +15 -1
- package/dist/cmd/project/template-flow.js.map +1 -1
- package/dist/cmd/setup/index.d.ts.map +1 -1
- package/dist/cmd/setup/index.js +40 -3
- package/dist/cmd/setup/index.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +3 -2
- package/dist/config.js.map +1 -1
- package/dist/steps.d.ts.map +1 -1
- package/dist/steps.js +4 -2
- package/dist/steps.js.map +1 -1
- package/dist/tui.d.ts +11 -1
- package/dist/tui.d.ts.map +1 -1
- package/dist/tui.js +47 -12
- package/dist/tui.js.map +1 -1
- package/package.json +6 -6
- package/src/auth.ts +12 -11
- package/src/cli.ts +121 -43
- package/src/cmd/auth/login.ts +57 -5
- package/src/cmd/build/patch/_util.ts +6 -2
- package/src/cmd/cloud/agent/get.ts +14 -6
- package/src/cmd/cloud/db/create.ts +15 -3
- package/src/cmd/cloud/db/get.ts +14 -3
- package/src/cmd/cloud/db/list.ts +16 -26
- package/src/cmd/cloud/deployment/show.ts +53 -47
- package/src/cmd/cloud/sandbox/create.ts +20 -2
- package/src/cmd/cloud/sandbox/execution/get.ts +16 -13
- package/src/cmd/cloud/sandbox/get.ts +48 -38
- package/src/cmd/cloud/sandbox/list.ts +6 -1
- package/src/cmd/cloud/sandbox/run.ts +5 -1
- package/src/cmd/cloud/sandbox/snapshot/build.ts +51 -24
- package/src/cmd/cloud/sandbox/snapshot/generate.ts +2 -0
- package/src/cmd/cloud/sandbox/snapshot/get.ts +11 -7
- package/src/cmd/cloud/session/get.ts +25 -29
- package/src/cmd/cloud/session/list.ts +7 -2
- package/src/cmd/cloud/thread/get.ts +12 -8
- package/src/cmd/cloud/thread/list.ts +6 -1
- package/src/cmd/dev/file-watcher.ts +2 -0
- package/src/cmd/dev/index.ts +76 -4
- package/src/cmd/project/template-flow.ts +15 -1
- package/src/cmd/setup/index.ts +41 -3
- package/src/config.ts +3 -2
- package/src/steps.ts +4 -2
- package/src/tui.ts +61 -12
|
@@ -29,6 +29,7 @@ const SandboxGetResponseSchema = z.object({
|
|
|
29
29
|
dependencies: z.array(z.string()).optional().describe('Apt packages installed'),
|
|
30
30
|
metadata: z.record(z.string(), z.unknown()).optional().describe('User-defined metadata'),
|
|
31
31
|
resources: SandboxResourcesSchema.optional().describe('Resource limits'),
|
|
32
|
+
url: z.string().optional().describe('Public URL for the sandbox (if network port configured)'),
|
|
32
33
|
});
|
|
33
34
|
|
|
34
35
|
export const getSubcommand = createCommand({
|
|
@@ -72,57 +73,65 @@ export const getSubcommand = createCommand({
|
|
|
72
73
|
? tui.colorError
|
|
73
74
|
: tui.colorMuted;
|
|
74
75
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
console.log(`${tui.muted('Runtime:')} ${result.runtimeName}`);
|
|
86
|
-
}
|
|
87
|
-
if (result.region) {
|
|
88
|
-
console.log(`${tui.muted('Region:')} ${result.region}`);
|
|
89
|
-
}
|
|
90
|
-
if (result.snapshotId || result.snapshotTag) {
|
|
91
|
-
const snapshotDisplay = result.snapshotTag
|
|
92
|
-
? `${result.snapshotTag} ${tui.muted('(' + result.snapshotId + ')')}`
|
|
93
|
-
: result.snapshotId;
|
|
94
|
-
console.log(`${tui.muted('Snapshot:')} ${snapshotDisplay}`);
|
|
95
|
-
}
|
|
96
|
-
console.log(`${tui.muted('Executions:')} ${result.executions}`);
|
|
76
|
+
const snapshotDisplay =
|
|
77
|
+
result.snapshotId || result.snapshotTag
|
|
78
|
+
? result.snapshotTag
|
|
79
|
+
? result.snapshotId
|
|
80
|
+
? `${result.snapshotTag} ${tui.muted('(' + result.snapshotId + ')')}`
|
|
81
|
+
: result.snapshotTag
|
|
82
|
+
: result.snapshotId
|
|
83
|
+
: undefined;
|
|
84
|
+
|
|
85
|
+
let streamDisplay: string | undefined;
|
|
97
86
|
if (
|
|
98
87
|
result.stdoutStreamUrl &&
|
|
99
88
|
result.stderrStreamUrl &&
|
|
100
89
|
result.stdoutStreamUrl === result.stderrStreamUrl
|
|
101
90
|
) {
|
|
102
|
-
|
|
103
|
-
} else {
|
|
104
|
-
if (result.stdoutStreamUrl) {
|
|
105
|
-
console.log(`${tui.muted('Stream (stdout):')} ${tui.link(result.stdoutStreamUrl)}`);
|
|
106
|
-
}
|
|
107
|
-
if (result.stderrStreamUrl) {
|
|
108
|
-
console.log(`${tui.muted('Stream (stderr):')} ${tui.link(result.stderrStreamUrl)}`);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
if (result.dependencies && result.dependencies.length > 0) {
|
|
112
|
-
console.log(`${tui.muted('Dependencies:')} ${result.dependencies.join(', ')}`);
|
|
91
|
+
streamDisplay = tui.link(result.stdoutStreamUrl);
|
|
113
92
|
}
|
|
93
|
+
|
|
94
|
+
const resourceParts: string[] = [];
|
|
114
95
|
if (result.resources) {
|
|
115
|
-
const resourceParts: string[] = [];
|
|
116
96
|
if (result.resources.memory) resourceParts.push(`memory=${result.resources.memory}`);
|
|
117
97
|
if (result.resources.cpu) resourceParts.push(`cpu=${result.resources.cpu}`);
|
|
118
98
|
if (result.resources.disk) resourceParts.push(`disk=${result.resources.disk}`);
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const tableData: Record<string, string | number> = {
|
|
102
|
+
Sandbox: tui.bold(result.sandboxId),
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
if (result.name) tableData['Name'] = result.name;
|
|
106
|
+
if (result.description) tableData['Description'] = result.description;
|
|
107
|
+
tableData['Status'] = statusColor(result.status);
|
|
108
|
+
tableData['Created'] = result.createdAt;
|
|
109
|
+
if (result.runtimeName) tableData['Runtime'] = result.runtimeName;
|
|
110
|
+
if (result.region) tableData['Region'] = result.region;
|
|
111
|
+
if (snapshotDisplay) tableData['Snapshot'] = snapshotDisplay;
|
|
112
|
+
tableData['Executions'] = result.executions;
|
|
113
|
+
if (streamDisplay) {
|
|
114
|
+
tableData['Stream'] = streamDisplay;
|
|
115
|
+
} else {
|
|
116
|
+
if (result.stdoutStreamUrl)
|
|
117
|
+
tableData['Stream (stdout)'] = tui.link(result.stdoutStreamUrl);
|
|
118
|
+
if (result.stderrStreamUrl)
|
|
119
|
+
tableData['Stream (stderr)'] = tui.link(result.stderrStreamUrl);
|
|
120
|
+
}
|
|
121
|
+
if (result.dependencies && result.dependencies.length > 0) {
|
|
122
|
+
tableData['Dependencies'] = result.dependencies.join(', ');
|
|
123
|
+
}
|
|
124
|
+
if (resourceParts.length > 0) {
|
|
125
|
+
tableData['Resources'] = resourceParts.join(', ');
|
|
122
126
|
}
|
|
123
127
|
if (result.metadata && Object.keys(result.metadata).length > 0) {
|
|
124
|
-
|
|
128
|
+
tableData['Metadata'] = JSON.stringify(result.metadata);
|
|
125
129
|
}
|
|
130
|
+
if (result.url) {
|
|
131
|
+
tableData['URL'] = tui.link(result.url);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
tui.table([tableData], Object.keys(tableData), { layout: 'vertical', padStart: ' ' });
|
|
126
135
|
}
|
|
127
136
|
|
|
128
137
|
return {
|
|
@@ -142,6 +151,7 @@ export const getSubcommand = createCommand({
|
|
|
142
151
|
dependencies: result.dependencies,
|
|
143
152
|
metadata: result.metadata,
|
|
144
153
|
resources: result.resources,
|
|
154
|
+
url: result.url,
|
|
145
155
|
};
|
|
146
156
|
},
|
|
147
157
|
});
|
|
@@ -59,6 +59,10 @@ export const listSubcommand = createCommand({
|
|
|
59
59
|
command: getCommand('cloud sandbox list --limit 10 --offset 20'),
|
|
60
60
|
description: 'List with pagination',
|
|
61
61
|
},
|
|
62
|
+
{
|
|
63
|
+
command: getCommand('cloud sandbox list --all'),
|
|
64
|
+
description: 'List all sandboxes regardless of project context',
|
|
65
|
+
},
|
|
62
66
|
],
|
|
63
67
|
schema: {
|
|
64
68
|
options: z.object({
|
|
@@ -67,6 +71,7 @@ export const listSubcommand = createCommand({
|
|
|
67
71
|
.optional()
|
|
68
72
|
.describe('Filter by status'),
|
|
69
73
|
projectId: z.string().optional().describe('Filter by project ID'),
|
|
74
|
+
all: z.boolean().optional().describe('List all sandboxes regardless of project context'),
|
|
70
75
|
limit: z.number().optional().describe('Maximum number of results (default: 50, max: 100)'),
|
|
71
76
|
offset: z.number().optional().describe('Pagination offset'),
|
|
72
77
|
}),
|
|
@@ -77,7 +82,7 @@ export const listSubcommand = createCommand({
|
|
|
77
82
|
const { opts, options, auth, project, logger, orgId, config } = ctx;
|
|
78
83
|
const client = await getGlobalCatalystAPIClient(logger, auth, config?.name);
|
|
79
84
|
|
|
80
|
-
const projectId = opts.projectId || project?.projectId;
|
|
85
|
+
const projectId = opts.all ? undefined : opts.projectId || project?.projectId;
|
|
81
86
|
|
|
82
87
|
const result = await sandboxList(client, {
|
|
83
88
|
orgId,
|
|
@@ -20,6 +20,7 @@ export const runSubcommand = createCommand({
|
|
|
20
20
|
description: 'Run a one-shot command in a sandbox (creates, executes, destroys)',
|
|
21
21
|
tags: ['slow', 'requires-auth'],
|
|
22
22
|
requires: { auth: true, region: true, org: true },
|
|
23
|
+
optional: { project: true },
|
|
23
24
|
examples: [
|
|
24
25
|
{
|
|
25
26
|
command: getCommand('cloud sandbox run -- echo "hello world"'),
|
|
@@ -63,12 +64,14 @@ export const runSubcommand = createCommand({
|
|
|
63
64
|
.array(z.string())
|
|
64
65
|
.optional()
|
|
65
66
|
.describe('Apt packages to install (can be specified multiple times)'),
|
|
67
|
+
projectId: z.string().optional().describe('Project ID to associate this sandbox with'),
|
|
66
68
|
}),
|
|
67
69
|
response: SandboxRunResponseSchema,
|
|
68
70
|
},
|
|
69
71
|
|
|
70
72
|
async handler(ctx) {
|
|
71
|
-
const { args, opts, options, auth, region, config, logger, orgId } = ctx;
|
|
73
|
+
const { args, opts, options, auth, region, config, logger, orgId, project } = ctx;
|
|
74
|
+
const projectId = opts.projectId || project?.projectId;
|
|
72
75
|
const client = createSandboxClient(logger, auth, region);
|
|
73
76
|
const started = Date.now();
|
|
74
77
|
|
|
@@ -151,6 +154,7 @@ export const runSubcommand = createCommand({
|
|
|
151
154
|
try {
|
|
152
155
|
const result = await sandboxRun(client, {
|
|
153
156
|
options: {
|
|
157
|
+
projectId,
|
|
154
158
|
runtime: opts.runtime,
|
|
155
159
|
runtimeId: opts.runtimeId,
|
|
156
160
|
name: opts.name,
|
|
@@ -190,7 +190,18 @@ async function resolveFileGlobs(
|
|
|
190
190
|
}
|
|
191
191
|
}
|
|
192
192
|
|
|
193
|
-
for (
|
|
193
|
+
for (let pattern of exclusions) {
|
|
194
|
+
// If the pattern refers to a directory, auto-append /** to exclude all contents
|
|
195
|
+
const patternPath = join(directory, pattern);
|
|
196
|
+
try {
|
|
197
|
+
const stat = statSync(patternPath);
|
|
198
|
+
if (stat.isDirectory()) {
|
|
199
|
+
pattern = pattern.endsWith('/') ? `${pattern}**` : `${pattern}/**`;
|
|
200
|
+
}
|
|
201
|
+
} catch {
|
|
202
|
+
// Path doesn't exist or can't be stat'd, use pattern as-is
|
|
203
|
+
}
|
|
204
|
+
|
|
194
205
|
const glob = new Bun.Glob(pattern);
|
|
195
206
|
for await (const file of glob.scan({ cwd: directory, dot: true })) {
|
|
196
207
|
files.delete(file);
|
|
@@ -473,16 +484,20 @@ export const buildSubcommand = createCommand({
|
|
|
473
484
|
if (!options.json) {
|
|
474
485
|
tui.info(`${tui.bold('Dry Run')} - No upload will be performed`);
|
|
475
486
|
console.log('');
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
487
|
+
tui.table(
|
|
488
|
+
[
|
|
489
|
+
{
|
|
490
|
+
Name: finalName,
|
|
491
|
+
Description: finalDescription ?? '-',
|
|
492
|
+
Runtime: buildConfig.runtime,
|
|
493
|
+
Tag: opts.tag ?? 'latest',
|
|
494
|
+
Size: tui.formatBytes(totalSize),
|
|
495
|
+
Files: fileList.length.toFixed(),
|
|
496
|
+
},
|
|
497
|
+
],
|
|
498
|
+
['Name', 'Description', 'Runtime', 'Tag', 'Size', 'Files'],
|
|
499
|
+
{ layout: 'vertical', padStart: ' ' }
|
|
500
|
+
);
|
|
486
501
|
|
|
487
502
|
if (buildConfig.dependencies && buildConfig.dependencies.length > 0) {
|
|
488
503
|
console.log('');
|
|
@@ -569,9 +584,16 @@ export const buildSubcommand = createCommand({
|
|
|
569
584
|
if (!options.json) {
|
|
570
585
|
tui.success(`Snapshot unchanged ${tui.bold(initResult.existingId!)}`);
|
|
571
586
|
console.log('');
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
587
|
+
tui.table(
|
|
588
|
+
[
|
|
589
|
+
{
|
|
590
|
+
Name: finalName,
|
|
591
|
+
Tag: opts.tag ?? 'latest',
|
|
592
|
+
},
|
|
593
|
+
],
|
|
594
|
+
['Name', 'Tag'],
|
|
595
|
+
{ layout: 'vertical', padStart: ' ' }
|
|
596
|
+
);
|
|
575
597
|
}
|
|
576
598
|
|
|
577
599
|
return {
|
|
@@ -630,17 +652,22 @@ export const buildSubcommand = createCommand({
|
|
|
630
652
|
if (!options.json) {
|
|
631
653
|
tui.success(`Created snapshot ${tui.bold(snapshot.snapshotId)}`);
|
|
632
654
|
console.log('');
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
655
|
+
|
|
656
|
+
tui.table(
|
|
657
|
+
[
|
|
658
|
+
{
|
|
659
|
+
Name: snapshot.name,
|
|
660
|
+
Description: snapshot.description ?? '-',
|
|
661
|
+
Runtime: buildConfig.runtime,
|
|
662
|
+
Tag: snapshot.tag ?? 'latest',
|
|
663
|
+
Size: tui.formatBytes(snapshot.sizeBytes),
|
|
664
|
+
Files: snapshot.fileCount.toFixed(),
|
|
665
|
+
Created: snapshot.createdAt,
|
|
666
|
+
},
|
|
667
|
+
],
|
|
668
|
+
['Name', 'Description', 'Runtime', 'Tag', 'Size', 'Files', 'Created'],
|
|
669
|
+
{ layout: 'vertical', padStart: ' ' }
|
|
641
670
|
);
|
|
642
|
-
console.log(` ${tui.muted('Files:'.padEnd(13))} ${snapshot.fileCount}`);
|
|
643
|
-
console.log(` ${tui.muted('Created:'.padEnd(13))} ${snapshot.createdAt}`);
|
|
644
671
|
|
|
645
672
|
if (buildConfig.dependencies && buildConfig.dependencies.length > 0) {
|
|
646
673
|
console.log('');
|
|
@@ -88,6 +88,8 @@ export const generateSubcommand = createCommand({
|
|
|
88
88
|
description: 'Generate a template snapshot build file',
|
|
89
89
|
tags: [],
|
|
90
90
|
requires: {},
|
|
91
|
+
skipUpgradeCheck: true,
|
|
92
|
+
skipSkill: true,
|
|
91
93
|
examples: [
|
|
92
94
|
{
|
|
93
95
|
command: getCommand('cloud sandbox snapshot generate'),
|
|
@@ -78,18 +78,22 @@ export const getSubcommand = createCommand({
|
|
|
78
78
|
);
|
|
79
79
|
|
|
80
80
|
if (!options.json) {
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
const tableData: Record<string, string | number> = {
|
|
82
|
+
Snapshot: tui.bold(snapshot.snapshotId),
|
|
83
|
+
Name: snapshot.name,
|
|
84
|
+
};
|
|
83
85
|
if (snapshot.tag) {
|
|
84
|
-
|
|
86
|
+
tableData['Tag'] = snapshot.tag;
|
|
85
87
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
88
|
+
tableData['Size'] = tui.formatBytes(snapshot.sizeBytes);
|
|
89
|
+
tableData['Files'] = snapshot.fileCount;
|
|
90
|
+
tableData['Created'] = snapshot.createdAt;
|
|
89
91
|
if (snapshot.parentSnapshotId) {
|
|
90
|
-
|
|
92
|
+
tableData['Parent'] = snapshot.parentSnapshotId;
|
|
91
93
|
}
|
|
92
94
|
|
|
95
|
+
tui.table([tableData], Object.keys(tableData), { layout: 'vertical', padStart: ' ' });
|
|
96
|
+
|
|
93
97
|
if (
|
|
94
98
|
snapshot.userMetadata &&
|
|
95
99
|
typeof snapshot.userMetadata === 'object' &&
|
|
@@ -67,7 +67,7 @@ const SessionGetResponseSchema = z.object({
|
|
|
67
67
|
pending: z.boolean(),
|
|
68
68
|
success: z.boolean(),
|
|
69
69
|
error: z.string().nullable(),
|
|
70
|
-
result: z.string().nullable(),
|
|
70
|
+
result: z.record(z.string(), z.unknown()).nullable(),
|
|
71
71
|
})
|
|
72
72
|
)
|
|
73
73
|
.describe('Eval runs'),
|
|
@@ -171,48 +171,44 @@ export const getSubcommand = createSubcommand({
|
|
|
171
171
|
return result;
|
|
172
172
|
}
|
|
173
173
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
174
|
+
const tableData: Record<string, string> = {
|
|
175
|
+
ID: session.id,
|
|
176
|
+
Project: session.project_id,
|
|
177
|
+
Deployment: session.deployment_id || '-',
|
|
178
|
+
Start: new Date(session.start_time).toLocaleString(),
|
|
179
|
+
};
|
|
178
180
|
if (session.end_time) {
|
|
179
|
-
|
|
181
|
+
tableData['End'] = new Date(session.end_time).toLocaleString();
|
|
180
182
|
}
|
|
181
|
-
if (session.duration && session.end_time) {
|
|
182
|
-
|
|
183
|
-
tui.bold('Duration: ') + `${(session.duration / 1_000_000).toFixed(0)}ms`
|
|
184
|
-
);
|
|
183
|
+
if (session.duration != null && session.end_time != null) {
|
|
184
|
+
tableData['Duration'] = `${(session.duration / 1_000_000).toFixed(0)}ms`;
|
|
185
185
|
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
186
|
+
tableData['Method'] = session.method;
|
|
187
|
+
tableData['URL'] = tui.link(session.url, session.url);
|
|
188
|
+
tableData['Trigger'] = session.trigger;
|
|
189
189
|
if (session.env !== 'production') {
|
|
190
|
-
|
|
190
|
+
tableData['Environment'] = session.env;
|
|
191
191
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
(session.success ? tui.colorSuccess('✓') : tui.colorError('✗'))
|
|
196
|
-
);
|
|
197
|
-
console.log(tui.bold('Pending: ') + (session.pending ? 'Yes' : 'No'));
|
|
192
|
+
tableData['Dev Mode'] = session.devmode ? 'Yes' : 'No';
|
|
193
|
+
tableData['Success'] = session.success ? tui.colorSuccess('✓') : tui.colorError('✗');
|
|
194
|
+
tableData['Pending'] = session.pending ? 'Yes' : 'No';
|
|
198
195
|
if (session.error) {
|
|
199
|
-
|
|
196
|
+
tableData['Error'] = tui.colorError(session.error);
|
|
200
197
|
}
|
|
201
198
|
if (enriched.agents.length > 0) {
|
|
202
|
-
|
|
199
|
+
tableData['Agents'] = enriched.agents
|
|
203
200
|
.map((agent: AgentInfo) => `${agent.name} ${tui.muted(`(${agent.identifier})`)}`)
|
|
204
201
|
.join(', ');
|
|
205
|
-
console.log(tui.bold('Agents: ') + agentDisplay);
|
|
206
202
|
}
|
|
207
203
|
if (enriched.route) {
|
|
208
|
-
|
|
209
|
-
tui.
|
|
210
|
-
`${enriched.route.method.toUpperCase()} ${enriched.route.path} ${tui.muted(`(${enriched.route.id})`)}`
|
|
211
|
-
);
|
|
204
|
+
tableData['Route'] =
|
|
205
|
+
`${enriched.route.method.toUpperCase()} ${enriched.route.path} ${tui.muted(`(${enriched.route.id})`)}`;
|
|
212
206
|
} else {
|
|
213
|
-
|
|
207
|
+
tableData['Route ID'] = session.route_id;
|
|
214
208
|
}
|
|
215
|
-
|
|
209
|
+
tableData['Thread ID'] = session.thread_id;
|
|
210
|
+
|
|
211
|
+
tui.table([tableData], Object.keys(tableData), { layout: 'vertical', padStart: ' ' });
|
|
216
212
|
|
|
217
213
|
if (enriched.evalRuns.length > 0) {
|
|
218
214
|
console.log('');
|
|
@@ -53,6 +53,10 @@ export const listSubcommand = createSubcommand({
|
|
|
53
53
|
command: getCommand('cloud session list --env=production'),
|
|
54
54
|
description: 'Only production environment',
|
|
55
55
|
},
|
|
56
|
+
{
|
|
57
|
+
command: getCommand('cloud session list --all'),
|
|
58
|
+
description: 'List all sessions regardless of project context',
|
|
59
|
+
},
|
|
56
60
|
],
|
|
57
61
|
aliases: ['ls'],
|
|
58
62
|
requires: { auth: true },
|
|
@@ -76,6 +80,7 @@ export const listSubcommand = createSubcommand({
|
|
|
76
80
|
.default(10)
|
|
77
81
|
.describe('Number of sessions to list (1–100)'),
|
|
78
82
|
projectId: z.string().optional().describe('Filter by project ID'),
|
|
83
|
+
all: z.boolean().optional().describe('List all sessions regardless of project context'),
|
|
79
84
|
deploymentId: z.string().optional().describe('Filter by deployment ID'),
|
|
80
85
|
trigger: z.string().optional().describe('Filter by trigger type (api, cron, webhook)'),
|
|
81
86
|
env: z.string().optional().describe('Filter by environment'),
|
|
@@ -89,14 +94,14 @@ export const listSubcommand = createSubcommand({
|
|
|
89
94
|
response: SessionListResponseSchema,
|
|
90
95
|
},
|
|
91
96
|
webUrl: (ctx) => {
|
|
92
|
-
const projectId = ctx.opts?.projectId || ctx.project?.projectId;
|
|
97
|
+
const projectId = ctx.opts?.all ? undefined : ctx.opts?.projectId || ctx.project?.projectId;
|
|
93
98
|
return projectId ? `/projects/${encodeURIComponent(projectId)}/sessions` : undefined;
|
|
94
99
|
},
|
|
95
100
|
async handler(ctx) {
|
|
96
101
|
const { logger, auth, project, opts, options, config } = ctx;
|
|
97
102
|
const catalystClient = await getGlobalCatalystAPIClient(logger, auth, config?.name);
|
|
98
103
|
|
|
99
|
-
const projectId = opts.projectId || project?.projectId;
|
|
104
|
+
const projectId = opts.all ? undefined : opts.projectId || project?.projectId;
|
|
100
105
|
|
|
101
106
|
try {
|
|
102
107
|
const sessions = await sessionList(catalystClient, {
|
|
@@ -59,21 +59,25 @@ export const getSubcommand = createSubcommand({
|
|
|
59
59
|
return result;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
62
|
+
const tableData: Record<string, string> = {
|
|
63
|
+
ID: thread.id,
|
|
64
|
+
Project: thread.project_id,
|
|
65
|
+
Created: new Date(thread.created_at).toLocaleString(),
|
|
66
|
+
Updated: new Date(thread.updated_at).toLocaleString(),
|
|
67
|
+
Deleted: thread.deleted ? 'Yes' : 'No',
|
|
68
|
+
};
|
|
67
69
|
if (thread.deleted_at) {
|
|
68
|
-
|
|
70
|
+
tableData['Deleted At'] = new Date(thread.deleted_at).toLocaleString();
|
|
69
71
|
}
|
|
70
72
|
if (thread.deleted_by) {
|
|
71
|
-
|
|
73
|
+
tableData['Deleted By'] = thread.deleted_by;
|
|
72
74
|
}
|
|
73
75
|
if (thread.user_data) {
|
|
74
|
-
|
|
76
|
+
tableData['User Data'] = thread.user_data;
|
|
75
77
|
}
|
|
76
78
|
|
|
79
|
+
tui.table([tableData], Object.keys(tableData), { layout: 'vertical', padStart: ' ' });
|
|
80
|
+
|
|
77
81
|
return result;
|
|
78
82
|
} catch (ex) {
|
|
79
83
|
if (ex instanceof APIError && ex.status === 404) {
|
|
@@ -34,6 +34,10 @@ export const listSubcommand = createSubcommand({
|
|
|
34
34
|
command: getCommand('cloud thread list --org-id=org_*'),
|
|
35
35
|
description: 'Filter by organization',
|
|
36
36
|
},
|
|
37
|
+
{
|
|
38
|
+
command: getCommand('cloud thread list --all'),
|
|
39
|
+
description: 'List all threads regardless of project context',
|
|
40
|
+
},
|
|
37
41
|
],
|
|
38
42
|
aliases: ['ls'],
|
|
39
43
|
requires: { auth: true },
|
|
@@ -58,6 +62,7 @@ export const listSubcommand = createSubcommand({
|
|
|
58
62
|
.describe('Number of threads to list (1–100)'),
|
|
59
63
|
orgId: z.string().optional().describe('Filter by organization ID'),
|
|
60
64
|
projectId: z.string().optional().describe('Filter by project ID'),
|
|
65
|
+
all: z.boolean().optional().describe('List all threads regardless of project context'),
|
|
61
66
|
}),
|
|
62
67
|
response: ThreadListResponseSchema,
|
|
63
68
|
},
|
|
@@ -65,7 +70,7 @@ export const listSubcommand = createSubcommand({
|
|
|
65
70
|
const { logger, auth, project, opts, options, config } = ctx;
|
|
66
71
|
const catalystClient = await getGlobalCatalystAPIClient(logger, auth, config?.name);
|
|
67
72
|
|
|
68
|
-
const projectId = opts.projectId || project?.projectId;
|
|
73
|
+
const projectId = opts.all ? undefined : opts.projectId || project?.projectId;
|
|
69
74
|
const orgId = opts.orgId;
|
|
70
75
|
|
|
71
76
|
try {
|
|
@@ -55,6 +55,7 @@ export function createFileWatcher(options: FileWatcherOptions): FileWatcherManag
|
|
|
55
55
|
'.idea',
|
|
56
56
|
'.DS_Store',
|
|
57
57
|
'.playwright',
|
|
58
|
+
'.bun',
|
|
58
59
|
'src/generated',
|
|
59
60
|
]);
|
|
60
61
|
|
|
@@ -76,6 +77,7 @@ export function createFileWatcher(options: FileWatcherOptions): FileWatcherManag
|
|
|
76
77
|
'.dist',
|
|
77
78
|
'.vscode',
|
|
78
79
|
'.idea',
|
|
80
|
+
'.bun',
|
|
79
81
|
'.DS_Store',
|
|
80
82
|
'.playwright',
|
|
81
83
|
'src/web', // Vite handles frontend with HMR - no backend restart needed
|
package/src/cmd/dev/index.ts
CHANGED
|
@@ -12,9 +12,10 @@ import { APIClient, getAPIBaseURL, getAppBaseURL, getGravityDevModeURL } from '.
|
|
|
12
12
|
import { download } from './download';
|
|
13
13
|
import { createDevmodeSyncService } from './sync';
|
|
14
14
|
import { getDevmodeDeploymentId } from '../build/ast';
|
|
15
|
-
import { getDefaultConfigDir, saveConfig, loadProjectSDKKey } from '../../config';
|
|
15
|
+
import { getDefaultConfigDir, saveConfig, loadProjectSDKKey, getAuth } from '../../config';
|
|
16
16
|
import type { Config } from '../../types';
|
|
17
17
|
import { typecheck } from '../build/typecheck';
|
|
18
|
+
import { isTTY, hasLoggedInBefore } from '../../auth';
|
|
18
19
|
import { createFileWatcher } from './file-watcher';
|
|
19
20
|
import { regenerateSkillsAsync } from './skills';
|
|
20
21
|
import { prepareDevLock, releaseLockSync } from './dev-lock';
|
|
@@ -171,12 +172,15 @@ export const command = createCommand({
|
|
|
171
172
|
.describe('The TCP port to start the dev server (also reads from PORT env)'),
|
|
172
173
|
}),
|
|
173
174
|
},
|
|
174
|
-
optional: {
|
|
175
|
+
optional: { project: true },
|
|
175
176
|
|
|
176
177
|
async handler(ctx) {
|
|
177
|
-
const { opts, logger, project, projectDir
|
|
178
|
+
const { opts, logger, project, projectDir } = ctx;
|
|
178
179
|
let { config } = ctx;
|
|
179
180
|
|
|
181
|
+
// Get auth state - we handle auth ourselves based on project state
|
|
182
|
+
let auth = await getAuth();
|
|
183
|
+
|
|
180
184
|
const rootDir = resolve(projectDir);
|
|
181
185
|
const appTs = join(rootDir, 'app.ts');
|
|
182
186
|
const srcDir = join(rootDir, 'src');
|
|
@@ -208,6 +212,71 @@ export const command = createCommand({
|
|
|
208
212
|
originalExit(1);
|
|
209
213
|
}
|
|
210
214
|
|
|
215
|
+
// Handle authentication state based on project registration
|
|
216
|
+
if (project) {
|
|
217
|
+
// Registered project (has agentuity.json) - check if user needs to login
|
|
218
|
+
const isValidAuth = auth && auth.expires > new Date();
|
|
219
|
+
if (!isValidAuth) {
|
|
220
|
+
if (isTTY()) {
|
|
221
|
+
const hasProfile = await hasLoggedInBefore();
|
|
222
|
+
const message = hasProfile
|
|
223
|
+
? 'Your session has expired or you are not logged in.'
|
|
224
|
+
: 'This project is registered with Agentuity Cloud but you are not logged in.';
|
|
225
|
+
|
|
226
|
+
tui.warning(message);
|
|
227
|
+
tui.newline();
|
|
228
|
+
|
|
229
|
+
const shouldLogin = await tui.confirm(
|
|
230
|
+
hasProfile ? 'Would you like to login now?' : 'Would you like to login or create an account?',
|
|
231
|
+
true
|
|
232
|
+
);
|
|
233
|
+
|
|
234
|
+
if (shouldLogin) {
|
|
235
|
+
tui.newline();
|
|
236
|
+
|
|
237
|
+
// Run login flow inline
|
|
238
|
+
const { loginCommand } = await import('../auth/login');
|
|
239
|
+
|
|
240
|
+
// Ensure apiClient is available for login handler
|
|
241
|
+
const loginCtx = ctx as unknown as Record<string, unknown>;
|
|
242
|
+
if (!loginCtx.apiClient) {
|
|
243
|
+
loginCtx.apiClient = new APIClient(getAPIBaseURL(config), logger, config);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
if (loginCommand.handler) {
|
|
247
|
+
await loginCommand.handler(
|
|
248
|
+
loginCtx as Parameters<NonNullable<typeof loginCommand.handler>>[0]
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// Refresh auth state after login
|
|
253
|
+
const freshAuth = await getAuth();
|
|
254
|
+
if (!freshAuth || freshAuth.expires <= new Date()) {
|
|
255
|
+
tui.fatal('Login was not completed successfully.', ErrorCode.AUTH_FAILED);
|
|
256
|
+
}
|
|
257
|
+
auth = freshAuth;
|
|
258
|
+
tui.newline();
|
|
259
|
+
tui.success('Login successful! Continuing with dev server...');
|
|
260
|
+
tui.newline();
|
|
261
|
+
} else {
|
|
262
|
+
// User chose not to login - show warning about disabled features
|
|
263
|
+
tui.newline();
|
|
264
|
+
tui.showLoggedOutMessage(getAppBaseURL(config), hasProfile);
|
|
265
|
+
}
|
|
266
|
+
} else {
|
|
267
|
+
// Non-TTY: fatal error with instruction
|
|
268
|
+
logger.fatal(
|
|
269
|
+
`Authentication required for this project.\n` +
|
|
270
|
+
`Run "${getCommand('auth login')}" to login to Agentuity`,
|
|
271
|
+
ErrorCode.AUTH_REQUIRED
|
|
272
|
+
);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
} else {
|
|
276
|
+
// No agentuity.json - local-only mode, ignore auth state
|
|
277
|
+
tui.showLocalOnlyWarning();
|
|
278
|
+
}
|
|
279
|
+
|
|
211
280
|
// Prepare dev lock: cleans up stale processes from previous sessions
|
|
212
281
|
// and creates a new lockfile for this session
|
|
213
282
|
const devLock = await prepareDevLock(rootDir, opts.port, logger);
|
|
@@ -229,7 +298,10 @@ export const command = createCommand({
|
|
|
229
298
|
try {
|
|
230
299
|
// Setup devmode and gravity (if using public URL)
|
|
231
300
|
const useMockService = process.env.DEVMODE_SYNC_SERVICE_MOCK === 'true';
|
|
232
|
-
|
|
301
|
+
// Create apiClient with fresh auth API key (important after inline login)
|
|
302
|
+
const apiClient = auth
|
|
303
|
+
? new APIClient(getAPIBaseURL(config), logger, auth.apiKey, config)
|
|
304
|
+
: null;
|
|
233
305
|
const syncService = apiClient
|
|
234
306
|
? createDevmodeSyncService({
|
|
235
307
|
logger,
|