@continuedev/continuous-ai 1.0.0 → 1.0.2

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 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>`
@@ -167,4 +167,4 @@ fi
167
167
 
168
168
  ## License
169
169
 
170
- MIT
170
+ Apache-2.0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@continuedev/continuous-ai",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "CLI tool for interacting with Continue agent checks on pull requests",
5
5
  "type": "module",
6
6
  "bin": {
@@ -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
+ }
@@ -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 <pr-url>')
10
- .description('Reject changes and close the PR')
11
- .option('--org <slug>', 'Organization context')
8
+ .command('reject <session-id>')
9
+ .description('Reject agent changes')
12
10
  .option('--token <key>', 'API key')
13
- .option('--reason <text>', 'Optional rejection reason')
14
- .action(async (prUrl, options) => {
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
- // Reject PR
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);
@@ -27,7 +27,7 @@ export function statusCommand(program) {
27
27
  organizationId: options.org,
28
28
  });
29
29
 
30
- const sessions = result.sessions || [];
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 { approveCommand } from './commands/approve.js';
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 checks on pull requests')
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
- approveCommand(program);
22
+ acceptCommand(program);
23
23
  rejectCommand(program);
24
24
 
25
25
  program.parse(process.argv);
@@ -123,27 +123,23 @@ export class ApiClient {
123
123
  }
124
124
 
125
125
  /**
126
- * Approve a PR and optionally merge
126
+ * Accept agent changes and push to GitHub
127
127
  */
128
- async approvePr(pullRequestUrl, options = {}) {
129
- const { organizationSlug, autoMerge = false, mergeMethod = 'squash' } = options;
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
- * Reject a PR (close it)
133
+ * Accept agent changes for local application (marks as accepted without pushing)
140
134
  */
141
- async rejectPr(pullRequestUrl, options = {}) {
142
- const { organizationSlug, reason } = options;
143
- return this.post('/agents/reject-pr', {
144
- pullRequestUrl,
145
- organizationSlug,
146
- reason,
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
  }
@@ -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:
@@ -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
- }