@agentic15.com/agentic15-claude-zen 4.2.1 → 4.2.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
@@ -128,9 +128,14 @@ npx agentic15 commit
128
128
 
129
129
  **On GitHub:**
130
130
  1. Review and merge the PR
131
- 2. Continue to next task:
132
131
 
132
+ **Back in Your Terminal:**
133
133
  ```bash
134
+ # Sync with main branch after PR merge
135
+ npx agentic15 sync
136
+ # This will: switch to main, pull changes, delete feature branch
137
+
138
+ # Continue to next task
134
139
  npx agentic15 task next
135
140
  ```
136
141
 
@@ -147,6 +152,7 @@ npx agentic15 task next
147
152
  | `npx agentic15 task start TASK-XXX` | Start specific task |
148
153
  | `npx agentic15 task status` | View current progress |
149
154
  | `npx agentic15 commit` | Commit, push, and create PR |
155
+ | `npx agentic15 sync` | Sync with main branch after PR merge |
150
156
  | `npx agentic15 visual-test <url>` | Capture UI screenshots and console errors |
151
157
  | `npx agentic15 upgrade` | Update framework files |
152
158
  | `npx agentic15 auth` | Configure GitHub authentication |
@@ -163,7 +169,7 @@ The framework automates:
163
169
  ### Standard Workflow
164
170
 
165
171
  ```
166
- plan → task → code → commit → PR → merge → next task
172
+ plan → task → code → commit → PR → merge → sync → next task
167
173
  ```
168
174
 
169
175
  ---
package/bin/agentic15.js CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
2
2
 
3
3
  import { Command } from 'commander';
4
4
  import { AuthCommand } from '../src/cli/AuthCommand.js';
@@ -8,6 +8,7 @@ import { StatusCommand } from '../src/cli/StatusCommand.js';
8
8
  import { PlanCommand } from '../src/cli/PlanCommand.js';
9
9
  import { UpgradeCommand } from '../src/cli/UpgradeCommand.js';
10
10
  import { VisualTestCommand } from '../src/cli/VisualTestCommand.js';
11
+ import { SyncCommand } from '../src/cli/SyncCommand.js';
11
12
 
12
13
  const program = new Command();
13
14
 
@@ -62,4 +63,10 @@ program
62
63
  .argument('<url>', 'URL to test (e.g., http://localhost:3000)')
63
64
  .action((url) => VisualTestCommand.execute(url));
64
65
 
66
+ // Sync with remote main branch
67
+ program
68
+ .command('sync')
69
+ .description('Switch to main branch, pull latest changes, and cleanup feature branch')
70
+ .action(() => SyncCommand.execute());
71
+
65
72
  program.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentic15.com/agentic15-claude-zen",
3
- "version": "4.2.1",
3
+ "version": "4.2.2",
4
4
  "description": "Structured AI-assisted development framework for Claude Code with enforced quality standards",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -0,0 +1,137 @@
