@agentuity/cli 0.1.33 → 0.1.35
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/bin/cli.ts +107 -6
- package/dist/cmd/ai/index.d.ts.map +1 -1
- package/dist/cmd/ai/index.js +0 -6
- package/dist/cmd/ai/index.js.map +1 -1
- package/dist/cmd/ai/opencode/uninstall.js +1 -1
- package/dist/cmd/ai/opencode/uninstall.js.map +1 -1
- package/dist/cmd/build/vite/bun-dev-server.d.ts +6 -0
- package/dist/cmd/build/vite/bun-dev-server.d.ts.map +1 -1
- package/dist/cmd/build/vite/bun-dev-server.js +100 -33
- package/dist/cmd/build/vite/bun-dev-server.js.map +1 -1
- package/dist/cmd/cloud/apikey/create.d.ts.map +1 -1
- package/dist/cmd/cloud/apikey/create.js +1 -1
- package/dist/cmd/cloud/apikey/create.js.map +1 -1
- package/dist/cmd/cloud/deploy.d.ts.map +1 -1
- package/dist/cmd/cloud/deploy.js +4 -1
- package/dist/cmd/cloud/deploy.js.map +1 -1
- package/dist/cmd/cloud/env/delete.d.ts.map +1 -1
- package/dist/cmd/cloud/env/delete.js +100 -45
- package/dist/cmd/cloud/env/delete.js.map +1 -1
- package/dist/cmd/cloud/env/pull.d.ts.map +1 -1
- package/dist/cmd/cloud/env/pull.js +1 -1
- package/dist/cmd/cloud/env/pull.js.map +1 -1
- package/dist/cmd/cloud/machine/delete.js +1 -1
- package/dist/cmd/cloud/machine/delete.js.map +1 -1
- package/dist/cmd/cloud/sandbox/exec.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/exec.js +10 -35
- package/dist/cmd/cloud/sandbox/exec.js.map +1 -1
- package/dist/cmd/dev/index.d.ts.map +1 -1
- package/dist/cmd/dev/index.js +58 -10
- package/dist/cmd/dev/index.js.map +1 -1
- package/dist/cmd/index.d.ts.map +1 -1
- package/dist/cmd/index.js +1 -0
- package/dist/cmd/index.js.map +1 -1
- package/dist/cmd/support/index.d.ts +2 -0
- package/dist/cmd/support/index.d.ts.map +1 -0
- package/dist/cmd/support/index.js +11 -0
- package/dist/cmd/support/index.js.map +1 -0
- package/dist/cmd/support/logs/index.d.ts +3 -0
- package/dist/cmd/support/logs/index.d.ts.map +1 -0
- package/dist/cmd/support/logs/index.js +9 -0
- package/dist/cmd/support/logs/index.js.map +1 -0
- package/dist/cmd/support/logs/path.d.ts +3 -0
- package/dist/cmd/support/logs/path.d.ts.map +1 -0
- package/dist/cmd/support/logs/path.js +52 -0
- package/dist/cmd/support/logs/path.js.map +1 -0
- package/dist/cmd/support/logs/show.d.ts +3 -0
- package/dist/cmd/support/logs/show.d.ts.map +1 -0
- package/dist/cmd/support/logs/show.js +121 -0
- package/dist/cmd/support/logs/show.js.map +1 -0
- package/dist/cmd/support/report.d.ts +3 -0
- package/dist/cmd/support/report.d.ts.map +1 -0
- package/dist/cmd/support/report.js +299 -0
- package/dist/cmd/support/report.js.map +1 -0
- package/dist/cmd/support/system.d.ts +3 -0
- package/dist/cmd/support/system.d.ts.map +1 -0
- package/dist/cmd/support/system.js +120 -0
- package/dist/cmd/support/system.js.map +1 -0
- package/dist/cmd/version/index.d.ts.map +1 -1
- package/dist/cmd/version/index.js +1 -0
- package/dist/cmd/version/index.js.map +1 -1
- package/dist/composite-logger.d.ts +35 -0
- package/dist/composite-logger.d.ts.map +1 -0
- package/dist/composite-logger.js +78 -0
- package/dist/composite-logger.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/internal-logger.d.ts +77 -0
- package/dist/internal-logger.d.ts.map +1 -0
- package/dist/internal-logger.js +340 -0
- package/dist/internal-logger.js.map +1 -0
- package/dist/types.d.ts +6 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/installation-type.d.ts.map +1 -1
- package/dist/utils/installation-type.js +54 -16
- package/dist/utils/installation-type.js.map +1 -1
- package/package.json +6 -6
- package/src/cmd/ai/index.ts +0 -6
- package/src/cmd/ai/opencode/uninstall.ts +1 -1
- package/src/cmd/build/vite/bun-dev-server.ts +113 -36
- package/src/cmd/cloud/apikey/create.ts +3 -1
- package/src/cmd/cloud/deploy.ts +4 -1
- package/src/cmd/cloud/env/delete.ts +100 -45
- package/src/cmd/cloud/env/pull.ts +1 -6
- package/src/cmd/cloud/machine/delete.ts +1 -1
- package/src/cmd/cloud/sandbox/exec.ts +10 -41
- package/src/cmd/dev/index.ts +59 -11
- package/src/cmd/index.ts +1 -0
- package/src/cmd/support/index.ts +11 -0
- package/src/cmd/support/logs/index.ts +9 -0
- package/src/cmd/support/logs/path.ts +56 -0
- package/src/cmd/support/logs/show.ts +144 -0
- package/src/cmd/support/report.ts +364 -0
- package/src/cmd/support/system.ts +130 -0
- package/src/cmd/version/index.ts +1 -0
- package/src/composite-logger.ts +86 -0
- package/src/index.ts +7 -0
- package/src/internal-logger.ts +411 -0
- package/src/types.ts +6 -0
- package/src/utils/installation-type.ts +55 -16
- package/dist/cmd/ai/skills/generate.d.ts +0 -3
- package/dist/cmd/ai/skills/generate.d.ts.map +0 -1
- package/dist/cmd/ai/skills/generate.js +0 -65
- package/dist/cmd/ai/skills/generate.js.map +0 -1
- package/dist/cmd/ai/skills/generator.d.ts +0 -4
- package/dist/cmd/ai/skills/generator.d.ts.map +0 -1
- package/dist/cmd/ai/skills/generator.js +0 -410
- package/dist/cmd/ai/skills/generator.js.map +0 -1
- package/dist/cmd/ai/skills/index.d.ts +0 -4
- package/dist/cmd/ai/skills/index.d.ts.map +0 -1
- package/dist/cmd/ai/skills/index.js +0 -21
- package/dist/cmd/ai/skills/index.js.map +0 -1
- package/dist/cmd/dev/skills.d.ts +0 -10
- package/dist/cmd/dev/skills.d.ts.map +0 -1
- package/dist/cmd/dev/skills.js +0 -57
- package/dist/cmd/dev/skills.js.map +0 -1
- package/src/cmd/ai/skills/generate.ts +0 -75
- package/src/cmd/ai/skills/generator.ts +0 -527
- package/src/cmd/ai/skills/index.ts +0 -23
- package/src/cmd/dev/skills.ts +0 -82
|
@@ -7,8 +7,8 @@ import { getCommand } from '../../../command-prefix';
|
|
|
7
7
|
import { sandboxExecute, executionGet, writeAndDrain } from '@agentuity/server';
|
|
8
8
|
import type { Logger } from '@agentuity/core';
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
const
|
|
10
|
+
// Server-side long-poll wait duration (max 5 minutes supported by server)
|
|
11
|
+
const EXECUTION_WAIT_DURATION = '5m';
|
|
12
12
|
|
|
13
13
|
const SandboxExecResponseSchema = z.object({
|
|
14
14
|
executionId: z.string().describe('Unique execution identifier'),
|
|
@@ -115,41 +115,14 @@ export const execSubcommand = createCommand({
|
|
|
115
115
|
}
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
await sleep(POLL_INTERVAL_MS);
|
|
127
|
-
attempts++;
|
|
128
|
-
|
|
129
|
-
try {
|
|
130
|
-
const execInfo = await executionGet(client, {
|
|
131
|
-
executionId: execution.executionId,
|
|
132
|
-
orgId,
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
if (
|
|
136
|
-
execInfo.status === 'completed' ||
|
|
137
|
-
execInfo.status === 'failed' ||
|
|
138
|
-
execInfo.status === 'timeout' ||
|
|
139
|
-
execInfo.status === 'cancelled'
|
|
140
|
-
) {
|
|
141
|
-
finalExecution = {
|
|
142
|
-
executionId: execInfo.executionId,
|
|
143
|
-
status: execInfo.status,
|
|
144
|
-
exitCode: execInfo.exitCode,
|
|
145
|
-
durationMs: execInfo.durationMs,
|
|
146
|
-
};
|
|
147
|
-
break;
|
|
148
|
-
}
|
|
149
|
-
} catch {
|
|
150
|
-
continue;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
118
|
+
// Use server-side long-polling to wait for execution completion
|
|
119
|
+
// This is more efficient than client-side polling and provides immediate
|
|
120
|
+
// error detection if the sandbox is terminated
|
|
121
|
+
const finalExecution = await executionGet(client, {
|
|
122
|
+
executionId: execution.executionId,
|
|
123
|
+
orgId,
|
|
124
|
+
wait: EXECUTION_WAIT_DURATION,
|
|
125
|
+
});
|
|
153
126
|
|
|
154
127
|
// Wait for all streams to reach EOF (Pulse blocks until true EOF)
|
|
155
128
|
await Promise.all(streamPromises);
|
|
@@ -248,8 +221,4 @@ function createCaptureStream(onChunk: (chunk: string) => void): NodeJS.WritableS
|
|
|
248
221
|
});
|
|
249
222
|
}
|
|
250
223
|
|
|
251
|
-
function sleep(ms: number): Promise<void> {
|
|
252
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
253
|
-
}
|
|
254
|
-
|
|
255
224
|
export default execSubcommand;
|
package/src/cmd/dev/index.ts
CHANGED
|
@@ -18,7 +18,6 @@ import { typecheck } from '../build/typecheck';
|
|
|
18
18
|
import { validateGravityRequiresUpgrade } from '../../runtime';
|
|
19
19
|
import { isTTY, hasLoggedInBefore } from '../../auth';
|
|
20
20
|
import { createFileWatcher } from './file-watcher';
|
|
21
|
-
import { regenerateSkillsAsync } from './skills';
|
|
22
21
|
import { prepareDevLock, releaseLockSync } from './dev-lock';
|
|
23
22
|
import { checkAndUpgradeDependencies } from '../../utils/dependency-checker';
|
|
24
23
|
import { ErrorCode } from '../../errors';
|
|
@@ -81,6 +80,7 @@ async function killLingeringGravityProcesses(logger: {
|
|
|
81
80
|
/**
|
|
82
81
|
* Stop the existing Bun server if one is running.
|
|
83
82
|
* Waits for the port to become available before returning (with timeout).
|
|
83
|
+
* Handles both in-process server and subprocess (when debugger is enabled).
|
|
84
84
|
*/
|
|
85
85
|
async function stopBunServer(
|
|
86
86
|
port: number,
|
|
@@ -88,6 +88,48 @@ async function stopBunServer(
|
|
|
88
88
|
): Promise<void> {
|
|
89
89
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
90
90
|
const globalAny = globalThis as any;
|
|
91
|
+
|
|
92
|
+
// Check for subprocess first (used when debugger flags are enabled)
|
|
93
|
+
const bunSubprocess = globalAny.__AGENTUITY_BUN_SUBPROCESS__ as ProcessLike | undefined;
|
|
94
|
+
if (bunSubprocess) {
|
|
95
|
+
logger.debug('Stopping Bun subprocess...');
|
|
96
|
+
try {
|
|
97
|
+
bunSubprocess.kill('SIGTERM');
|
|
98
|
+
// After SIGTERM, wait and check multiple times before giving up
|
|
99
|
+
let attempts = 0;
|
|
100
|
+
while (bunSubprocess.exitCode === null && attempts < 3) {
|
|
101
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
102
|
+
attempts++;
|
|
103
|
+
}
|
|
104
|
+
if (bunSubprocess.exitCode === null) {
|
|
105
|
+
bunSubprocess.kill('SIGKILL');
|
|
106
|
+
}
|
|
107
|
+
logger.debug('Bun subprocess killed');
|
|
108
|
+
} catch (err) {
|
|
109
|
+
logger.debug('Error killing Bun subprocess: %s', err);
|
|
110
|
+
}
|
|
111
|
+
globalAny.__AGENTUITY_BUN_SUBPROCESS__ = undefined;
|
|
112
|
+
|
|
113
|
+
// Wait for port to become available
|
|
114
|
+
const MAX_WAIT_ITERATIONS = 10;
|
|
115
|
+
for (let i = 0; i < MAX_WAIT_ITERATIONS; i++) {
|
|
116
|
+
try {
|
|
117
|
+
await fetch(`http://127.0.0.1:${port}/`, {
|
|
118
|
+
method: 'HEAD',
|
|
119
|
+
signal: AbortSignal.timeout(150),
|
|
120
|
+
});
|
|
121
|
+
// Still responding, wait a bit more
|
|
122
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
123
|
+
} catch {
|
|
124
|
+
// Connection refused or timeout => server is down
|
|
125
|
+
logger.debug('Bun subprocess stopped');
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Handle in-process server
|
|
91
133
|
const server = globalAny.__AGENTUITY_SERVER__ as BunServer | undefined;
|
|
92
134
|
if (!server) {
|
|
93
135
|
logger.debug('No Bun server to stop');
|
|
@@ -171,6 +213,15 @@ export const command = createCommand({
|
|
|
171
213
|
.max(MAX_PORT)
|
|
172
214
|
.default(getDefaultPort())
|
|
173
215
|
.describe('The TCP port to start the dev server (also reads from PORT env)'),
|
|
216
|
+
inspect: z.boolean().optional().describe('Enable bun debugger on available port'),
|
|
217
|
+
inspectWait: z
|
|
218
|
+
.boolean()
|
|
219
|
+
.optional()
|
|
220
|
+
.describe('Enable bun debugger and wait for connection before executing'),
|
|
221
|
+
inspectBrk: z
|
|
222
|
+
.boolean()
|
|
223
|
+
.optional()
|
|
224
|
+
.describe('Enable bun debugger with breakpoint at first line'),
|
|
174
225
|
}),
|
|
175
226
|
},
|
|
176
227
|
optional: { project: true },
|
|
@@ -489,12 +540,6 @@ export const command = createCommand({
|
|
|
489
540
|
centerTitle: false,
|
|
490
541
|
});
|
|
491
542
|
|
|
492
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
493
|
-
const cliVersion = ((global as any).__CLI_SCHEMA__?.version as string) ?? '';
|
|
494
|
-
if (cliVersion) {
|
|
495
|
-
regenerateSkillsAsync(rootDir, cliVersion, logger).catch(() => {});
|
|
496
|
-
}
|
|
497
|
-
|
|
498
543
|
// Start Vite asset server ONCE before restart loop
|
|
499
544
|
// Vite handles frontend HMR independently and stays running across backend restarts
|
|
500
545
|
let viteServer: ServerLike | null = null;
|
|
@@ -961,7 +1006,7 @@ export const command = createCommand({
|
|
|
961
1006
|
}
|
|
962
1007
|
} catch (error) {
|
|
963
1008
|
tui.error(`Failed to build dev bundle: ${error}`);
|
|
964
|
-
tui.
|
|
1009
|
+
tui.warning('Waiting for file changes to retry...');
|
|
965
1010
|
|
|
966
1011
|
// Resume watcher to detect changes for retry
|
|
967
1012
|
fileWatcher.resume();
|
|
@@ -986,7 +1031,7 @@ export const command = createCommand({
|
|
|
986
1031
|
if (sdkKey) {
|
|
987
1032
|
process.env.AGENTUITY_SDK_KEY = sdkKey;
|
|
988
1033
|
} else if (project) {
|
|
989
|
-
tui.
|
|
1034
|
+
tui.warning(
|
|
990
1035
|
'AGENTUITY_SDK_KEY not found in .env file. Numerous features will be unavailable.'
|
|
991
1036
|
);
|
|
992
1037
|
tui.bullet(
|
|
@@ -1035,6 +1080,9 @@ export const command = createCommand({
|
|
|
1035
1080
|
deploymentId,
|
|
1036
1081
|
logger,
|
|
1037
1082
|
vitePort, // Pass port of already-running Vite server
|
|
1083
|
+
inspect: opts.inspect,
|
|
1084
|
+
inspectWait: opts.inspectWait,
|
|
1085
|
+
inspectBrk: opts.inspectBrk,
|
|
1038
1086
|
});
|
|
1039
1087
|
|
|
1040
1088
|
// Wait for app.ts to finish loading (Vite is ready but app may still be initializing)
|
|
@@ -1047,7 +1095,7 @@ export const command = createCommand({
|
|
|
1047
1095
|
}
|
|
1048
1096
|
} catch (error) {
|
|
1049
1097
|
tui.error(`Failed to start dev server: ${error}`);
|
|
1050
|
-
tui.
|
|
1098
|
+
tui.warning('Waiting for file changes to retry...');
|
|
1051
1099
|
|
|
1052
1100
|
// Wait for next restart trigger or shutdown
|
|
1053
1101
|
await new Promise<void>((resolve) => {
|
|
@@ -1274,7 +1322,7 @@ export const command = createCommand({
|
|
|
1274
1322
|
await Bun.sleep(500);
|
|
1275
1323
|
} catch (error) {
|
|
1276
1324
|
tui.error(`Error during server operation: ${error}`);
|
|
1277
|
-
tui.
|
|
1325
|
+
tui.warning('Waiting for file changes to retry...');
|
|
1278
1326
|
|
|
1279
1327
|
// Cleanup on error (Vite stays running)
|
|
1280
1328
|
await cleanupForRestart();
|
package/src/cmd/index.ts
CHANGED
|
@@ -15,6 +15,7 @@ export async function discoverCommands(): Promise<CommandDefinition[]> {
|
|
|
15
15
|
import('./project').then((m) => m.command),
|
|
16
16
|
import('./repl').then((m) => m.command),
|
|
17
17
|
import('./setup').then((m) => m.command),
|
|
18
|
+
import('./support').then((m) => m.command),
|
|
18
19
|
import('./upgrade').then((m) => m.command),
|
|
19
20
|
import('./version').then((m) => m.command),
|
|
20
21
|
]);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { createCommand } from '../../types';
|
|
2
|
+
import logs from './logs';
|
|
3
|
+
import report from './report';
|
|
4
|
+
import system from './system';
|
|
5
|
+
|
|
6
|
+
export const command = createCommand({
|
|
7
|
+
name: 'support',
|
|
8
|
+
description: 'Create support tickets and report issues',
|
|
9
|
+
skipInternalLogging: true,
|
|
10
|
+
subcommands: [logs, report, system],
|
|
11
|
+
});
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { createSubcommand } from '../../../types';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { getLatestLogSession, getLogsDirPath } from '../../../internal-logger';
|
|
4
|
+
import * as tui from '../../../tui';
|
|
5
|
+
|
|
6
|
+
const argsSchema = z.object({});
|
|
7
|
+
|
|
8
|
+
const optionsSchema = z.object({
|
|
9
|
+
logs: z.boolean().optional().default(false).describe('Show path to logs directory instead of session'),
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
export default createSubcommand({
|
|
13
|
+
name: 'path',
|
|
14
|
+
description: 'Show the path to the most recent log session',
|
|
15
|
+
schema: {
|
|
16
|
+
args: argsSchema,
|
|
17
|
+
options: optionsSchema,
|
|
18
|
+
},
|
|
19
|
+
handler: async (ctx) => {
|
|
20
|
+
const { opts } = ctx;
|
|
21
|
+
const isJsonMode = ctx.options.json;
|
|
22
|
+
|
|
23
|
+
if (opts.logs) {
|
|
24
|
+
// Show the logs directory path
|
|
25
|
+
const logsDir = getLogsDirPath();
|
|
26
|
+
if (isJsonMode) {
|
|
27
|
+
console.log(JSON.stringify({ logsDir }));
|
|
28
|
+
} else {
|
|
29
|
+
console.log(logsDir);
|
|
30
|
+
}
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const sessionDir = getLatestLogSession();
|
|
35
|
+
if (!sessionDir) {
|
|
36
|
+
if (isJsonMode) {
|
|
37
|
+
console.log(
|
|
38
|
+
JSON.stringify({
|
|
39
|
+
error: 'No logs found',
|
|
40
|
+
logsDir: getLogsDirPath(),
|
|
41
|
+
})
|
|
42
|
+
);
|
|
43
|
+
} else {
|
|
44
|
+
tui.warning('No CLI logs found');
|
|
45
|
+
tui.info(`Logs directory: ${tui.muted(getLogsDirPath())}`);
|
|
46
|
+
}
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (isJsonMode) {
|
|
51
|
+
console.log(JSON.stringify({ sessionDir }));
|
|
52
|
+
} else {
|
|
53
|
+
console.log(sessionDir);
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
});
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { createSubcommand } from '../../../types';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
4
|
+
import { getLatestLogSession, getLogsDirPath } from '../../../internal-logger';
|
|
5
|
+
import * as tui from '../../../tui';
|
|
6
|
+
import { join } from 'node:path';
|
|
7
|
+
|
|
8
|
+
const argsSchema = z.object({});
|
|
9
|
+
|
|
10
|
+
const optionsSchema = z.object({
|
|
11
|
+
session: z.boolean().optional().default(false).describe('Show session metadata only'),
|
|
12
|
+
tail: z.number().optional().describe('Show last N log entries'),
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
export default createSubcommand({
|
|
16
|
+
name: 'show',
|
|
17
|
+
description: 'Show the most recent CLI command logs',
|
|
18
|
+
schema: {
|
|
19
|
+
args: argsSchema,
|
|
20
|
+
options: optionsSchema,
|
|
21
|
+
},
|
|
22
|
+
handler: async (ctx) => {
|
|
23
|
+
const { opts } = ctx;
|
|
24
|
+
const isJsonMode = ctx.options.json;
|
|
25
|
+
|
|
26
|
+
const sessionDir = getLatestLogSession();
|
|
27
|
+
if (!sessionDir) {
|
|
28
|
+
if (isJsonMode) {
|
|
29
|
+
console.log(
|
|
30
|
+
JSON.stringify({
|
|
31
|
+
error: 'No logs found',
|
|
32
|
+
logsDir: getLogsDirPath(),
|
|
33
|
+
})
|
|
34
|
+
);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
tui.warning('No CLI logs found');
|
|
38
|
+
tui.info(`Logs are stored in: ${tui.muted(getLogsDirPath())}`);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const sessionFile = join(sessionDir, 'session.json');
|
|
43
|
+
const logsFile = join(sessionDir, 'logs.jsonl');
|
|
44
|
+
|
|
45
|
+
if (!existsSync(sessionFile)) {
|
|
46
|
+
if (isJsonMode) {
|
|
47
|
+
console.log(JSON.stringify({ error: 'Session metadata not found' }));
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
tui.error('Session metadata not found');
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Read session metadata
|
|
55
|
+
const sessionData = JSON.parse(readFileSync(sessionFile, 'utf-8'));
|
|
56
|
+
|
|
57
|
+
if (opts.session) {
|
|
58
|
+
// Show session metadata only
|
|
59
|
+
if (isJsonMode) {
|
|
60
|
+
console.log(JSON.stringify(sessionData, null, 2));
|
|
61
|
+
} else {
|
|
62
|
+
tui.info(tui.bold('CLI Command Session'));
|
|
63
|
+
tui.newline();
|
|
64
|
+
tui.output(`Session ID: ${tui.colorPrimary(sessionData.sessionId)}`);
|
|
65
|
+
tui.output(`Command: ${tui.colorInfo(sessionData.command)}`);
|
|
66
|
+
tui.output(`Args: ${sessionData.args.join(' ')}`);
|
|
67
|
+
tui.output(`Timestamp: ${sessionData.timestamp}`);
|
|
68
|
+
tui.output(`CLI Version: ${sessionData.cli.version}`);
|
|
69
|
+
tui.output(`Platform: ${sessionData.system.platform}/${sessionData.system.arch}`);
|
|
70
|
+
tui.output(`CWD: ${sessionData.cwd}`);
|
|
71
|
+
tui.newline();
|
|
72
|
+
tui.output(tui.muted(`Session directory: ${sessionDir}`));
|
|
73
|
+
}
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Read log entries
|
|
78
|
+
if (!existsSync(logsFile)) {
|
|
79
|
+
if (isJsonMode) {
|
|
80
|
+
console.log(JSON.stringify({ session: sessionData, logs: [] }));
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
tui.warning('No log entries found for this session');
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const logLines = readFileSync(logsFile, 'utf-8')
|
|
88
|
+
.split('\n')
|
|
89
|
+
.filter((line) => line.trim());
|
|
90
|
+
const logEntries = logLines.map((line) => JSON.parse(line));
|
|
91
|
+
|
|
92
|
+
// Apply tail filter if specified
|
|
93
|
+
const displayEntries = opts.tail ? logEntries.slice(-opts.tail) : logEntries;
|
|
94
|
+
|
|
95
|
+
if (isJsonMode) {
|
|
96
|
+
console.log(
|
|
97
|
+
JSON.stringify(
|
|
98
|
+
{
|
|
99
|
+
session: sessionData,
|
|
100
|
+
logs: displayEntries,
|
|
101
|
+
},
|
|
102
|
+
null,
|
|
103
|
+
2
|
|
104
|
+
)
|
|
105
|
+
);
|
|
106
|
+
} else {
|
|
107
|
+
// Human-readable output
|
|
108
|
+
tui.info(tui.bold('CLI Command Session'));
|
|
109
|
+
tui.newline();
|
|
110
|
+
tui.output(`Session ID: ${tui.colorPrimary(sessionData.sessionId)}`);
|
|
111
|
+
tui.output(`Command: ${tui.colorInfo(sessionData.command)}`);
|
|
112
|
+
tui.output(`Timestamp: ${sessionData.timestamp}`);
|
|
113
|
+
tui.output(`Total Logs: ${logEntries.length}`);
|
|
114
|
+
if (opts.tail) {
|
|
115
|
+
tui.output(`Showing: Last ${opts.tail} entries`);
|
|
116
|
+
}
|
|
117
|
+
tui.newline();
|
|
118
|
+
|
|
119
|
+
// Display log entries
|
|
120
|
+
for (const entry of displayEntries) {
|
|
121
|
+
const levelColor =
|
|
122
|
+
entry.level === 'error'
|
|
123
|
+
? tui.colorError
|
|
124
|
+
: entry.level === 'warn'
|
|
125
|
+
? tui.warn
|
|
126
|
+
: entry.level === 'info'
|
|
127
|
+
? tui.colorInfo
|
|
128
|
+
: tui.muted;
|
|
129
|
+
|
|
130
|
+
const timestamp = new Date(entry.timestamp).toLocaleTimeString();
|
|
131
|
+
const level = entry.level.toUpperCase().padEnd(5);
|
|
132
|
+
|
|
133
|
+
tui.output(`${tui.muted(timestamp)} ${levelColor(level)} ${entry.message}`);
|
|
134
|
+
|
|
135
|
+
if (entry.context && Object.keys(entry.context).length > 0) {
|
|
136
|
+
tui.output(tui.muted(` Context: ${JSON.stringify(entry.context)}`));
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
tui.newline();
|
|
141
|
+
tui.output(tui.muted(`Session directory: ${sessionDir}`));
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
});
|