@agentuity/cli 0.0.53 → 0.0.55
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/cli.d.ts.map +1 -1
- package/dist/cli.js +66 -8
- package/dist/cli.js.map +1 -1
- package/dist/cmd/auth/ssh/add.d.ts.map +1 -1
- package/dist/cmd/auth/ssh/add.js +28 -13
- package/dist/cmd/auth/ssh/add.js.map +1 -1
- package/dist/cmd/auth/ssh/delete.d.ts.map +1 -1
- package/dist/cmd/auth/ssh/delete.js +28 -18
- package/dist/cmd/auth/ssh/delete.js.map +1 -1
- package/dist/cmd/auth/ssh/list.d.ts.map +1 -1
- package/dist/cmd/auth/ssh/list.js +5 -6
- package/dist/cmd/auth/ssh/list.js.map +1 -1
- package/dist/cmd/build/ast.d.ts +34 -0
- package/dist/cmd/build/ast.d.ts.map +1 -1
- package/dist/cmd/build/ast.js +165 -5
- package/dist/cmd/build/ast.js.map +1 -1
- package/dist/cmd/build/bundler.d.ts +2 -1
- package/dist/cmd/build/bundler.d.ts.map +1 -1
- package/dist/cmd/build/bundler.js +78 -17
- package/dist/cmd/build/bundler.js.map +1 -1
- package/dist/cmd/build/index.d.ts.map +1 -1
- package/dist/cmd/build/index.js +2 -0
- package/dist/cmd/build/index.js.map +1 -1
- package/dist/cmd/build/plugin.d.ts.map +1 -1
- package/dist/cmd/build/plugin.js +75 -7
- package/dist/cmd/build/plugin.js.map +1 -1
- package/dist/cmd/cloud/deployment/list.d.ts.map +1 -1
- package/dist/cmd/cloud/deployment/list.js +28 -23
- package/dist/cmd/cloud/deployment/list.js.map +1 -1
- package/dist/cmd/cloud/deployment/show.d.ts.map +1 -1
- package/dist/cmd/cloud/deployment/show.js +50 -47
- package/dist/cmd/cloud/deployment/show.js.map +1 -1
- package/dist/cmd/cloud/env/get.d.ts.map +1 -1
- package/dist/cmd/cloud/env/get.js +16 -14
- package/dist/cmd/cloud/env/get.js.map +1 -1
- package/dist/cmd/cloud/env/list.d.ts.map +1 -1
- package/dist/cmd/cloud/env/list.js +24 -20
- package/dist/cmd/cloud/env/list.js.map +1 -1
- package/dist/cmd/cloud/keyvalue/get.d.ts.map +1 -1
- package/dist/cmd/cloud/keyvalue/get.js +18 -16
- package/dist/cmd/cloud/keyvalue/get.js.map +1 -1
- package/dist/cmd/cloud/keyvalue/keys.d.ts.map +1 -1
- package/dist/cmd/cloud/keyvalue/keys.js +11 -11
- package/dist/cmd/cloud/keyvalue/keys.js.map +1 -1
- package/dist/cmd/cloud/keyvalue/list-namespaces.d.ts.map +1 -1
- package/dist/cmd/cloud/keyvalue/list-namespaces.js +11 -7
- package/dist/cmd/cloud/keyvalue/list-namespaces.js.map +1 -1
- package/dist/cmd/cloud/keyvalue/search.d.ts.map +1 -1
- package/dist/cmd/cloud/keyvalue/search.js +16 -17
- package/dist/cmd/cloud/keyvalue/search.js.map +1 -1
- package/dist/cmd/cloud/keyvalue/stats.d.ts.map +1 -1
- package/dist/cmd/cloud/keyvalue/stats.js +38 -23
- package/dist/cmd/cloud/keyvalue/stats.js.map +1 -1
- package/dist/cmd/cloud/objectstore/get.d.ts.map +1 -1
- package/dist/cmd/cloud/objectstore/get.js +17 -15
- package/dist/cmd/cloud/objectstore/get.js.map +1 -1
- package/dist/cmd/cloud/objectstore/list-buckets.d.ts.map +1 -1
- package/dist/cmd/cloud/objectstore/list-buckets.js +12 -8
- package/dist/cmd/cloud/objectstore/list-buckets.js.map +1 -1
- package/dist/cmd/cloud/objectstore/list-keys.d.ts.map +1 -1
- package/dist/cmd/cloud/objectstore/list-keys.js +13 -10
- package/dist/cmd/cloud/objectstore/list-keys.js.map +1 -1
- package/dist/cmd/cloud/resource/list.d.ts.map +1 -1
- package/dist/cmd/cloud/resource/list.js +38 -27
- package/dist/cmd/cloud/resource/list.js.map +1 -1
- package/dist/cmd/cloud/secret/get.d.ts.map +1 -1
- package/dist/cmd/cloud/secret/get.js +17 -15
- package/dist/cmd/cloud/secret/get.js.map +1 -1
- package/dist/cmd/cloud/secret/list.d.ts.map +1 -1
- package/dist/cmd/cloud/secret/list.js +24 -20
- package/dist/cmd/cloud/secret/list.js.map +1 -1
- package/dist/cmd/cloud/session/logs.d.ts.map +1 -1
- package/dist/cmd/cloud/session/logs.js +18 -15
- package/dist/cmd/cloud/session/logs.js.map +1 -1
- package/dist/cmd/dev/agents.d.ts.map +1 -1
- package/dist/cmd/dev/agents.js +55 -41
- package/dist/cmd/dev/agents.js.map +1 -1
- package/dist/cmd/dev/index.d.ts.map +1 -1
- package/dist/cmd/dev/index.js +34 -14
- package/dist/cmd/dev/index.js.map +1 -1
- package/dist/cmd/profile/create.js +1 -1
- package/dist/cmd/profile/create.js.map +1 -1
- package/dist/cmd/profile/delete.d.ts.map +1 -1
- package/dist/cmd/profile/delete.js +1 -1
- package/dist/cmd/profile/delete.js.map +1 -1
- package/dist/cmd/profile/list.d.ts.map +1 -1
- package/dist/cmd/profile/list.js +29 -11
- package/dist/cmd/profile/list.js.map +1 -1
- package/dist/cmd/profile/show.d.ts.map +1 -1
- package/dist/cmd/profile/show.js +7 -10
- package/dist/cmd/profile/show.js.map +1 -1
- package/dist/cmd/project/delete.js +1 -1
- package/dist/cmd/project/delete.js.map +1 -1
- package/dist/cmd/version/index.d.ts.map +1 -1
- package/dist/cmd/version/index.js +1 -1
- package/dist/cmd/version/index.js.map +1 -1
- package/dist/tui.d.ts.map +1 -1
- package/dist/tui.js +3 -1
- package/dist/tui.js.map +1 -1
- package/dist/types.d.ts +32 -8
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +3 -3
- package/src/cli.ts +109 -8
- package/src/cmd/auth/ssh/add.ts +37 -17
- package/src/cmd/auth/ssh/delete.ts +36 -23
- package/src/cmd/auth/ssh/list.ts +8 -6
- package/src/cmd/build/ast.ts +209 -5
- package/src/cmd/build/bundler.ts +82 -16
- package/src/cmd/build/index.ts +2 -0
- package/src/cmd/build/plugin.ts +93 -7
- package/src/cmd/cloud/deployment/list.ts +30 -26
- package/src/cmd/cloud/deployment/show.ts +47 -42
- package/src/cmd/cloud/env/get.ts +14 -12
- package/src/cmd/cloud/env/list.ts +24 -22
- package/src/cmd/cloud/keyvalue/get.ts +19 -14
- package/src/cmd/cloud/keyvalue/keys.ts +10 -12
- package/src/cmd/cloud/keyvalue/list-namespaces.ts +10 -8
- package/src/cmd/cloud/keyvalue/search.ts +14 -17
- package/src/cmd/cloud/keyvalue/stats.ts +52 -28
- package/src/cmd/cloud/objectstore/get.ts +18 -13
- package/src/cmd/cloud/objectstore/list-buckets.ts +11 -9
- package/src/cmd/cloud/objectstore/list-keys.ts +12 -11
- package/src/cmd/cloud/resource/list.ts +33 -23
- package/src/cmd/cloud/secret/get.ts +15 -13
- package/src/cmd/cloud/secret/list.ts +24 -22
- package/src/cmd/cloud/session/logs.ts +18 -17
- package/src/cmd/dev/agents.ts +70 -50
- package/src/cmd/dev/index.ts +41 -14
- package/src/cmd/profile/create.ts +3 -3
- package/src/cmd/profile/delete.ts +5 -2
- package/src/cmd/profile/list.ts +31 -11
- package/src/cmd/profile/show.ts +15 -12
- package/src/cmd/project/delete.ts +1 -1
- package/src/cmd/version/index.ts +5 -1
- package/src/tui.ts +3 -1
- package/src/types.ts +32 -10
|
@@ -35,7 +35,7 @@ export const getSubcommand = createSubcommand({
|
|
|
35
35
|
idempotent: true,
|
|
36
36
|
|
|
37
37
|
async handler(ctx) {
|
|
38
|
-
const { args, opts, apiClient, project } = ctx;
|
|
38
|
+
const { args, opts, apiClient, project, options } = ctx;
|
|
39
39
|
|
|
40
40
|
// Fetch project with unmasked secrets
|
|
41
41
|
const projectData = await tui.spinner('Fetching secrets', () => {
|
|
@@ -49,19 +49,21 @@ export const getSubcommand = createSubcommand({
|
|
|
49
49
|
tui.fatal(`Secret '${args.key}' not found`, ErrorCode.RESOURCE_NOT_FOUND);
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
if (
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
52
|
+
if (!options.json) {
|
|
53
|
+
if (process.stdout.isTTY) {
|
|
54
|
+
// Display the value, masked by default
|
|
55
|
+
if (opts?.mask) {
|
|
56
|
+
tui.success(`${args.key}=${maskSecret(value)}`);
|
|
57
|
+
} else {
|
|
58
|
+
tui.success(`${args.key}=${value}`);
|
|
59
|
+
}
|
|
56
60
|
} else {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
} else {
|
|
64
|
-
console.log(`${args.key}=${value}`);
|
|
61
|
+
// Display the value, masked by default
|
|
62
|
+
if (opts?.mask) {
|
|
63
|
+
console.log(`${args.key}=${maskSecret(value)}`);
|
|
64
|
+
} else {
|
|
65
|
+
console.log(`${args.key}=${value}`);
|
|
66
|
+
}
|
|
65
67
|
}
|
|
66
68
|
}
|
|
67
69
|
|
|
@@ -26,7 +26,7 @@ export const listSubcommand = createSubcommand({
|
|
|
26
26
|
},
|
|
27
27
|
|
|
28
28
|
async handler(ctx) {
|
|
29
|
-
const { opts, apiClient, project } = ctx;
|
|
29
|
+
const { opts, apiClient, project, options } = ctx;
|
|
30
30
|
|
|
31
31
|
// Fetch project with unmasked secrets
|
|
32
32
|
const projectData = await tui.spinner('Fetching secrets', () => {
|
|
@@ -35,28 +35,30 @@ export const listSubcommand = createSubcommand({
|
|
|
35
35
|
|
|
36
36
|
const secrets = projectData.secrets || {};
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
// Display the secrets
|
|
44
|
-
if (process.stdout.isTTY) {
|
|
45
|
-
tui.newline();
|
|
46
|
-
tui.success(`Secrets (${Object.keys(secrets).length}):`);
|
|
47
|
-
tui.newline();
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const sortedKeys = Object.keys(secrets).sort();
|
|
51
|
-
// For secrets, masking is enabled by default in TTY (can be disabled with --no-mask)
|
|
52
|
-
const shouldMask = opts?.mask !== false;
|
|
53
|
-
for (const key of sortedKeys) {
|
|
54
|
-
const value = secrets[key];
|
|
55
|
-
const displayValue = shouldMask ? maskSecret(value) : value;
|
|
56
|
-
if (process.stdout.isTTY) {
|
|
57
|
-
console.log(`${tui.bold(key)}=${displayValue}`);
|
|
38
|
+
// Skip TUI output in JSON mode
|
|
39
|
+
if (!options.json) {
|
|
40
|
+
if (Object.keys(secrets).length === 0) {
|
|
41
|
+
tui.info('No secrets found');
|
|
58
42
|
} else {
|
|
59
|
-
|
|
43
|
+
// Display the secrets
|
|
44
|
+
if (process.stdout.isTTY) {
|
|
45
|
+
tui.newline();
|
|
46
|
+
tui.success(`Secrets (${Object.keys(secrets).length}):`);
|
|
47
|
+
tui.newline();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const sortedKeys = Object.keys(secrets).sort();
|
|
51
|
+
// For secrets, masking is enabled by default in TTY (can be disabled with --no-mask)
|
|
52
|
+
const shouldMask = opts?.mask !== false;
|
|
53
|
+
for (const key of sortedKeys) {
|
|
54
|
+
const value = secrets[key];
|
|
55
|
+
const displayValue = shouldMask ? maskSecret(value) : value;
|
|
56
|
+
if (process.stdout.isTTY) {
|
|
57
|
+
console.log(`${tui.bold(key)}=${displayValue}`);
|
|
58
|
+
} else {
|
|
59
|
+
console.log(`${key}=${displayValue}`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
60
62
|
}
|
|
61
63
|
}
|
|
62
64
|
|
|
@@ -32,29 +32,30 @@ export const logsSubcommand = createSubcommand({
|
|
|
32
32
|
response: SessionLogsResponseSchema,
|
|
33
33
|
},
|
|
34
34
|
async handler(ctx) {
|
|
35
|
-
const { apiClient, args } = ctx;
|
|
35
|
+
const { apiClient, args, options } = ctx;
|
|
36
36
|
|
|
37
37
|
try {
|
|
38
38
|
const logs = await sessionLogs(apiClient, { id: args.session_id });
|
|
39
39
|
|
|
40
|
-
if (
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
tui.banner(`Logs for Session ${args.session_id}`, `${logs.length} log entries`);
|
|
40
|
+
if (!options.json) {
|
|
41
|
+
if (logs.length === 0) {
|
|
42
|
+
tui.info('No logs found for this session.');
|
|
43
|
+
} else {
|
|
44
|
+
tui.banner(`Logs for Session ${args.session_id}`, `${logs.length} log entries`);
|
|
46
45
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
46
|
+
for (const log of logs) {
|
|
47
|
+
const timestamp = new Date(log.timestamp).toLocaleTimeString();
|
|
48
|
+
const severity = log.severity.padEnd(5);
|
|
49
|
+
const severityColor =
|
|
50
|
+
log.severity === 'ERROR'
|
|
51
|
+
? tui.error(severity)
|
|
52
|
+
: log.severity === 'WARN'
|
|
53
|
+
? tui.warning(severity)
|
|
54
|
+
: tui.muted(severity);
|
|
56
55
|
|
|
57
|
-
|
|
56
|
+
console.log(`${tui.muted(timestamp)} ${severityColor} ${log.body}`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
58
59
|
}
|
|
59
60
|
|
|
60
61
|
return logs;
|
package/src/cmd/dev/agents.ts
CHANGED
|
@@ -46,22 +46,30 @@ export const agentsSubcommand = createSubcommand({
|
|
|
46
46
|
.describe('Output format: json or table'),
|
|
47
47
|
verbose: z.boolean().optional().default(false).describe('Show full IDs and descriptions'),
|
|
48
48
|
}),
|
|
49
|
+
response: z.array(AgentSchema),
|
|
49
50
|
},
|
|
50
51
|
async handler(ctx) {
|
|
51
|
-
const { opts, apiClient, project } = ctx;
|
|
52
|
+
const { opts, apiClient, project, options } = ctx;
|
|
52
53
|
const projectId = project.projectId;
|
|
53
54
|
const format = opts?.format ?? 'table';
|
|
54
55
|
const verbose = opts?.verbose ?? false;
|
|
55
56
|
|
|
56
57
|
const deploymentId = opts?.deploymentId;
|
|
57
58
|
const queryParams = deploymentId ? `?deploymentId=${deploymentId}` : '';
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
59
|
+
|
|
60
|
+
const response = options.json
|
|
61
|
+
? await apiClient.request(
|
|
62
|
+
'GET',
|
|
63
|
+
`/cli/agent/${projectId}${queryParams}`,
|
|
64
|
+
AgentsResponseSchema
|
|
65
|
+
)
|
|
66
|
+
: await tui.spinner('Fetching agents', async () => {
|
|
67
|
+
return apiClient.request(
|
|
68
|
+
'GET',
|
|
69
|
+
`/cli/agent/${projectId}${queryParams}`,
|
|
70
|
+
AgentsResponseSchema
|
|
71
|
+
);
|
|
72
|
+
});
|
|
65
73
|
|
|
66
74
|
if (!response.success) {
|
|
67
75
|
tui.fatal(`Failed to fetch agents: ${response.message ?? 'Unknown error'}`);
|
|
@@ -69,54 +77,66 @@ export const agentsSubcommand = createSubcommand({
|
|
|
69
77
|
|
|
70
78
|
const agents = response.data;
|
|
71
79
|
|
|
72
|
-
if (format === 'json') {
|
|
80
|
+
if (format === 'json' && !options.json) {
|
|
73
81
|
console.log(JSON.stringify(agents, null, 2));
|
|
74
|
-
return;
|
|
82
|
+
return agents;
|
|
75
83
|
}
|
|
76
84
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
85
|
+
if (!options.json) {
|
|
86
|
+
tui.info(`Agents (${agents.length})`);
|
|
87
|
+
if (agents.length === 0) {
|
|
88
|
+
tui.muted('No agents found');
|
|
89
|
+
} else {
|
|
90
|
+
console.table(
|
|
91
|
+
agents.map((agent) => ({
|
|
92
|
+
name: agent.name,
|
|
93
|
+
id: verbose ? agent.id : abbreviate(agent.id, 20),
|
|
94
|
+
identifier: verbose ? agent.identifier : abbreviate(agent.identifier, 20),
|
|
95
|
+
deployment: abbreviate(agent.deploymentId, 20),
|
|
96
|
+
version: verbose
|
|
97
|
+
? (agent.version ?? 'N/A')
|
|
98
|
+
: (abbreviate(agent.version, 20) ?? 'N/A'),
|
|
99
|
+
evals: agent.evals.length,
|
|
100
|
+
createdAt: new Date(agent.createdAt).toLocaleString(),
|
|
101
|
+
})),
|
|
102
|
+
['name', 'id', 'identifier', 'deployment', 'version', 'evals', 'createdAt']
|
|
103
|
+
);
|
|
95
104
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
105
|
+
// Show evals for each agent
|
|
106
|
+
for (const agent of agents) {
|
|
107
|
+
if (agent.evals.length > 0) {
|
|
108
|
+
console.log(`\n Evals for ${agent.name}:`);
|
|
109
|
+
console.table(
|
|
110
|
+
agent.evals.map((evalItem) => ({
|
|
111
|
+
name: evalItem.name,
|
|
112
|
+
id: verbose ? evalItem.id : abbreviate(evalItem.id, 20),
|
|
113
|
+
identifier: verbose
|
|
114
|
+
? (evalItem.identifier ?? 'N/A')
|
|
115
|
+
: (abbreviate(evalItem.identifier, 20) ?? 'N/A'),
|
|
116
|
+
deployment: abbreviate(evalItem.deploymentId, 20),
|
|
117
|
+
version: verbose
|
|
118
|
+
? (evalItem.version ?? 'N/A')
|
|
119
|
+
: (abbreviate(evalItem.version, 20) ?? 'N/A'),
|
|
120
|
+
description: verbose
|
|
121
|
+
? (evalItem.description ?? 'N/A')
|
|
122
|
+
: abbreviateDescription(evalItem.description),
|
|
123
|
+
createdAt: new Date(evalItem.createdAt).toLocaleString(),
|
|
124
|
+
})),
|
|
125
|
+
[
|
|
126
|
+
'name',
|
|
127
|
+
'id',
|
|
128
|
+
'identifier',
|
|
129
|
+
'deployment',
|
|
130
|
+
'version',
|
|
131
|
+
'description',
|
|
132
|
+
'createdAt',
|
|
133
|
+
]
|
|
134
|
+
);
|
|
135
|
+
}
|
|
118
136
|
}
|
|
119
137
|
}
|
|
120
138
|
}
|
|
139
|
+
|
|
140
|
+
return agents;
|
|
121
141
|
},
|
|
122
142
|
});
|
package/src/cmd/dev/index.ts
CHANGED
|
@@ -236,6 +236,7 @@ export const command = createCommand({
|
|
|
236
236
|
let showInitialReadyMessage = true;
|
|
237
237
|
let serverStartTime = 0;
|
|
238
238
|
let gravityClient: Bun.Subprocess | undefined;
|
|
239
|
+
let initialStartupComplete = false;
|
|
239
240
|
|
|
240
241
|
if (gravityBin && devmode && project) {
|
|
241
242
|
const sdkKey = await loadProjectSDKKey(rootDir);
|
|
@@ -259,7 +260,7 @@ export const command = createCommand({
|
|
|
259
260
|
'--url',
|
|
260
261
|
config?.overrides?.gravity_url ?? 'grpc://devmode.agentuity.com',
|
|
261
262
|
'--log-level',
|
|
262
|
-
'error',
|
|
263
|
+
process.env.AGENTUITY_GRAVITY_LOG_LEVEL ?? 'error',
|
|
263
264
|
],
|
|
264
265
|
{
|
|
265
266
|
cwd: rootDir,
|
|
@@ -326,6 +327,7 @@ export const command = createCommand({
|
|
|
326
327
|
logger.trace('Killing dev server (pid: %d)', pid);
|
|
327
328
|
shuttingDownForRestart = true;
|
|
328
329
|
running = false;
|
|
330
|
+
process.kill(pid, 'SIGINT');
|
|
329
331
|
try {
|
|
330
332
|
// Kill the process group (negative PID kills entire group)
|
|
331
333
|
process.kill(-pid, 'SIGTERM');
|
|
@@ -411,17 +413,10 @@ export const command = createCommand({
|
|
|
411
413
|
logger.trace('Initial server start');
|
|
412
414
|
}
|
|
413
415
|
logger.trace('Starting typecheck and build...');
|
|
414
|
-
await
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
cwd: rootDir,
|
|
419
|
-
clearOnSuccess: true,
|
|
420
|
-
truncate: false,
|
|
421
|
-
maxLinesOutput: 2,
|
|
422
|
-
maxLinesOnFailure: 15,
|
|
423
|
-
}),
|
|
424
|
-
tui.spinner('Building project', async () => {
|
|
416
|
+
await tui.spinner({
|
|
417
|
+
message: 'Building project',
|
|
418
|
+
clearOnSuccess: true,
|
|
419
|
+
callback: async () => {
|
|
425
420
|
try {
|
|
426
421
|
logger.trace('Bundle starting...');
|
|
427
422
|
building = true;
|
|
@@ -430,17 +425,31 @@ export const command = createCommand({
|
|
|
430
425
|
dev: true,
|
|
431
426
|
projectId: project?.projectId,
|
|
432
427
|
deploymentId,
|
|
428
|
+
port: opts.port,
|
|
433
429
|
});
|
|
434
430
|
building = false;
|
|
435
431
|
buildCompletedAt = Date.now();
|
|
436
432
|
logger.trace('Bundle completed successfully');
|
|
433
|
+
logger.trace('tsc starting...');
|
|
434
|
+
await tui.runCommand({
|
|
435
|
+
command: 'tsc',
|
|
436
|
+
cmd: ['bunx', 'tsc', '--noEmit'],
|
|
437
|
+
cwd: rootDir,
|
|
438
|
+
clearOnSuccess: true,
|
|
439
|
+
truncate: false,
|
|
440
|
+
maxLinesOutput: 2,
|
|
441
|
+
maxLinesOnFailure: 15,
|
|
442
|
+
});
|
|
443
|
+
logger.trace('tsc completed successfully');
|
|
437
444
|
} catch (error) {
|
|
438
445
|
building = false;
|
|
439
446
|
logger.trace('Bundle failed: %s', error);
|
|
440
447
|
failure('Build failed');
|
|
448
|
+
return;
|
|
441
449
|
}
|
|
442
|
-
}
|
|
443
|
-
|
|
450
|
+
},
|
|
451
|
+
});
|
|
452
|
+
|
|
444
453
|
logger.trace('Typecheck and build completed');
|
|
445
454
|
|
|
446
455
|
if (failed) {
|
|
@@ -539,8 +548,14 @@ export const command = createCommand({
|
|
|
539
548
|
|
|
540
549
|
if (showInitialReadyMessage) {
|
|
541
550
|
showInitialReadyMessage = false;
|
|
551
|
+
// Clear any lingering spinner/command output - clear everything below cursor
|
|
552
|
+
process.stderr.write('\x1B[J'); // Clear from cursor to end of screen
|
|
553
|
+
process.stdout.write('\x1B[J'); // Clear from cursor to end of screen
|
|
542
554
|
logger.info('DevMode ready 🚀');
|
|
543
555
|
logger.trace('Initial ready message logged');
|
|
556
|
+
// Mark initial startup complete immediately to prevent watcher restarts
|
|
557
|
+
initialStartupComplete = true;
|
|
558
|
+
logger.trace('Initial startup complete, file watcher restarts now enabled');
|
|
544
559
|
}
|
|
545
560
|
|
|
546
561
|
logger.trace('Attaching exit handler to dev server process...');
|
|
@@ -632,6 +647,7 @@ export const command = createCommand({
|
|
|
632
647
|
logger.trace('Starting initial build and server');
|
|
633
648
|
await restart();
|
|
634
649
|
logger.trace('Initial restart completed, setting up watchers');
|
|
650
|
+
logger.trace('initialStartupComplete is now: %s', initialStartupComplete);
|
|
635
651
|
|
|
636
652
|
// Setup keyboard shortcuts (only if we have a TTY)
|
|
637
653
|
if (canDoInput) {
|
|
@@ -741,6 +757,17 @@ export const command = createCommand({
|
|
|
741
757
|
const watcher = watch(watchDir, { recursive: true }, (eventType, changedFile) => {
|
|
742
758
|
const absPath = changedFile ? resolve(watchDir, changedFile) : watchDir;
|
|
743
759
|
|
|
760
|
+
// Ignore file changes during initial startup to prevent spurious restarts
|
|
761
|
+
if (!initialStartupComplete) {
|
|
762
|
+
logger.trace(
|
|
763
|
+
'File change ignored (initial startup): %s (event: %s, file: %s)',
|
|
764
|
+
watchDir,
|
|
765
|
+
eventType,
|
|
766
|
+
changedFile
|
|
767
|
+
);
|
|
768
|
+
return;
|
|
769
|
+
}
|
|
770
|
+
|
|
744
771
|
// Ignore file changes during active build to prevent loops
|
|
745
772
|
if (building) {
|
|
746
773
|
logger.trace(
|
|
@@ -59,7 +59,7 @@ export const createCommand = createSubcommand({
|
|
|
59
59
|
return logger.fatal(
|
|
60
60
|
`Profile "${name}" already exists at ${existing.filename}`,
|
|
61
61
|
ErrorCode.RESOURCE_ALREADY_EXISTS
|
|
62
|
-
);
|
|
62
|
+
) as never;
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
await ensureConfigDir();
|
|
@@ -103,10 +103,10 @@ export const createCommand = createSubcommand({
|
|
|
103
103
|
} catch (error) {
|
|
104
104
|
const message = error instanceof Error ? error.message : String(error);
|
|
105
105
|
const stack = error instanceof Error ? error.stack : undefined;
|
|
106
|
-
logger.fatal(
|
|
106
|
+
return logger.fatal(
|
|
107
107
|
`Failed to create profile: ${message}${stack ? `\n${stack}` : ''}`,
|
|
108
108
|
ErrorCode.INTERNAL_ERROR
|
|
109
|
-
);
|
|
109
|
+
) as never;
|
|
110
110
|
}
|
|
111
111
|
},
|
|
112
112
|
});
|
|
@@ -43,7 +43,7 @@ export const deleteCommand = createSubcommand({
|
|
|
43
43
|
const profile = profiles.find((p) => p.name === name);
|
|
44
44
|
|
|
45
45
|
if (!profile) {
|
|
46
|
-
return logger.fatal(`Profile "${name}" not found`, ErrorCode.RESOURCE_NOT_FOUND);
|
|
46
|
+
return logger.fatal(`Profile "${name}" not found`, ErrorCode.RESOURCE_NOT_FOUND) as never;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
// Ask for confirmation unless --confirm flag is passed
|
|
@@ -66,7 +66,10 @@ export const deleteCommand = createSubcommand({
|
|
|
66
66
|
|
|
67
67
|
return { success: true, name };
|
|
68
68
|
} catch (error) {
|
|
69
|
-
logger.fatal(
|
|
69
|
+
return logger.fatal(
|
|
70
|
+
`Failed to delete profile: ${error}`,
|
|
71
|
+
ErrorCode.FILE_WRITE_ERROR
|
|
72
|
+
) as never;
|
|
70
73
|
}
|
|
71
74
|
},
|
|
72
75
|
});
|
package/src/cmd/profile/list.ts
CHANGED
|
@@ -1,9 +1,18 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
1
2
|
import { createSubcommand } from '../../types';
|
|
2
3
|
import { fetchProfiles } from '../../config';
|
|
3
4
|
import { basename, dirname } from 'node:path';
|
|
4
5
|
import * as tui from '../../tui';
|
|
5
6
|
import { getCommand } from '../../command-prefix';
|
|
6
7
|
|
|
8
|
+
const ProfileListResponseSchema = z.array(
|
|
9
|
+
z.object({
|
|
10
|
+
name: z.string().describe('Profile name'),
|
|
11
|
+
filename: z.string().describe('Profile file path'),
|
|
12
|
+
selected: z.boolean().describe('Whether this profile is currently selected'),
|
|
13
|
+
})
|
|
14
|
+
);
|
|
15
|
+
|
|
7
16
|
export const listCommand = createSubcommand({
|
|
8
17
|
name: 'list',
|
|
9
18
|
description: 'List all available profiles',
|
|
@@ -11,21 +20,32 @@ export const listCommand = createSubcommand({
|
|
|
11
20
|
idempotent: true,
|
|
12
21
|
aliases: ['ls'],
|
|
13
22
|
examples: [getCommand('profile list'), getCommand('profile ls')],
|
|
23
|
+
schema: {
|
|
24
|
+
response: ProfileListResponseSchema,
|
|
25
|
+
},
|
|
14
26
|
|
|
15
|
-
async handler() {
|
|
27
|
+
async handler(ctx) {
|
|
28
|
+
const { options } = ctx;
|
|
16
29
|
const profiles = await fetchProfiles();
|
|
17
30
|
|
|
18
|
-
if (
|
|
19
|
-
|
|
20
|
-
|
|
31
|
+
if (!options.json) {
|
|
32
|
+
if (profiles.length === 0) {
|
|
33
|
+
tui.info('No profiles found');
|
|
34
|
+
} else {
|
|
35
|
+
console.log('Available profiles:');
|
|
36
|
+
for (const profile of profiles) {
|
|
37
|
+
const marker = profile.selected ? '•' : ' ';
|
|
38
|
+
const name = tui.padRight(profile.name, 15, ' ');
|
|
39
|
+
const path = `${basename(dirname(profile.filename))}/${basename(profile.filename)}`;
|
|
40
|
+
console.log(`${marker} ${name} ${tui.muted(path)}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
21
43
|
}
|
|
22
44
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
console.log(`${marker} ${name} ${tui.muted(path)}`);
|
|
29
|
-
}
|
|
45
|
+
return profiles.map((p) => ({
|
|
46
|
+
name: p.name,
|
|
47
|
+
filename: p.filename,
|
|
48
|
+
selected: p.selected,
|
|
49
|
+
}));
|
|
30
50
|
},
|
|
31
51
|
});
|
package/src/cmd/profile/show.ts
CHANGED
|
@@ -19,9 +19,6 @@ export const showCommand = createSubcommand({
|
|
|
19
19
|
getCommand('profile show staging --json'),
|
|
20
20
|
],
|
|
21
21
|
schema: {
|
|
22
|
-
options: z.object({
|
|
23
|
-
json: z.boolean().optional().describe('Show the JSON config'),
|
|
24
|
-
}),
|
|
25
22
|
args: z
|
|
26
23
|
.object({
|
|
27
24
|
name: z.string().optional().describe('Profile name to show (optional)'),
|
|
@@ -32,7 +29,7 @@ export const showCommand = createSubcommand({
|
|
|
32
29
|
idempotent: true,
|
|
33
30
|
|
|
34
31
|
async handler(ctx) {
|
|
35
|
-
const { logger, args,
|
|
32
|
+
const { logger, args, options } = ctx;
|
|
36
33
|
|
|
37
34
|
try {
|
|
38
35
|
let current = false;
|
|
@@ -47,19 +44,25 @@ export const showCommand = createSubcommand({
|
|
|
47
44
|
const profile = profiles.find((p) => p.name === name);
|
|
48
45
|
|
|
49
46
|
if (!profile) {
|
|
50
|
-
return logger.fatal(
|
|
47
|
+
return logger.fatal(
|
|
48
|
+
`Profile "${name}" not found`,
|
|
49
|
+
ErrorCode.RESOURCE_NOT_FOUND
|
|
50
|
+
) as never;
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
const profilePath = profile.filename;
|
|
54
54
|
current = profile.selected;
|
|
55
55
|
|
|
56
|
-
tui.info(`Profile: ${profilePath}`);
|
|
57
|
-
|
|
58
56
|
const content = await loadConfig(current ? undefined : profilePath);
|
|
57
|
+
if (!content) {
|
|
58
|
+
return logger.fatal(
|
|
59
|
+
`Failed to load profile configuration`,
|
|
60
|
+
ErrorCode.INTERNAL_ERROR
|
|
61
|
+
) as never;
|
|
62
|
+
}
|
|
59
63
|
|
|
60
|
-
if (
|
|
61
|
-
|
|
62
|
-
} else {
|
|
64
|
+
if (!options.json) {
|
|
65
|
+
tui.info(`Profile: ${profilePath}`);
|
|
63
66
|
tui.newline();
|
|
64
67
|
const textContent = await readFile(profilePath, 'utf-8');
|
|
65
68
|
console.log(textContent);
|
|
@@ -68,9 +71,9 @@ export const showCommand = createSubcommand({
|
|
|
68
71
|
return content;
|
|
69
72
|
} catch (error) {
|
|
70
73
|
if (error instanceof Error) {
|
|
71
|
-
logger.fatal(`Failed to show profile: ${error.message}`);
|
|
74
|
+
return logger.fatal(`Failed to show profile: ${error.message}`) as never;
|
|
72
75
|
} else {
|
|
73
|
-
logger.fatal('Failed to show profile');
|
|
76
|
+
return logger.fatal('Failed to show profile') as never;
|
|
74
77
|
}
|
|
75
78
|
}
|
|
76
79
|
},
|
package/src/cmd/version/index.ts
CHANGED
|
@@ -24,7 +24,11 @@ export const command = createCommand({
|
|
|
24
24
|
return version;
|
|
25
25
|
} catch (error) {
|
|
26
26
|
const logger = createLogger();
|
|
27
|
-
logger.fatal(
|
|
27
|
+
return logger.fatal(
|
|
28
|
+
'Failed to retrieve version: %s',
|
|
29
|
+
error,
|
|
30
|
+
ErrorCode.INTERNAL_ERROR
|
|
31
|
+
) as never;
|
|
28
32
|
}
|
|
29
33
|
},
|
|
30
34
|
});
|
package/src/tui.ts
CHANGED
|
@@ -831,7 +831,9 @@ export async function spinner<T>(
|
|
|
831
831
|
: await options.callback;
|
|
832
832
|
|
|
833
833
|
// If clearOnSuccess is true, don't show success message
|
|
834
|
-
|
|
834
|
+
// Also skip success message in JSON mode
|
|
835
|
+
const isJsonMode = outputOptions?.json === true;
|
|
836
|
+
if (!options.clearOnSuccess && !isJsonMode) {
|
|
835
837
|
const successColor = getColor('success');
|
|
836
838
|
console.error(`${successColor}${ICONS.success} ${message}${reset}`);
|
|
837
839
|
}
|