1
+ import { execSync } from 'child_process';
2
+ import { readFileSync, existsSync } from 'fs';
3
+ import { join } from 'path';
4
+
5
+ export class SyncCommand {
6
+ static execute() {
7
+ console.log('\n🔄 Syncing with remote main branch...\n');
8
+
9
+ // Step 1: Get current branch
10
+ const currentBranch = this.getCurrentBranch();
11
+ console.log(`📍 Current branch: ${currentBranch}\n`);
12
+
13
+ // Step 2: Check if on feature branch
14
+ const isFeatureBranch = currentBranch.startsWith('feature/');
15
+
16
+ if (!isFeatureBranch && currentBranch !== 'main') {
17
+ console.log(`⚠️ You're on branch '${currentBranch}', not a feature branch`);
18
+ console.log(` This command syncs feature branches with main\n`);
19
+ process.exit(1);
20
+ }
21
+
22
+ // Step 3: Check for uncommitted changes
23
+ if (this.hasUncommittedChanges()) {
24
+ console.log('❌ You have uncommitted changes');
25
+ console.log(' Commit or stash them first\n');
26
+ process.exit(1);
27
+ }
28
+
29
+ // Step 4: Get main branch name
30
+ const mainBranch = this.getMainBranch();
31
+ console.log(`🎯 Main branch: ${mainBranch}\n`);
32
+
33
+ // Step 5: Switch to main
34
+ console.log(`📦 Switching to ${mainBranch}...\n`);
35
+ this.switchToMain(mainBranch);
36
+
37
+ // Step 6: Pull latest changes
38
+ console.log('⬇️ Pulling latest changes...\n');
39
+ this.pullMain(mainBranch);
40
+
41
+ // Step 7: Delete feature branch if we were on one
42
+ if (isFeatureBranch) {
43
+ console.log(`🗑️ Cleaning up feature branch: ${currentBranch}...\n`);
44
+ this.deleteFeatureBranch(currentBranch);
45
+ }
46
+
47
+ // Step 8: Display summary
48
+ this.displaySummary(mainBranch, currentBranch, isFeatureBranch);
49
+ }
50
+
51
+ static getCurrentBranch() {
52
+ try {
53
+ return execSync('git branch --show-current', { encoding: 'utf-8' }).trim();
54
+ } catch (error) {
55
+ console.log(`\n❌ Failed to get current branch: ${error.message}\n`);
56
+ process.exit(1);
57
+ }
58
+ }
59
+
60
+ static getMainBranch() {
61
+ try {
62
+ // Try to detect main branch from remote
63
+ const remotes = execSync('git branch -r', { encoding: 'utf-8' });
64
+
65
+ if (remotes.includes('origin/main')) {
66
+ return 'main';
67
+ } else if (remotes.includes('origin/master')) {
68
+ return 'master';
69
+ }
70
+
71
+ // Default to main
72
+ return 'main';
73
+ } catch (error) {
74
+ return 'main';
75
+ }
76
+ }
77
+
78
+ static hasUncommittedChanges() {
79
+ try {
80
+ const status = execSync('git status --porcelain', { encoding: 'utf-8' });
81
+ return status.trim().length > 0;
82
+ } catch (error) {
83
+ return false;
84
+ }
85
+ }
86
+
87
+ static switchToMain(mainBranch) {
88
+ try {
89
+ execSync(`git checkout ${mainBranch}`, { stdio: 'inherit' });
90
+ } catch (error) {
91
+ console.log(`\n❌ Failed to switch to ${mainBranch}: ${error.message}\n`);
92
+ process.exit(1);
93
+ }
94
+ }
95
+
96
+ static pullMain(mainBranch) {
97
+ try {
98
+ execSync(`git pull origin ${mainBranch}`, { stdio: 'inherit' });
99
+ } catch (error) {
100
+ console.log(`\n❌ Failed to pull from ${mainBranch}: ${error.message}\n`);
101
+ process.exit(1);
102
+ }
103
+ }
104
+
105
+ static deleteFeatureBranch(branchName) {
106
+ try {
107
+ // Delete local branch
108
+ execSync(`git branch -d ${branchName}`, { stdio: 'inherit' });
109
+ console.log(` ✓ Deleted local branch: ${branchName}`);
110
+ } catch (error) {
111
+ // Branch might have unmerged commits, try force delete
112
+ try {
113
+ console.log(` ⚠️ Branch has unmerged commits, force deleting...`);
114
+ execSync(`git branch -D ${branchName}`, { stdio: 'inherit' });
115
+ console.log(` ✓ Force deleted local branch: ${branchName}`);
116
+ } catch (forceError) {
117
+ console.log(` ⚠️ Could not delete branch: ${forceError.message}`);
118
+ }
119
+ }
120
+ }
121
+
122
+ static displaySummary(mainBranch, previousBranch, wasFeatureBranch) {
123
+ console.log('\n' + '='.repeat(60));
124
+ console.log('✅ Sync complete!');
125
+ console.log('='.repeat(60));
126
+ console.log(`\n📍 Current branch: ${mainBranch}`);
127
+ console.log(`📥 Latest changes pulled from origin/${mainBranch}`);
128
+
129
+ if (wasFeatureBranch) {
130
+ console.log(`🗑️ Deleted feature branch: ${previousBranch}`);
131
+ }
132
+
133
+ console.log('\n💡 Next steps:');
134
+ console.log(' 1. Start a new task: npx agentic15 task start TASK-XXX');
135
+ console.log(' 2. Check status: npx agentic15 status\n');
136
+ }
137
+ }