@thegitai/cli 1.0.0-beta.5 → 1.0.0-beta.6
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 +1 -0
- package/dist/bin/ai.js +13 -49
- package/dist/src/cli-args.js +65 -0
- package/dist/src/help-text.js +14 -0
- package/dist/src/ui/repl.js +13 -1
- package/dist/src/version.js +35 -0
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -20,6 +20,7 @@ ai login sign in via your browser (--no-browser for SSH/headless)
|
|
|
20
20
|
ai whoami show the signed-in account
|
|
21
21
|
ai --usage show account usage and reset times
|
|
22
22
|
ai logout sign out
|
|
23
|
+
ai --version print the version and exit
|
|
23
24
|
```
|
|
24
25
|
|
|
25
26
|
Run `ai --help` for sessions, modes, keys, and chat commands.
|
package/dist/bin/ai.js
CHANGED
|
@@ -13,59 +13,13 @@ import { runClientInteractive, shouldUseClientRatatuiShell, } from '../src/ui/re
|
|
|
13
13
|
import { appendPromptToFile } from '../src/ui/prompt-history-store.js';
|
|
14
14
|
import { formatSessionExitNotice } from '../src/session-exit.js';
|
|
15
15
|
import { formatUsageText } from '../src/usage.js';
|
|
16
|
+
import { formatVersionLine } from '../src/version.js';
|
|
17
|
+
import { parseArgs } from '../src/cli-args.js';
|
|
16
18
|
const DEFAULT_SERVER_URL = 'https://thegit.ai';
|
|
17
|
-
const AUTH_COMMANDS = new Set(['login', 'whoami', 'logout']);
|
|
18
19
|
const { auth, chat, models, sessions } = ServerApi;
|
|
19
20
|
function printUsage() {
|
|
20
21
|
console.log(formatCliHelpText({ color: process.stdout.isTTY === true }));
|
|
21
22
|
}
|
|
22
|
-
export function parseArgs(argv) {
|
|
23
|
-
const args = argv.slice(2);
|
|
24
|
-
const firstArg = args[0];
|
|
25
|
-
const command = firstArg && AUTH_COMMANDS.has(firstArg) ? firstArg : null;
|
|
26
|
-
const commandArgs = command ? args.slice(1) : [];
|
|
27
|
-
let autoYes = false;
|
|
28
|
-
let help = false;
|
|
29
|
-
let usage = false;
|
|
30
|
-
let session = null;
|
|
31
|
-
let listSessions = false;
|
|
32
|
-
const promptParts = [];
|
|
33
|
-
for (let i = 0; i < args.length; i++) {
|
|
34
|
-
const arg = args[i];
|
|
35
|
-
if (arg === '--yes' || arg === '-y') {
|
|
36
|
-
autoYes = true;
|
|
37
|
-
continue;
|
|
38
|
-
}
|
|
39
|
-
if ((arg === '--session' || arg === '--resume') && i + 1 < args.length) {
|
|
40
|
-
session = args[i + 1] ?? null;
|
|
41
|
-
i += 1;
|
|
42
|
-
continue;
|
|
43
|
-
}
|
|
44
|
-
if (arg === '--list-sessions') {
|
|
45
|
-
listSessions = true;
|
|
46
|
-
continue;
|
|
47
|
-
}
|
|
48
|
-
if (arg === '--help' || arg === '-h') {
|
|
49
|
-
help = true;
|
|
50
|
-
continue;
|
|
51
|
-
}
|
|
52
|
-
if (arg === '--usage') {
|
|
53
|
-
usage = true;
|
|
54
|
-
continue;
|
|
55
|
-
}
|
|
56
|
-
promptParts.push(arg);
|
|
57
|
-
}
|
|
58
|
-
return {
|
|
59
|
-
command,
|
|
60
|
-
commandArgs,
|
|
61
|
-
autoYes,
|
|
62
|
-
help,
|
|
63
|
-
usage,
|
|
64
|
-
session,
|
|
65
|
-
listSessions,
|
|
66
|
-
prompt: promptParts.join(' ').trim(),
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
23
|
function commandFlagValue(args, name) {
|
|
70
24
|
const index = args.indexOf(name);
|
|
71
25
|
if (index === -1)
|
|
@@ -340,11 +294,21 @@ async function mainInteractive({ authConfig, projectIndex, serverModels, serverS
|
|
|
340
294
|
}
|
|
341
295
|
}
|
|
342
296
|
export async function main() {
|
|
343
|
-
const { autoYes, help, usage, command, commandArgs, session: sessionIdentifier, listSessions, prompt, } = parseArgs(process.argv);
|
|
297
|
+
const { autoYes, help, version, usage, command, commandArgs, session: sessionIdentifier, listSessions, unknownOption, prompt, } = parseArgs(process.argv);
|
|
298
|
+
if (version) {
|
|
299
|
+
console.log(formatVersionLine());
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
344
302
|
if (help) {
|
|
345
303
|
printUsage();
|
|
346
304
|
return;
|
|
347
305
|
}
|
|
306
|
+
if (unknownOption) {
|
|
307
|
+
console.error(`Unknown option: ${unknownOption}`);
|
|
308
|
+
console.error("Run 'ai --help' to see available commands and options.");
|
|
309
|
+
process.exitCode = 2;
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
348
312
|
if (command) {
|
|
349
313
|
await runAuthCommand(command, commandArgs);
|
|
350
314
|
return;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
export const AUTH_COMMANDS = new Set(['login', 'whoami', 'logout']);
|
|
2
|
+
export function parseArgs(argv) {
|
|
3
|
+
const args = argv.slice(2);
|
|
4
|
+
const firstArg = args[0];
|
|
5
|
+
const command = firstArg && AUTH_COMMANDS.has(firstArg) ? firstArg : null;
|
|
6
|
+
const commandArgs = command ? args.slice(1) : [];
|
|
7
|
+
let autoYes = false;
|
|
8
|
+
let help = false;
|
|
9
|
+
let version = false;
|
|
10
|
+
let usage = false;
|
|
11
|
+
let session = null;
|
|
12
|
+
let listSessions = false;
|
|
13
|
+
let unknownOption = null;
|
|
14
|
+
const promptParts = [];
|
|
15
|
+
for (let i = 0; i < args.length; i++) {
|
|
16
|
+
const arg = args[i];
|
|
17
|
+
if (arg === '--yes' || arg === '-y') {
|
|
18
|
+
autoYes = true;
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
if ((arg === '--session' || arg === '--resume') && i + 1 < args.length) {
|
|
22
|
+
session = args[i + 1] ?? null;
|
|
23
|
+
i += 1;
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
if (arg === '--list-sessions') {
|
|
27
|
+
listSessions = true;
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
if (arg === '--help' || arg === '-h') {
|
|
31
|
+
help = true;
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (arg === '--version' || arg === '-v') {
|
|
35
|
+
version = true;
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
if (arg === '--usage') {
|
|
39
|
+
usage = true;
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
// An unrecognized dashed token is a mistyped flag, not prompt text. Without
|
|
43
|
+
// an auth subcommand (whose flags are parsed separately) it would otherwise
|
|
44
|
+
// be swept into the prompt and silently start a billable session. Flag the
|
|
45
|
+
// first one so the caller can fail fast instead. Quoted prompts are a single
|
|
46
|
+
// argv entry with spaces, so they never look like a bare option here.
|
|
47
|
+
if (command === null && unknownOption === null && /^-/.test(arg)) {
|
|
48
|
+
unknownOption = arg;
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
promptParts.push(arg);
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
command,
|
|
55
|
+
commandArgs,
|
|
56
|
+
autoYes,
|
|
57
|
+
help,
|
|
58
|
+
version,
|
|
59
|
+
usage,
|
|
60
|
+
session,
|
|
61
|
+
listSessions,
|
|
62
|
+
unknownOption,
|
|
63
|
+
prompt: promptParts.join(' ').trim(),
|
|
64
|
+
};
|
|
65
|
+
}
|
package/dist/src/help-text.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
|
+
import { getCliVersion, getPlatformTag } from './version.js';
|
|
2
3
|
// The bound keys (Enter/Esc/Ctrl+C/Tab/arrows) are identical across platforms in
|
|
3
4
|
// a terminal. The one thing that genuinely differs is the terminal's paste
|
|
4
5
|
// shortcut, so surface the one for the host OS (right-click paste works
|
|
@@ -45,6 +46,7 @@ const HELP_MARKDOWN = [
|
|
|
45
46
|
'',
|
|
46
47
|
'- `-y, --yes` — start in Auto-Accept mode',
|
|
47
48
|
'- `-h, --help` — show this help',
|
|
49
|
+
'- `-v, --version` — print the version and exit',
|
|
48
50
|
'',
|
|
49
51
|
'## Modes',
|
|
50
52
|
'',
|
|
@@ -70,6 +72,7 @@ const HELP_MARKDOWN = [
|
|
|
70
72
|
'## Chat commands',
|
|
71
73
|
'',
|
|
72
74
|
'- `/help` — show this help',
|
|
75
|
+
'- `/about` — show version and platform info',
|
|
73
76
|
'- `/usage` — show account usage percentage and reset times',
|
|
74
77
|
'- `/model` — list supported models and pick one',
|
|
75
78
|
'- `/model <id>` — switch the active model without clearing history',
|
|
@@ -100,6 +103,17 @@ const HELP_MARKDOWN = [
|
|
|
100
103
|
'- For anything else, re-run the command and report the printed error',
|
|
101
104
|
' message — there is no client-side debug mode by design.',
|
|
102
105
|
].join('\n');
|
|
106
|
+
export function formatAboutCard() {
|
|
107
|
+
// Fenced so the column alignment survives terminal markdown rendering.
|
|
108
|
+
return [
|
|
109
|
+
'```',
|
|
110
|
+
'TheGitAI',
|
|
111
|
+
` Version ${getCliVersion()}`,
|
|
112
|
+
` Platform ${getPlatformTag()}`,
|
|
113
|
+
` Node ${process.version}`,
|
|
114
|
+
'```',
|
|
115
|
+
].join('\n');
|
|
116
|
+
}
|
|
103
117
|
export function formatHelpMarkdown() {
|
|
104
118
|
return HELP_MARKDOWN;
|
|
105
119
|
}
|
package/dist/src/ui/repl.js
CHANGED
|
@@ -11,7 +11,7 @@ import { applySessionSnapshot, listSessionMetadata, loadSessionSnapshot, saveSes
|
|
|
11
11
|
import { truncate } from '../utils.js';
|
|
12
12
|
import { writeClipboardText } from '../core/clipboard.js';
|
|
13
13
|
import { openUrl } from '../core/open-url.js';
|
|
14
|
-
import { formatInteractiveHelpText } from '../help-text.js';
|
|
14
|
+
import { formatAboutCard, formatInteractiveHelpText } from '../help-text.js';
|
|
15
15
|
import { expandPastedChunks, } from './paste-collapse.js';
|
|
16
16
|
import { loadPromptHistory, MAX_PROMPT_HISTORY_ENTRIES, } from './prompt-history-store.js';
|
|
17
17
|
const RESPONSE_STREAM_CHUNK_SIZE = 4;
|
|
@@ -86,6 +86,10 @@ export const SLASH_COMMANDS = [
|
|
|
86
86
|
command: '/help',
|
|
87
87
|
description: 'Show available chat commands',
|
|
88
88
|
},
|
|
89
|
+
{
|
|
90
|
+
command: '/about',
|
|
91
|
+
description: 'Show version and platform info',
|
|
92
|
+
},
|
|
89
93
|
{
|
|
90
94
|
command: '/usage',
|
|
91
95
|
description: 'Show account usage percentage and reset times',
|
|
@@ -1875,6 +1879,14 @@ export async function runClientInteractive({ appendPromptHistory, authConfig, de
|
|
|
1875
1879
|
});
|
|
1876
1880
|
return;
|
|
1877
1881
|
}
|
|
1882
|
+
if (input === '/about') {
|
|
1883
|
+
appendStaticEntry({
|
|
1884
|
+
body: formatAboutCard(),
|
|
1885
|
+
kind: 'system',
|
|
1886
|
+
title: 'About',
|
|
1887
|
+
});
|
|
1888
|
+
return;
|
|
1889
|
+
}
|
|
1878
1890
|
if (input === '/usage') {
|
|
1879
1891
|
store.update((current) => ({
|
|
1880
1892
|
...current,
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
const PACKAGE_NAME = '@thegitai/cli';
|
|
5
|
+
const UNKNOWN_VERSION = '0.0.0';
|
|
6
|
+
// Resolve the package version at runtime by walking up from this module to the
|
|
7
|
+
// nearest package.json named @thegitai/cli. This works in both layouts: the
|
|
8
|
+
// compiled binary (dist/bin/ai.js → ../../package.json) and the source tree run
|
|
9
|
+
// under tsx in tests (src/version.ts → ../package.json). The name guard avoids
|
|
10
|
+
// picking up an unrelated manifest if the file is ever nested elsewhere.
|
|
11
|
+
export function getCliVersion() {
|
|
12
|
+
let dir = path.dirname(fileURLToPath(import.meta.url));
|
|
13
|
+
for (let depth = 0; depth < 6; depth++) {
|
|
14
|
+
try {
|
|
15
|
+
const pkg = JSON.parse(readFileSync(path.join(dir, 'package.json'), 'utf8'));
|
|
16
|
+
if (pkg.name === PACKAGE_NAME && typeof pkg.version === 'string') {
|
|
17
|
+
return pkg.version;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
// No package.json at this level (or unreadable); keep walking up.
|
|
22
|
+
}
|
|
23
|
+
const parent = path.dirname(dir);
|
|
24
|
+
if (parent === dir)
|
|
25
|
+
break;
|
|
26
|
+
dir = parent;
|
|
27
|
+
}
|
|
28
|
+
return UNKNOWN_VERSION;
|
|
29
|
+
}
|
|
30
|
+
export function getPlatformTag() {
|
|
31
|
+
return `${process.platform}-${process.arch}`;
|
|
32
|
+
}
|
|
33
|
+
export function formatVersionLine() {
|
|
34
|
+
return `ai ${getCliVersion()} (${getPlatformTag()}, node ${process.version})`;
|
|
35
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thegitai/cli",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.6",
|
|
4
4
|
"description": "TheGitAI CLI client (source-visible, proprietary)",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"homepage": "https://thegit.ai",
|
|
@@ -27,10 +27,10 @@
|
|
|
27
27
|
"web-tree-sitter": "^0.26.6"
|
|
28
28
|
},
|
|
29
29
|
"optionalDependencies": {
|
|
30
|
-
"@thegitai/tui-darwin-arm64": "1.0.0-beta.
|
|
31
|
-
"@thegitai/tui-darwin-x64": "1.0.0-beta.
|
|
32
|
-
"@thegitai/tui-linux-x64": "1.0.0-beta.
|
|
33
|
-
"@thegitai/tui-win32-x64": "1.0.0-beta.
|
|
30
|
+
"@thegitai/tui-darwin-arm64": "1.0.0-beta.6",
|
|
31
|
+
"@thegitai/tui-darwin-x64": "1.0.0-beta.6",
|
|
32
|
+
"@thegitai/tui-linux-x64": "1.0.0-beta.6",
|
|
33
|
+
"@thegitai/tui-win32-x64": "1.0.0-beta.6"
|
|
34
34
|
},
|
|
35
35
|
"publishConfig": {
|
|
36
36
|
"access": "public"
|