@continuedev/continuous-ai 1.0.1 → 1.0.3
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 -1
- package/package.json +1 -1
- package/src/commands/accept.js +62 -0
- package/src/commands/reject.js +6 -24
- package/src/commands/status.js +1 -1
- package/src/index.js +3 -3
- package/src/lib/api-client.js +13 -17
- package/src/lib/formatters.js +2 -1
- package/src/commands/approve.js +0 -52
package/README.md
CHANGED
|
@@ -87,7 +87,7 @@ cai approve https://github.com/owner/repo/pull/123 --merge
|
|
|
87
87
|
Options:
|
|
88
88
|
- `--org <slug>` - Organization context
|
|
89
89
|
- `--token <key>` - API key
|
|
90
|
-
- `--merge` - Also merge the PR (default: just mark ready)
|
|
90
|
+
- `--merge` - Also merge the PR (default: just mark as ready)
|
|
91
91
|
- `--merge-method squash|merge|rebase` - Merge method (default: squash)
|
|
92
92
|
|
|
93
93
|
#### `cai reject <pr-url>`
|
package/package.json
CHANGED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { execSync } from 'child_process';
|
|
3
|
+
import { getApiKey, getApiUrl, requireApiKey } from '../lib/auth.js';
|
|
4
|
+
import { ApiClient } from '../lib/api-client.js';
|
|
5
|
+
import { createSpinner } from '../lib/formatters.js';
|
|
6
|
+
|
|
7
|
+
export function acceptCommand(program) {
|
|
8
|
+
program
|
|
9
|
+
.command('accept <session-id>')
|
|
10
|
+
.description('Accept agent changes (pushes to GitHub, or use --local to apply locally)')
|
|
11
|
+
.option('--token <key>', 'API key')
|
|
12
|
+
.option('--local', 'Apply diff locally instead of pushing to GitHub', false)
|
|
13
|
+
.action(async (sessionId, options) => {
|
|
14
|
+
const spinner = createSpinner(
|
|
15
|
+
options.local ? 'Accepting changes locally...' : 'Accepting and pushing to GitHub...'
|
|
16
|
+
);
|
|
17
|
+
try {
|
|
18
|
+
const apiKey = getApiKey(options.token);
|
|
19
|
+
requireApiKey(apiKey);
|
|
20
|
+
|
|
21
|
+
const client = new ApiClient(getApiUrl(), apiKey);
|
|
22
|
+
spinner.start();
|
|
23
|
+
|
|
24
|
+
if (options.local) {
|
|
25
|
+
// Fetch diff first
|
|
26
|
+
const diffResult = await client.getSessionDiff(sessionId);
|
|
27
|
+
const diff = diffResult.diff || diffResult;
|
|
28
|
+
|
|
29
|
+
if (!diff || diff.trim() === '') {
|
|
30
|
+
spinner.stop();
|
|
31
|
+
console.log(chalk.yellow('No changes to apply'));
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Mark as accepted in backend
|
|
36
|
+
await client.acceptCommitLocal(sessionId);
|
|
37
|
+
|
|
38
|
+
// Apply diff locally
|
|
39
|
+
try {
|
|
40
|
+
execSync('git apply', { input: diff, stdio: ['pipe', 'pipe', 'pipe'] });
|
|
41
|
+
spinner.stop();
|
|
42
|
+
console.log(chalk.green('✓') + ' Changes accepted and applied locally');
|
|
43
|
+
console.log(' You can now review and commit the changes yourself');
|
|
44
|
+
} catch (gitError) {
|
|
45
|
+
spinner.stop();
|
|
46
|
+
console.log(chalk.yellow('✓') + ' Marked as accepted, but failed to apply diff locally');
|
|
47
|
+
console.error(' Git error:', gitError.message);
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
} else {
|
|
51
|
+
// Accept and push to GitHub
|
|
52
|
+
await client.acceptCommit(sessionId);
|
|
53
|
+
spinner.stop();
|
|
54
|
+
console.log(chalk.green('✓') + ' Changes accepted and pushed to GitHub');
|
|
55
|
+
}
|
|
56
|
+
} catch (error) {
|
|
57
|
+
spinner.stop();
|
|
58
|
+
console.error('ERROR:', error.message);
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
}
|
package/src/commands/reject.js
CHANGED
|
@@ -1,44 +1,26 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import { getApiKey, getApiUrl, requireApiKey } from '../lib/auth.js';
|
|
3
3
|
import { ApiClient } from '../lib/api-client.js';
|
|
4
|
-
import { parsePrUrl } from '../lib/pr-parser.js';
|
|
5
4
|
import { createSpinner } from '../lib/formatters.js';
|
|
6
5
|
|
|
7
6
|
export function rejectCommand(program) {
|
|
8
7
|
program
|
|
9
|
-
.command('reject <
|
|
10
|
-
.description('Reject changes
|
|
11
|
-
.option('--org <slug>', 'Organization context')
|
|
8
|
+
.command('reject <session-id>')
|
|
9
|
+
.description('Reject agent changes')
|
|
12
10
|
.option('--token <key>', 'API key')
|
|
13
|
-
.
|
|
14
|
-
|
|
15
|
-
const spinner = createSpinner('Rejecting pull request...');
|
|
11
|
+
.action(async (sessionId, options) => {
|
|
12
|
+
const spinner = createSpinner('Rejecting changes...');
|
|
16
13
|
try {
|
|
17
|
-
// Get API key
|
|
18
14
|
const apiKey = getApiKey(options.token);
|
|
19
15
|
requireApiKey(apiKey);
|
|
20
16
|
|
|
21
|
-
// Parse PR URL
|
|
22
|
-
const pr = parsePrUrl(prUrl);
|
|
23
|
-
|
|
24
|
-
// Create API client
|
|
25
17
|
const client = new ApiClient(getApiUrl(), apiKey);
|
|
26
|
-
|
|
27
18
|
spinner.start();
|
|
28
19
|
|
|
29
|
-
|
|
30
|
-
const result = await client.rejectPr(pr.url, {
|
|
31
|
-
organizationSlug: options.org,
|
|
32
|
-
reason: options.reason,
|
|
33
|
-
});
|
|
20
|
+
await client.rejectCommit(sessionId);
|
|
34
21
|
|
|
35
22
|
spinner.stop();
|
|
36
|
-
|
|
37
|
-
console.log(chalk.red('✗') + ' Pull request rejected and closed.');
|
|
38
|
-
console.log(` ${prUrl}`);
|
|
39
|
-
if (options.reason) {
|
|
40
|
-
console.log(` Reason: ${options.reason}`);
|
|
41
|
-
}
|
|
23
|
+
console.log(chalk.green('✓') + ' Changes rejected');
|
|
42
24
|
} catch (error) {
|
|
43
25
|
spinner.stop();
|
|
44
26
|
console.error('ERROR:', error.message);
|
package/src/commands/status.js
CHANGED
|
@@ -27,7 +27,7 @@ export function statusCommand(program) {
|
|
|
27
27
|
organizationId: options.org,
|
|
28
28
|
});
|
|
29
29
|
|
|
30
|
-
const sessions = result.
|
|
30
|
+
const sessions = result.agents || [];
|
|
31
31
|
|
|
32
32
|
// Calculate summary
|
|
33
33
|
const terminalStates = ['completed', 'failed', 'cancelled', 'suspended'];
|
package/src/index.js
CHANGED
|
@@ -4,14 +4,14 @@ import { statusCommand } from './commands/status.js';
|
|
|
4
4
|
import { waitCommand } from './commands/wait.js';
|
|
5
5
|
import { logsCommand } from './commands/logs.js';
|
|
6
6
|
import { diffCommand } from './commands/diff.js';
|
|
7
|
-
import {
|
|
7
|
+
import { acceptCommand } from './commands/accept.js';
|
|
8
8
|
import { rejectCommand } from './commands/reject.js';
|
|
9
9
|
|
|
10
10
|
const program = new Command();
|
|
11
11
|
|
|
12
12
|
program
|
|
13
13
|
.name('cai')
|
|
14
|
-
.description('CLI tool for interacting with Continue agent
|
|
14
|
+
.description('CLI tool for interacting with Continue agent sessions')
|
|
15
15
|
.version('0.1.0');
|
|
16
16
|
|
|
17
17
|
// Register commands
|
|
@@ -19,7 +19,7 @@ statusCommand(program);
|
|
|
19
19
|
waitCommand(program);
|
|
20
20
|
logsCommand(program);
|
|
21
21
|
diffCommand(program);
|
|
22
|
-
|
|
22
|
+
acceptCommand(program);
|
|
23
23
|
rejectCommand(program);
|
|
24
24
|
|
|
25
25
|
program.parse(process.argv);
|
package/src/lib/api-client.js
CHANGED
|
@@ -123,27 +123,23 @@ export class ApiClient {
|
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
/**
|
|
126
|
-
*
|
|
126
|
+
* Accept agent changes and push to GitHub
|
|
127
127
|
*/
|
|
128
|
-
async
|
|
129
|
-
|
|
130
|
-
return this.post('/agents/approve-pr', {
|
|
131
|
-
pullRequestUrl,
|
|
132
|
-
organizationSlug,
|
|
133
|
-
autoMerge,
|
|
134
|
-
mergeMethod,
|
|
135
|
-
});
|
|
128
|
+
async acceptCommit(sessionId) {
|
|
129
|
+
return this.post(`/agents/${sessionId}/accept`);
|
|
136
130
|
}
|
|
137
131
|
|
|
138
132
|
/**
|
|
139
|
-
*
|
|
133
|
+
* Accept agent changes for local application (marks as accepted without pushing)
|
|
140
134
|
*/
|
|
141
|
-
async
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
135
|
+
async acceptCommitLocal(sessionId) {
|
|
136
|
+
return this.post(`/agents/${sessionId}/accept-local`);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Reject agent changes
|
|
141
|
+
*/
|
|
142
|
+
async rejectCommit(sessionId) {
|
|
143
|
+
return this.post(`/agents/${sessionId}/reject`);
|
|
148
144
|
}
|
|
149
145
|
}
|
package/src/lib/formatters.js
CHANGED
|
@@ -20,7 +20,7 @@ export function formatSessionsTable(sessions, summary) {
|
|
|
20
20
|
|
|
21
21
|
// Table rows
|
|
22
22
|
for (const session of sessions) {
|
|
23
|
-
const sessionId = session.
|
|
23
|
+
const sessionId = session.id.substring(0, 8);
|
|
24
24
|
const status = formatStatus(session.status);
|
|
25
25
|
const updated = formatRelativeTime(session.updatedAt);
|
|
26
26
|
|
|
@@ -57,6 +57,7 @@ function formatStatus(status) {
|
|
|
57
57
|
case 'pending':
|
|
58
58
|
return chalk.gray('⏸ Pending');
|
|
59
59
|
case 'suspended':
|
|
60
|
+
return chalk.gray('⚠ Suspended');
|
|
60
61
|
case 'cancelled':
|
|
61
62
|
return chalk.gray('⚠ Cancelled');
|
|
62
63
|
default:
|
package/src/commands/approve.js
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
import { getApiKey, getApiUrl, requireApiKey } from '../lib/auth.js';
|
|
3
|
-
import { ApiClient } from '../lib/api-client.js';
|
|
4
|
-
import { parsePrUrl } from '../lib/pr-parser.js';
|
|
5
|
-
import { createSpinner } from '../lib/formatters.js';
|
|
6
|
-
|
|
7
|
-
export function approveCommand(program) {
|
|
8
|
-
program
|
|
9
|
-
.command('approve <pr-url>')
|
|
10
|
-
.description('Approve changes and optionally merge the PR')
|
|
11
|
-
.option('--org <slug>', 'Organization context')
|
|
12
|
-
.option('--token <key>', 'API key')
|
|
13
|
-
.option('--merge', 'Also merge the PR', false)
|
|
14
|
-
.option('--merge-method <method>', 'Merge method (squash|merge|rebase)', 'squash')
|
|
15
|
-
.action(async (prUrl, options) => {
|
|
16
|
-
const spinner = createSpinner('Approving pull request...');
|
|
17
|
-
try {
|
|
18
|
-
// Get API key
|
|
19
|
-
const apiKey = getApiKey(options.token);
|
|
20
|
-
requireApiKey(apiKey);
|
|
21
|
-
|
|
22
|
-
// Parse PR URL
|
|
23
|
-
const pr = parsePrUrl(prUrl);
|
|
24
|
-
|
|
25
|
-
// Create API client
|
|
26
|
-
const client = new ApiClient(getApiUrl(), apiKey);
|
|
27
|
-
|
|
28
|
-
spinner.start();
|
|
29
|
-
|
|
30
|
-
// Approve PR
|
|
31
|
-
const result = await client.approvePr(pr.url, {
|
|
32
|
-
organizationSlug: options.org,
|
|
33
|
-
autoMerge: options.merge,
|
|
34
|
-
mergeMethod: options.mergeMethod,
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
spinner.stop();
|
|
38
|
-
|
|
39
|
-
if (result.merged) {
|
|
40
|
-
console.log(chalk.green('✓') + ' Pull request approved and merged!');
|
|
41
|
-
console.log(` ${prUrl}`);
|
|
42
|
-
} else {
|
|
43
|
-
console.log(chalk.green('✓') + ' Pull request marked as ready for review!');
|
|
44
|
-
console.log(` ${prUrl}`);
|
|
45
|
-
}
|
|
46
|
-
} catch (error) {
|
|
47
|
-
spinner.stop();
|
|
48
|
-
console.error('ERROR:', error.message);
|
|
49
|
-
process.exit(1);
|
|
50
|
-
}
|
|
51
|
-
});
|
|
52
|
-
}
|