@agentuity/cli 1.0.13 → 1.0.15
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 +8 -0
- package/dist/agent-detection.js +2 -2
- package/dist/agent-detection.js.map +1 -1
- package/dist/banner.js +2 -2
- package/dist/banner.js.map +1 -1
- package/dist/bun-path.d.ts.map +1 -1
- package/dist/bun-path.js +2 -1
- package/dist/bun-path.js.map +1 -1
- package/dist/cmd/build/ast.d.ts.map +1 -1
- package/dist/cmd/build/ast.js +87 -14
- package/dist/cmd/build/ast.js.map +1 -1
- package/dist/cmd/build/vite/agent-discovery.d.ts.map +1 -1
- package/dist/cmd/build/vite/agent-discovery.js +3 -2
- package/dist/cmd/build/vite/agent-discovery.js.map +1 -1
- package/dist/cmd/build/vite/metadata-generator.d.ts.map +1 -1
- package/dist/cmd/build/vite/metadata-generator.js +2 -1
- package/dist/cmd/build/vite/metadata-generator.js.map +1 -1
- package/dist/cmd/build/vite/registry-generator.d.ts.map +1 -1
- package/dist/cmd/build/vite/registry-generator.js +9 -7
- package/dist/cmd/build/vite/registry-generator.js.map +1 -1
- package/dist/cmd/build/vite/route-discovery.d.ts.map +1 -1
- package/dist/cmd/build/vite/route-discovery.js +3 -2
- package/dist/cmd/build/vite/route-discovery.js.map +1 -1
- package/dist/cmd/cloud/deploy.d.ts.map +1 -1
- package/dist/cmd/cloud/deploy.js +19 -21
- 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 +3 -26
- package/dist/cmd/cloud/env/delete.js.map +1 -1
- package/dist/cmd/cloud/env/import.d.ts.map +1 -1
- package/dist/cmd/cloud/env/import.js +3 -16
- package/dist/cmd/cloud/env/import.js.map +1 -1
- package/dist/cmd/cloud/env/set.d.ts.map +1 -1
- package/dist/cmd/cloud/env/set.js +3 -19
- package/dist/cmd/cloud/env/set.js.map +1 -1
- package/dist/cmd/cloud/sandbox/cp.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/cp.js +2 -1
- package/dist/cmd/cloud/sandbox/cp.js.map +1 -1
- package/dist/cmd/git/account/add.d.ts +6 -8
- package/dist/cmd/git/account/add.d.ts.map +1 -1
- package/dist/cmd/git/account/add.js +37 -151
- package/dist/cmd/git/account/add.js.map +1 -1
- package/dist/cmd/git/account/index.d.ts +0 -1
- package/dist/cmd/git/account/index.d.ts.map +1 -1
- package/dist/cmd/git/account/index.js +3 -4
- package/dist/cmd/git/account/index.js.map +1 -1
- package/dist/cmd/git/account/list.d.ts.map +1 -1
- package/dist/cmd/git/account/list.js +35 -67
- package/dist/cmd/git/account/list.js.map +1 -1
- package/dist/cmd/git/account/remove.d.ts.map +1 -1
- package/dist/cmd/git/account/remove.js +42 -84
- package/dist/cmd/git/account/remove.js.map +1 -1
- package/dist/cmd/git/api.d.ts +19 -23
- package/dist/cmd/git/api.d.ts.map +1 -1
- package/dist/cmd/git/api.js +38 -56
- package/dist/cmd/git/api.js.map +1 -1
- package/dist/cmd/git/identity/connect.d.ts +15 -0
- package/dist/cmd/git/identity/connect.d.ts.map +1 -0
- package/dist/cmd/git/identity/connect.js +135 -0
- package/dist/cmd/git/identity/connect.js.map +1 -0
- package/dist/cmd/git/identity/disconnect.d.ts +2 -0
- package/dist/cmd/git/identity/disconnect.d.ts.map +1 -0
- package/dist/cmd/git/identity/disconnect.js +83 -0
- package/dist/cmd/git/identity/disconnect.js.map +1 -0
- package/dist/cmd/git/identity/index.d.ts +2 -0
- package/dist/cmd/git/identity/index.d.ts.map +1 -0
- package/dist/cmd/git/identity/index.js +10 -0
- package/dist/cmd/git/identity/index.js.map +1 -0
- package/dist/cmd/git/identity/status.d.ts +2 -0
- package/dist/cmd/git/identity/status.d.ts.map +1 -0
- package/dist/cmd/git/identity/status.js +77 -0
- package/dist/cmd/git/identity/status.js.map +1 -0
- package/dist/cmd/git/index.d.ts +0 -1
- package/dist/cmd/git/index.d.ts.map +1 -1
- package/dist/cmd/git/index.js +3 -2
- package/dist/cmd/git/index.js.map +1 -1
- package/dist/cmd/git/link.d.ts +2 -3
- package/dist/cmd/git/link.d.ts.map +1 -1
- package/dist/cmd/git/link.js +22 -28
- package/dist/cmd/git/link.js.map +1 -1
- package/dist/cmd/git/list.d.ts.map +1 -1
- package/dist/cmd/git/list.js +42 -55
- package/dist/cmd/git/list.js.map +1 -1
- package/dist/cmd/git/status.d.ts.map +1 -1
- package/dist/cmd/git/status.js +51 -38
- package/dist/cmd/git/status.js.map +1 -1
- package/dist/cmd/upgrade/npm-availability.d.ts +6 -7
- package/dist/cmd/upgrade/npm-availability.d.ts.map +1 -1
- package/dist/cmd/upgrade/npm-availability.js +9 -18
- package/dist/cmd/upgrade/npm-availability.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +14 -4
- package/dist/config.js.map +1 -1
- package/dist/utils/detectSubagent.d.ts.map +1 -1
- package/dist/utils/detectSubagent.js +3 -0
- package/dist/utils/detectSubagent.js.map +1 -1
- package/dist/utils/normalize-path.d.ts +11 -0
- package/dist/utils/normalize-path.d.ts.map +1 -0
- package/dist/utils/normalize-path.js +13 -0
- package/dist/utils/normalize-path.js.map +1 -0
- package/dist/utils/zip.d.ts.map +1 -1
- package/dist/utils/zip.js +2 -1
- package/dist/utils/zip.js.map +1 -1
- package/package.json +6 -6
- package/src/agent-detection.ts +2 -2
- package/src/banner.ts +2 -2
- package/src/bun-path.ts +2 -1
- package/src/cmd/build/ast.ts +96 -15
- package/src/cmd/build/vite/agent-discovery.ts +3 -2
- package/src/cmd/build/vite/metadata-generator.ts +2 -1
- package/src/cmd/build/vite/registry-generator.ts +9 -7
- package/src/cmd/build/vite/route-discovery.ts +3 -2
- package/src/cmd/cloud/deploy.ts +54 -61
- package/src/cmd/cloud/env/delete.ts +3 -34
- package/src/cmd/cloud/env/import.ts +2 -18
- package/src/cmd/cloud/env/set.ts +2 -21
- package/src/cmd/cloud/sandbox/cp.ts +2 -1
- package/src/cmd/git/account/add.ts +51 -190
- package/src/cmd/git/account/index.ts +3 -5
- package/src/cmd/git/account/list.ts +51 -82
- package/src/cmd/git/account/remove.ts +45 -95
- package/src/cmd/git/api.ts +49 -111
- package/src/cmd/git/identity/connect.ts +178 -0
- package/src/cmd/git/identity/disconnect.ts +103 -0
- package/src/cmd/git/identity/index.ts +10 -0
- package/src/cmd/git/identity/status.ts +96 -0
- package/src/cmd/git/index.ts +3 -3
- package/src/cmd/git/link.ts +32 -35
- package/src/cmd/git/list.ts +48 -59
- package/src/cmd/git/status.ts +55 -40
- package/src/cmd/upgrade/npm-availability.ts +14 -23
- package/src/config.ts +14 -5
- package/src/utils/detectSubagent.ts +5 -0
- package/src/utils/normalize-path.ts +12 -0
- package/src/utils/zip.ts +2 -1
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { getCommand } from '../../../command-prefix';
|
|
3
|
+
import { ErrorCode } from '../../../errors';
|
|
4
|
+
import * as tui from '../../../tui';
|
|
5
|
+
import { createSubcommand } from '../../../types';
|
|
6
|
+
import { disconnectGithubIntegration, getGithubIntegrationStatus } from '../api';
|
|
7
|
+
|
|
8
|
+
const DisconnectOptionsSchema = z.object({
|
|
9
|
+
confirm: z.boolean().optional().describe('Skip confirmation prompt'),
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
const DisconnectResponseSchema = z.object({
|
|
13
|
+
disconnected: z.boolean().describe('Whether the identity was disconnected'),
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
export const disconnectSubcommand = createSubcommand({
|
|
17
|
+
name: 'disconnect',
|
|
18
|
+
description: 'Disconnect your GitHub identity and all installations',
|
|
19
|
+
tags: ['mutating', 'destructive', 'slow'],
|
|
20
|
+
idempotent: false,
|
|
21
|
+
requires: { auth: true, apiClient: true },
|
|
22
|
+
schema: {
|
|
23
|
+
options: DisconnectOptionsSchema,
|
|
24
|
+
response: DisconnectResponseSchema,
|
|
25
|
+
},
|
|
26
|
+
examples: [
|
|
27
|
+
{
|
|
28
|
+
command: getCommand('git identity disconnect'),
|
|
29
|
+
description: 'Disconnect your GitHub identity',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
command: getCommand('git identity disconnect --confirm'),
|
|
33
|
+
description: 'Disconnect without confirmation prompt',
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
|
|
37
|
+
async handler(ctx) {
|
|
38
|
+
const { logger, apiClient, opts, options } = ctx;
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
const status = await tui.spinner({
|
|
42
|
+
message: 'Checking GitHub connection...',
|
|
43
|
+
clearOnSuccess: true,
|
|
44
|
+
callback: () => getGithubIntegrationStatus(apiClient),
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
if (!status.connected || !status.identity) {
|
|
48
|
+
if (!options.json) {
|
|
49
|
+
tui.newline();
|
|
50
|
+
tui.info('No GitHub identity connected.');
|
|
51
|
+
}
|
|
52
|
+
return { disconnected: false };
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (!opts.confirm) {
|
|
56
|
+
tui.newline();
|
|
57
|
+
tui.output(
|
|
58
|
+
`Connected as ${tui.bold(status.identity.githubUsername)} with ${status.installations.length} installation${status.installations.length !== 1 ? 's' : ''}.`
|
|
59
|
+
);
|
|
60
|
+
tui.newline();
|
|
61
|
+
|
|
62
|
+
const confirmed = await tui.confirm(
|
|
63
|
+
'Are you sure you want to disconnect your GitHub identity?'
|
|
64
|
+
);
|
|
65
|
+
if (!confirmed) {
|
|
66
|
+
tui.info('Cancelled');
|
|
67
|
+
return { disconnected: false };
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
await tui.spinner({
|
|
72
|
+
message: 'Disconnecting GitHub identity...',
|
|
73
|
+
clearOnSuccess: true,
|
|
74
|
+
callback: () => disconnectGithubIntegration(apiClient),
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
if (!options.json) {
|
|
78
|
+
tui.newline();
|
|
79
|
+
tui.success('Disconnected GitHub identity and all installations');
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return { disconnected: true };
|
|
83
|
+
} catch (error) {
|
|
84
|
+
const isCancel =
|
|
85
|
+
error === '' ||
|
|
86
|
+
(error instanceof Error &&
|
|
87
|
+
(error.message === '' || error.message === 'User cancelled'));
|
|
88
|
+
|
|
89
|
+
if (isCancel) {
|
|
90
|
+
tui.newline();
|
|
91
|
+
tui.info('Cancelled');
|
|
92
|
+
return { disconnected: false };
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
logger.trace(error);
|
|
96
|
+
return logger.fatal(
|
|
97
|
+
'Failed to disconnect GitHub identity: %s',
|
|
98
|
+
error,
|
|
99
|
+
ErrorCode.INTEGRATION_FAILED
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { createCommand } from '../../../types';
|
|
2
|
+
import { connectSubcommand } from './connect';
|
|
3
|
+
import { disconnectSubcommand } from './disconnect';
|
|
4
|
+
import { statusSubcommand } from './status';
|
|
5
|
+
|
|
6
|
+
export const identityCommand = createCommand({
|
|
7
|
+
name: 'identity',
|
|
8
|
+
description: 'Manage your GitHub identity',
|
|
9
|
+
subcommands: [connectSubcommand, disconnectSubcommand, statusSubcommand],
|
|
10
|
+
});
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { getCommand } from '../../../command-prefix';
|
|
3
|
+
import { ErrorCode } from '../../../errors';
|
|
4
|
+
import * as tui from '../../../tui';
|
|
5
|
+
import { createSubcommand } from '../../../types';
|
|
6
|
+
import { getGithubIntegrationStatus } from '../api';
|
|
7
|
+
|
|
8
|
+
const StatusResponseSchema = z.object({
|
|
9
|
+
connected: z.boolean().describe('Whether a GitHub identity is connected'),
|
|
10
|
+
identity: z
|
|
11
|
+
.object({
|
|
12
|
+
githubUsername: z.string().describe('GitHub username'),
|
|
13
|
+
githubEmail: z.string().optional().describe('GitHub email'),
|
|
14
|
+
})
|
|
15
|
+
.nullable()
|
|
16
|
+
.describe('Connected GitHub identity'),
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
export const statusSubcommand = createSubcommand({
|
|
20
|
+
name: 'status',
|
|
21
|
+
description: 'Show your connected GitHub identity',
|
|
22
|
+
tags: ['read-only'],
|
|
23
|
+
idempotent: true,
|
|
24
|
+
requires: { auth: true, apiClient: true },
|
|
25
|
+
schema: {
|
|
26
|
+
response: StatusResponseSchema,
|
|
27
|
+
},
|
|
28
|
+
examples: [
|
|
29
|
+
{
|
|
30
|
+
command: getCommand('git identity status'),
|
|
31
|
+
description: 'Show your connected GitHub identity',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
command: getCommand('--json git identity status'),
|
|
35
|
+
description: 'Show identity in JSON format',
|
|
36
|
+
},
|
|
37
|
+
],
|
|
38
|
+
|
|
39
|
+
async handler(ctx) {
|
|
40
|
+
const { logger, apiClient, options } = ctx;
|
|
41
|
+
|
|
42
|
+
try {
|
|
43
|
+
const status = await tui.spinner({
|
|
44
|
+
message: 'Checking GitHub connection...',
|
|
45
|
+
clearOnSuccess: true,
|
|
46
|
+
callback: () => getGithubIntegrationStatus(apiClient),
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const result = {
|
|
50
|
+
connected: status.connected,
|
|
51
|
+
identity: status.identity
|
|
52
|
+
? {
|
|
53
|
+
githubUsername: status.identity.githubUsername,
|
|
54
|
+
githubEmail: status.identity.githubEmail,
|
|
55
|
+
}
|
|
56
|
+
: null,
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
if (options.json) {
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
tui.newline();
|
|
64
|
+
tui.output(tui.bold('GitHub Identity'));
|
|
65
|
+
tui.newline();
|
|
66
|
+
|
|
67
|
+
if (!status.connected || !status.identity) {
|
|
68
|
+
tui.output(
|
|
69
|
+
tui.muted(
|
|
70
|
+
`No GitHub identity connected. Run ${tui.bold('agentuity git identity connect')} to connect one.`
|
|
71
|
+
)
|
|
72
|
+
);
|
|
73
|
+
tui.newline();
|
|
74
|
+
return result;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
tui.output(
|
|
78
|
+
` ${tui.colorSuccess('✓')} Connected as ${tui.bold(status.identity.githubUsername)}`
|
|
79
|
+
);
|
|
80
|
+
if (status.identity.githubEmail) {
|
|
81
|
+
tui.output(` Email: ${status.identity.githubEmail}`);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
tui.newline();
|
|
85
|
+
|
|
86
|
+
return result;
|
|
87
|
+
} catch (error) {
|
|
88
|
+
logger.trace(error);
|
|
89
|
+
return logger.fatal(
|
|
90
|
+
'Failed to check GitHub identity: %s',
|
|
91
|
+
error,
|
|
92
|
+
ErrorCode.INTEGRATION_FAILED
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
});
|
package/src/cmd/git/index.ts
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { createCommand } from '../../types';
|
|
2
2
|
import { accountCommand } from './account';
|
|
3
|
+
import { identityCommand } from './identity';
|
|
3
4
|
import { linkSubcommand } from './link';
|
|
4
5
|
import { listSubcommand } from './list';
|
|
5
|
-
import { unlinkSubcommand } from './unlink';
|
|
6
6
|
import { statusSubcommand } from './status';
|
|
7
|
+
import { unlinkSubcommand } from './unlink';
|
|
7
8
|
|
|
8
9
|
export const gitCommand = createCommand({
|
|
9
10
|
name: 'git',
|
|
10
11
|
description: 'Manage GitHub integration and repository connections',
|
|
11
12
|
subcommands: [
|
|
13
|
+
identityCommand,
|
|
12
14
|
accountCommand,
|
|
13
15
|
linkSubcommand,
|
|
14
16
|
listSubcommand,
|
|
@@ -16,5 +18,3 @@ export const gitCommand = createCommand({
|
|
|
16
18
|
statusSubcommand,
|
|
17
19
|
],
|
|
18
20
|
});
|
|
19
|
-
|
|
20
|
-
export default gitCommand;
|
package/src/cmd/git/link.ts
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import * as tui from '../../tui';
|
|
3
|
-
import { getCommand } from '../../command-prefix';
|
|
4
|
-
import { ErrorCode } from '../../errors';
|
|
1
|
+
import type { Logger } from '@agentuity/core';
|
|
5
2
|
import enquirer from 'enquirer';
|
|
6
3
|
import { z } from 'zod';
|
|
4
|
+
import type { APIClient } from '../../api';
|
|
5
|
+
import { getCommand } from '../../command-prefix';
|
|
6
|
+
import { ErrorCode } from '../../errors';
|
|
7
|
+
import * as tui from '../../tui';
|
|
8
|
+
import { type Config, createSubcommand } from '../../types';
|
|
7
9
|
import {
|
|
10
|
+
type GithubInstallation,
|
|
11
|
+
type GithubRepo,
|
|
8
12
|
getGithubIntegrationStatus,
|
|
9
|
-
listGithubRepos,
|
|
10
|
-
linkProjectToRepo,
|
|
11
13
|
getProjectGithubStatus,
|
|
12
|
-
|
|
14
|
+
linkProjectToRepo,
|
|
15
|
+
listGithubRepos,
|
|
13
16
|
} from './api';
|
|
14
|
-
import
|
|
15
|
-
import type { Logger } from '@agentuity/core';
|
|
16
|
-
import { runGitAccountConnect } from './account/add';
|
|
17
|
+
import { runGitIdentityConnect } from './identity/connect';
|
|
17
18
|
|
|
18
19
|
export interface DetectedGitInfo {
|
|
19
20
|
repo: string | null;
|
|
@@ -60,7 +61,6 @@ export function detectGitInfo(): DetectedGitInfo {
|
|
|
60
61
|
export interface RunGitLinkOptions {
|
|
61
62
|
apiClient: APIClient;
|
|
62
63
|
projectId: string;
|
|
63
|
-
orgId: string;
|
|
64
64
|
logger: Logger;
|
|
65
65
|
branchOption?: string;
|
|
66
66
|
rootOption?: string;
|
|
@@ -84,7 +84,6 @@ export async function runGitLink(options: RunGitLinkOptions): Promise<RunGitLink
|
|
|
84
84
|
const {
|
|
85
85
|
apiClient,
|
|
86
86
|
projectId,
|
|
87
|
-
orgId,
|
|
88
87
|
logger,
|
|
89
88
|
branchOption,
|
|
90
89
|
rootOption,
|
|
@@ -120,12 +119,12 @@ export async function runGitLink(options: RunGitLinkOptions): Promise<RunGitLink
|
|
|
120
119
|
let githubStatus = await tui.spinner({
|
|
121
120
|
message: 'Checking GitHub connection...',
|
|
122
121
|
clearOnSuccess: true,
|
|
123
|
-
callback: () => getGithubIntegrationStatus(apiClient
|
|
122
|
+
callback: () => getGithubIntegrationStatus(apiClient),
|
|
124
123
|
});
|
|
125
124
|
|
|
126
|
-
if (!githubStatus.connected || githubStatus.
|
|
125
|
+
if (!githubStatus.connected || githubStatus.installations.length === 0) {
|
|
127
126
|
tui.newline();
|
|
128
|
-
tui.warning('No GitHub accounts connected
|
|
127
|
+
tui.warning('No GitHub accounts connected.');
|
|
129
128
|
tui.newline();
|
|
130
129
|
|
|
131
130
|
const wantConnect = await tui.confirm('Would you like to connect a GitHub account now?');
|
|
@@ -134,9 +133,8 @@ export async function runGitLink(options: RunGitLinkOptions): Promise<RunGitLink
|
|
|
134
133
|
return { linked: false, cancelled: true };
|
|
135
134
|
}
|
|
136
135
|
|
|
137
|
-
const connectResult = await
|
|
136
|
+
const connectResult = await runGitIdentityConnect({
|
|
138
137
|
apiClient,
|
|
139
|
-
orgId,
|
|
140
138
|
logger,
|
|
141
139
|
config,
|
|
142
140
|
});
|
|
@@ -148,9 +146,9 @@ export async function runGitLink(options: RunGitLinkOptions): Promise<RunGitLink
|
|
|
148
146
|
return { linked: false, noGithubConnected: true };
|
|
149
147
|
}
|
|
150
148
|
|
|
151
|
-
githubStatus = await getGithubIntegrationStatus(apiClient
|
|
149
|
+
githubStatus = await getGithubIntegrationStatus(apiClient);
|
|
152
150
|
|
|
153
|
-
if (!githubStatus.connected || githubStatus.
|
|
151
|
+
if (!githubStatus.connected || githubStatus.installations.length === 0) {
|
|
154
152
|
tui.error('GitHub connection failed. Please try again.');
|
|
155
153
|
return { linked: false, noGithubConnected: true };
|
|
156
154
|
}
|
|
@@ -165,7 +163,7 @@ export async function runGitLink(options: RunGitLinkOptions): Promise<RunGitLink
|
|
|
165
163
|
const allRepos = await tui.spinner({
|
|
166
164
|
message: 'Fetching available repositories...',
|
|
167
165
|
clearOnSuccess: true,
|
|
168
|
-
callback: () => listGithubRepos(apiClient
|
|
166
|
+
callback: () => listGithubRepos(apiClient),
|
|
169
167
|
});
|
|
170
168
|
|
|
171
169
|
if (allRepos.length === 0) {
|
|
@@ -198,14 +196,16 @@ export async function runGitLink(options: RunGitLinkOptions): Promise<RunGitLink
|
|
|
198
196
|
if (!selectedRepo) {
|
|
199
197
|
let repos = allRepos;
|
|
200
198
|
|
|
201
|
-
if (githubStatus.
|
|
199
|
+
if (githubStatus.installations.length > 1) {
|
|
202
200
|
tui.newline();
|
|
203
201
|
|
|
204
|
-
const accountChoices = githubStatus.
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
202
|
+
const accountChoices = githubStatus.installations.map(
|
|
203
|
+
(installation: GithubInstallation) => ({
|
|
204
|
+
name: installation.accountName,
|
|
205
|
+
value: installation.integrationId ?? installation.installationId,
|
|
206
|
+
message: `${installation.accountName} ${tui.muted(`(${installation.accountType})`)}`,
|
|
207
|
+
})
|
|
208
|
+
);
|
|
209
209
|
|
|
210
210
|
const accountResponse = await enquirer.prompt<{ integrationId: string }>({
|
|
211
211
|
type: 'select',
|
|
@@ -213,8 +213,10 @@ export async function runGitLink(options: RunGitLinkOptions): Promise<RunGitLink
|
|
|
213
213
|
message: 'Select a GitHub account',
|
|
214
214
|
choices: accountChoices,
|
|
215
215
|
result(name: string) {
|
|
216
|
-
// Return the value (
|
|
217
|
-
const choice = accountChoices.find(
|
|
216
|
+
// Return the value (integrationId) instead of the name
|
|
217
|
+
const choice = accountChoices.find(
|
|
218
|
+
(c: { name: string; value: string; message: string }) => c.name === name
|
|
219
|
+
);
|
|
218
220
|
return choice?.value ?? name;
|
|
219
221
|
},
|
|
220
222
|
});
|
|
@@ -222,7 +224,7 @@ export async function runGitLink(options: RunGitLinkOptions): Promise<RunGitLink
|
|
|
222
224
|
repos = await tui.spinner({
|
|
223
225
|
message: 'Fetching repositories...',
|
|
224
226
|
clearOnSuccess: true,
|
|
225
|
-
callback: () => listGithubRepos(apiClient,
|
|
227
|
+
callback: () => listGithubRepos(apiClient, accountResponse.integrationId),
|
|
226
228
|
});
|
|
227
229
|
|
|
228
230
|
if (repos.length === 0) {
|
|
@@ -254,7 +256,7 @@ export async function runGitLink(options: RunGitLinkOptions): Promise<RunGitLink
|
|
|
254
256
|
}
|
|
255
257
|
|
|
256
258
|
// Prompt for settings with defaults
|
|
257
|
-
const defaultBranch = branchOption ??
|
|
259
|
+
const defaultBranch = branchOption ?? selectedRepo.defaultBranch;
|
|
258
260
|
const defaultRoot = rootOption ?? '.';
|
|
259
261
|
|
|
260
262
|
tui.newline();
|
|
@@ -309,7 +311,6 @@ export async function runGitLink(options: RunGitLinkOptions): Promise<RunGitLink
|
|
|
309
311
|
autoDeploy: finalAutoDeploy,
|
|
310
312
|
previewDeploy: finalPreviewDeploy,
|
|
311
313
|
directory: directory === '.' ? undefined : directory,
|
|
312
|
-
integrationId: selectedRepo.integrationId,
|
|
313
314
|
}),
|
|
314
315
|
});
|
|
315
316
|
|
|
@@ -414,9 +415,6 @@ export const linkSubcommand = createSubcommand({
|
|
|
414
415
|
|
|
415
416
|
try {
|
|
416
417
|
// Non-interactive mode when repo is provided
|
|
417
|
-
// Note: integrationId is not passed in non-interactive mode. The API will
|
|
418
|
-
// attempt to find a matching integration based on the repo owner. This may
|
|
419
|
-
// fail if the org has multiple GitHub integrations with access to the same repo.
|
|
420
418
|
if (opts.repo && opts.confirm) {
|
|
421
419
|
const branch = opts.branch ?? 'main';
|
|
422
420
|
const directory = opts.root === '.' ? undefined : opts.root;
|
|
@@ -446,7 +444,6 @@ export const linkSubcommand = createSubcommand({
|
|
|
446
444
|
const result = await runGitLink({
|
|
447
445
|
apiClient,
|
|
448
446
|
projectId: project.projectId,
|
|
449
|
-
orgId: project.orgId,
|
|
450
447
|
logger,
|
|
451
448
|
branchOption: opts.branch,
|
|
452
449
|
rootOption: opts.root,
|
package/src/cmd/git/list.ts
CHANGED
|
@@ -1,20 +1,18 @@
|
|
|
1
|
-
import { createSubcommand } from '../../types';
|
|
2
|
-
import * as tui from '../../tui';
|
|
3
|
-
import { getCommand } from '../../command-prefix';
|
|
4
1
|
import enquirer from 'enquirer';
|
|
5
2
|
import { z } from 'zod';
|
|
6
|
-
import {
|
|
3
|
+
import { getCommand } from '../../command-prefix';
|
|
7
4
|
import { ErrorCode } from '../../errors';
|
|
8
|
-
import
|
|
5
|
+
import * as tui from '../../tui';
|
|
6
|
+
import { createSubcommand } from '../../types';
|
|
7
|
+
import { getGithubIntegrationStatus, listGithubRepos } from './api';
|
|
9
8
|
|
|
10
9
|
const ListOptionsSchema = z.object({
|
|
11
|
-
|
|
12
|
-
account: z.string().optional().describe('GitHub account/integration ID to filter by'),
|
|
10
|
+
account: z.string().optional().describe('GitHub account name to filter by'),
|
|
13
11
|
});
|
|
14
12
|
|
|
15
13
|
export const listSubcommand = createSubcommand({
|
|
16
14
|
name: 'list',
|
|
17
|
-
description: 'List GitHub repositories accessible to your
|
|
15
|
+
description: 'List GitHub repositories accessible to your account',
|
|
18
16
|
aliases: ['ls'],
|
|
19
17
|
tags: ['read-only'],
|
|
20
18
|
idempotent: true,
|
|
@@ -28,8 +26,8 @@ export const listSubcommand = createSubcommand({
|
|
|
28
26
|
description: 'List all accessible GitHub repositories',
|
|
29
27
|
},
|
|
30
28
|
{
|
|
31
|
-
command: getCommand('git list --org
|
|
32
|
-
description: 'List repos for a specific
|
|
29
|
+
command: getCommand('git list --account my-org'),
|
|
30
|
+
description: 'List repos for a specific GitHub account',
|
|
33
31
|
},
|
|
34
32
|
{
|
|
35
33
|
command: getCommand('--json git list'),
|
|
@@ -41,78 +39,69 @@ export const listSubcommand = createSubcommand({
|
|
|
41
39
|
const { logger, apiClient, opts, options } = ctx;
|
|
42
40
|
|
|
43
41
|
try {
|
|
44
|
-
//
|
|
45
|
-
const orgs = await tui.spinner({
|
|
46
|
-
message: 'Fetching organizations...',
|
|
47
|
-
clearOnSuccess: true,
|
|
48
|
-
callback: () => listOrganizations(apiClient),
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
if (orgs.length === 0) {
|
|
52
|
-
tui.error('No organizations found');
|
|
53
|
-
return [];
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// Select org
|
|
57
|
-
let orgId = opts.org;
|
|
58
|
-
if (!orgId) {
|
|
59
|
-
const firstOrg = orgs[0];
|
|
60
|
-
if (orgs.length === 1 && firstOrg) {
|
|
61
|
-
orgId = firstOrg.id;
|
|
62
|
-
} else {
|
|
63
|
-
tui.newline();
|
|
64
|
-
const orgChoices = orgs.map((o) => ({
|
|
65
|
-
name: o.id,
|
|
66
|
-
message: o.name,
|
|
67
|
-
}));
|
|
68
|
-
|
|
69
|
-
const response = await enquirer.prompt<{ orgId: string }>({
|
|
70
|
-
type: 'select',
|
|
71
|
-
name: 'orgId',
|
|
72
|
-
message: 'Select an organization',
|
|
73
|
-
choices: orgChoices,
|
|
74
|
-
});
|
|
75
|
-
orgId = response.orgId;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// Check GitHub integrations
|
|
42
|
+
// Check GitHub connection
|
|
80
43
|
const githubStatus = await tui.spinner({
|
|
81
44
|
message: 'Checking GitHub connection...',
|
|
82
45
|
clearOnSuccess: true,
|
|
83
|
-
callback: () => getGithubIntegrationStatus(apiClient
|
|
46
|
+
callback: () => getGithubIntegrationStatus(apiClient),
|
|
84
47
|
});
|
|
85
48
|
|
|
86
|
-
if (!githubStatus.connected || githubStatus.
|
|
49
|
+
if (!githubStatus.connected || githubStatus.installations.length === 0) {
|
|
87
50
|
tui.newline();
|
|
88
|
-
tui.error('No GitHub accounts connected
|
|
51
|
+
tui.error('No GitHub accounts connected.');
|
|
89
52
|
console.log(tui.muted(`Run ${tui.bold('agentuity git account add')} to connect one`));
|
|
90
53
|
return [];
|
|
91
54
|
}
|
|
92
55
|
|
|
93
|
-
// Select
|
|
94
|
-
let integrationId
|
|
95
|
-
|
|
56
|
+
// Select installation if multiple and not specified
|
|
57
|
+
let integrationId: string | undefined;
|
|
58
|
+
|
|
59
|
+
if (opts.account) {
|
|
60
|
+
// Match by account name
|
|
61
|
+
const matched = githubStatus.installations.find(
|
|
62
|
+
(inst) => inst.accountName.toLowerCase() === opts.account!.toLowerCase()
|
|
63
|
+
);
|
|
64
|
+
if (!matched) {
|
|
65
|
+
tui.newline();
|
|
66
|
+
tui.error(`No installation found for account "${opts.account}"`);
|
|
67
|
+
console.log(
|
|
68
|
+
tui.muted(
|
|
69
|
+
`Available: ${githubStatus.installations.map((i) => i.accountName).join(', ')}`
|
|
70
|
+
)
|
|
71
|
+
);
|
|
72
|
+
return [];
|
|
73
|
+
}
|
|
74
|
+
integrationId = matched.integrationId;
|
|
75
|
+
} else if (githubStatus.installations.length > 1) {
|
|
96
76
|
tui.newline();
|
|
97
|
-
const accountChoices = githubStatus.
|
|
98
|
-
name:
|
|
99
|
-
message: `${
|
|
77
|
+
const accountChoices = githubStatus.installations.map((installation) => ({
|
|
78
|
+
name: installation.installationId,
|
|
79
|
+
message: `${installation.accountName} ${tui.muted(`(${installation.accountType})`)}`,
|
|
80
|
+
value: installation.integrationId,
|
|
100
81
|
}));
|
|
101
82
|
|
|
102
|
-
const response = await enquirer.prompt<{
|
|
83
|
+
const response = await enquirer.prompt<{ installationId: string }>({
|
|
103
84
|
type: 'select',
|
|
104
|
-
name: '
|
|
85
|
+
name: 'installationId',
|
|
105
86
|
message: 'Select a GitHub account',
|
|
106
87
|
choices: accountChoices,
|
|
88
|
+
result(name: string) {
|
|
89
|
+
// Return the value (integrationId) instead of the display name
|
|
90
|
+
const choice = accountChoices.find((c) => c.name === name);
|
|
91
|
+
return choice?.value ?? name;
|
|
92
|
+
},
|
|
107
93
|
});
|
|
108
|
-
integrationId = response.
|
|
94
|
+
integrationId = response.installationId;
|
|
95
|
+
} else {
|
|
96
|
+
// Single installation — use its integrationId
|
|
97
|
+
integrationId = githubStatus.installations[0]?.integrationId;
|
|
109
98
|
}
|
|
110
99
|
|
|
111
100
|
// Fetch repos
|
|
112
101
|
const repos = await tui.spinner({
|
|
113
102
|
message: 'Fetching repositories...',
|
|
114
103
|
clearOnSuccess: true,
|
|
115
|
-
callback: () => listGithubRepos(apiClient,
|
|
104
|
+
callback: () => listGithubRepos(apiClient, integrationId),
|
|
116
105
|
});
|
|
117
106
|
|
|
118
107
|
if (repos.length === 0) {
|