s9n-devops-agent 1.2.1 → 1.3.1
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 +210 -56
- package/docs/INSTALLATION_GUIDE.md +366 -0
- package/docs/houserules.md +51 -0
- package/package.json +5 -1
- package/src/display-utils.cjs +350 -0
- package/src/file-coordinator.cjs +356 -0
- package/src/file-monitor-enhanced.cjs +338 -0
- package/src/house-rules-manager.js +443 -0
- package/src/session-coordinator.js +51 -6
- package/src/setup-cs-devops-agent.js +5 -3
- package/start-devops-session.sh +139 -0
|
@@ -0,0 +1,443 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* House Rules Version Manager
|
|
3
|
+
* ============================
|
|
4
|
+
*
|
|
5
|
+
* Manages versioning and updates of DevOps Agent sections in house rules.
|
|
6
|
+
* Allows intelligent updates while preserving user customizations.
|
|
7
|
+
*
|
|
8
|
+
* Each managed section includes:
|
|
9
|
+
* - Version marker: <!-- DEVOPS_AGENT_SECTION:name:version:checksum -->
|
|
10
|
+
* - Content checksum for change detection
|
|
11
|
+
* - End marker: <!-- END_DEVOPS_AGENT_SECTION:name -->
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import fs from 'fs';
|
|
15
|
+
import path from 'path';
|
|
16
|
+
import crypto from 'crypto';
|
|
17
|
+
import { fileURLToPath } from 'url';
|
|
18
|
+
import { dirname } from 'path';
|
|
19
|
+
|
|
20
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
21
|
+
const __dirname = dirname(__filename);
|
|
22
|
+
|
|
23
|
+
// Version of our house rules sections
|
|
24
|
+
const HOUSERULES_VERSION = '1.3.0';
|
|
25
|
+
|
|
26
|
+
// Managed sections with their content
|
|
27
|
+
const MANAGED_SECTIONS = {
|
|
28
|
+
'file-coordination': {
|
|
29
|
+
version: '1.3.0',
|
|
30
|
+
title: '## 🚨 CRITICAL: File Coordination Protocol (MUST FOLLOW)',
|
|
31
|
+
content: `**IMPORTANT: Always check the house rules at the beginning of each session!**
|
|
32
|
+
|
|
33
|
+
To prevent conflicts with other agents editing the same files, you MUST follow this protocol:
|
|
34
|
+
|
|
35
|
+
### Before Editing ANY Files:
|
|
36
|
+
|
|
37
|
+
1. **DECLARE YOUR INTENT FIRST**
|
|
38
|
+
Create a file at \`.file-coordination/active-edits/<your-name>-<session>.json\` with:
|
|
39
|
+
\`\`\`json
|
|
40
|
+
{
|
|
41
|
+
"agent": "<your-name>",
|
|
42
|
+
"session": "<session-id>",
|
|
43
|
+
"files": ["list", "of", "files", "you", "will", "edit"],
|
|
44
|
+
"operation": "edit",
|
|
45
|
+
"reason": "Brief description of what you're doing",
|
|
46
|
+
"declaredAt": "<current-ISO-8601-timestamp>",
|
|
47
|
+
"estimatedDuration": 300
|
|
48
|
+
}
|
|
49
|
+
\`\`\`
|
|
50
|
+
|
|
51
|
+
2. **CHECK FOR CONFLICTS**
|
|
52
|
+
- Read ALL files in \`.file-coordination/active-edits/\`
|
|
53
|
+
- If ANY other agent has declared the same files, you must:
|
|
54
|
+
- WAIT for them to finish, OR
|
|
55
|
+
- Choose different files to edit
|
|
56
|
+
|
|
57
|
+
3. **ONLY EDIT DECLARED FILES**
|
|
58
|
+
- Never edit files you haven't declared
|
|
59
|
+
- Stay within your declared scope
|
|
60
|
+
|
|
61
|
+
4. **RELEASE WHEN DONE**
|
|
62
|
+
- Delete your declaration file after completing edits
|
|
63
|
+
- Or move it to \`.file-coordination/completed-edits/\`
|
|
64
|
+
|
|
65
|
+
### If You Detect a Conflict:
|
|
66
|
+
- DO NOT proceed with edits
|
|
67
|
+
- Report the conflict to the user
|
|
68
|
+
- Wait or choose alternative files
|
|
69
|
+
|
|
70
|
+
### Helper Scripts Available:
|
|
71
|
+
- \`./scripts/coordination/check-file-availability.sh <files>\` - Check if files are available
|
|
72
|
+
- \`./scripts/coordination/declare-file-edits.sh <agent> <session> <files>\` - Declare your intent
|
|
73
|
+
- \`./scripts/coordination/release-file-edits.sh <agent> <session>\` - Release files after editing
|
|
74
|
+
|
|
75
|
+
**This coordination prevents wasted work and merge conflicts!**`
|
|
76
|
+
},
|
|
77
|
+
'core-principles': {
|
|
78
|
+
version: '1.0.0',
|
|
79
|
+
title: '## Core Principles',
|
|
80
|
+
content: `1. **Always preserve existing functionality** - Never break working code
|
|
81
|
+
2. **Follow existing patterns** - Match the codebase style and conventions
|
|
82
|
+
3. **Communicate clearly** - Document your changes and reasoning
|
|
83
|
+
4. **Coordinate with others** - Follow the file coordination protocol below`
|
|
84
|
+
},
|
|
85
|
+
'project-conventions': {
|
|
86
|
+
version: '1.0.0',
|
|
87
|
+
title: '## Project Conventions',
|
|
88
|
+
content: `### Code Style
|
|
89
|
+
- Follow existing indentation and formatting patterns
|
|
90
|
+
- Maintain consistent naming conventions used in the project
|
|
91
|
+
- Keep functions small and focused
|
|
92
|
+
- Write clear, descriptive variable and function names
|
|
93
|
+
|
|
94
|
+
### Git Workflow
|
|
95
|
+
- Write clear, descriptive commit messages
|
|
96
|
+
- Follow conventional commit format when applicable (feat:, fix:, docs:, etc.)
|
|
97
|
+
- Keep commits atomic and focused on a single change
|
|
98
|
+
- Never commit sensitive information or credentials
|
|
99
|
+
|
|
100
|
+
### Testing
|
|
101
|
+
- Write tests for new functionality
|
|
102
|
+
- Ensure existing tests pass before committing
|
|
103
|
+
- Update tests when changing functionality
|
|
104
|
+
|
|
105
|
+
### Documentation
|
|
106
|
+
- Update README files when adding new features
|
|
107
|
+
- Document complex logic with clear comments
|
|
108
|
+
- Keep API documentation up to date
|
|
109
|
+
- Update CHANGELOG for significant changes`
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
class HouseRulesManager {
|
|
114
|
+
constructor(projectRoot) {
|
|
115
|
+
this.projectRoot = projectRoot || process.cwd();
|
|
116
|
+
this.houseRulesPath = null;
|
|
117
|
+
this.findHouseRulesFile();
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Find existing house rules file
|
|
122
|
+
*/
|
|
123
|
+
findHouseRulesFile() {
|
|
124
|
+
const possiblePaths = [
|
|
125
|
+
'houserules.md',
|
|
126
|
+
'HOUSERULES.md',
|
|
127
|
+
'.github/HOUSERULES.md',
|
|
128
|
+
'docs/houserules.md',
|
|
129
|
+
'docs/HOUSERULES.md'
|
|
130
|
+
];
|
|
131
|
+
|
|
132
|
+
for (const relativePath of possiblePaths) {
|
|
133
|
+
const fullPath = path.join(this.projectRoot, relativePath);
|
|
134
|
+
if (fs.existsSync(fullPath)) {
|
|
135
|
+
this.houseRulesPath = fullPath;
|
|
136
|
+
return fullPath;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Calculate checksum for content
|
|
145
|
+
*/
|
|
146
|
+
calculateChecksum(content) {
|
|
147
|
+
return crypto.createHash('md5').update(content.trim()).digest('hex').substring(0, 8);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Create section marker
|
|
152
|
+
*/
|
|
153
|
+
createSectionMarker(sectionName, version, checksum) {
|
|
154
|
+
return `<!-- DEVOPS_AGENT_SECTION:${sectionName}:${version}:${checksum} -->`;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Create end marker
|
|
159
|
+
*/
|
|
160
|
+
createEndMarker(sectionName) {
|
|
161
|
+
return `<!-- END_DEVOPS_AGENT_SECTION:${sectionName} -->`;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Extract managed sections from existing house rules
|
|
166
|
+
*/
|
|
167
|
+
extractManagedSections(content) {
|
|
168
|
+
const sections = {};
|
|
169
|
+
const pattern = /<!-- DEVOPS_AGENT_SECTION:(\w+[-\w]*):([0-9.]+):([a-f0-9]+) -->([\s\S]*?)<!-- END_DEVOPS_AGENT_SECTION:\1 -->/g;
|
|
170
|
+
|
|
171
|
+
let match;
|
|
172
|
+
while ((match = pattern.exec(content)) !== null) {
|
|
173
|
+
sections[match[1]] = {
|
|
174
|
+
name: match[1],
|
|
175
|
+
version: match[2],
|
|
176
|
+
checksum: match[3],
|
|
177
|
+
content: match[4].trim(),
|
|
178
|
+
startIndex: match.index,
|
|
179
|
+
endIndex: match.index + match[0].length
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return sections;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Check if a section needs updating
|
|
188
|
+
*/
|
|
189
|
+
needsUpdate(sectionName, existingVersion, existingChecksum) {
|
|
190
|
+
const currentSection = MANAGED_SECTIONS[sectionName];
|
|
191
|
+
if (!currentSection) return false;
|
|
192
|
+
|
|
193
|
+
// Check version
|
|
194
|
+
if (this.compareVersions(currentSection.version, existingVersion) > 0) {
|
|
195
|
+
return true;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Check checksum (in case we updated content without version bump)
|
|
199
|
+
const currentChecksum = this.calculateChecksum(currentSection.content);
|
|
200
|
+
return currentChecksum !== existingChecksum;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Compare semantic versions
|
|
205
|
+
*/
|
|
206
|
+
compareVersions(v1, v2) {
|
|
207
|
+
const parts1 = v1.split('.').map(Number);
|
|
208
|
+
const parts2 = v2.split('.').map(Number);
|
|
209
|
+
|
|
210
|
+
for (let i = 0; i < 3; i++) {
|
|
211
|
+
if (parts1[i] > parts2[i]) return 1;
|
|
212
|
+
if (parts1[i] < parts2[i]) return -1;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
return 0;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Format a managed section with markers
|
|
220
|
+
*/
|
|
221
|
+
formatSection(sectionName) {
|
|
222
|
+
const section = MANAGED_SECTIONS[sectionName];
|
|
223
|
+
if (!section) return '';
|
|
224
|
+
|
|
225
|
+
const checksum = this.calculateChecksum(section.content);
|
|
226
|
+
const marker = this.createSectionMarker(sectionName, section.version, checksum);
|
|
227
|
+
const endMarker = this.createEndMarker(sectionName);
|
|
228
|
+
|
|
229
|
+
return `${marker}
|
|
230
|
+
${section.title}
|
|
231
|
+
|
|
232
|
+
${section.content}
|
|
233
|
+
${endMarker}`;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Create new house rules with all managed sections
|
|
238
|
+
*/
|
|
239
|
+
createNewHouseRules() {
|
|
240
|
+
const sections = [];
|
|
241
|
+
|
|
242
|
+
// Header
|
|
243
|
+
sections.push(`# House Rules for AI Agents
|
|
244
|
+
|
|
245
|
+
**IMPORTANT: All AI agents (Claude, Cline, Copilot, etc.) must read and follow these rules at the start of each session.**
|
|
246
|
+
`);
|
|
247
|
+
|
|
248
|
+
// Add managed sections
|
|
249
|
+
sections.push(this.formatSection('file-coordination'));
|
|
250
|
+
sections.push('');
|
|
251
|
+
sections.push(this.formatSection('core-principles'));
|
|
252
|
+
sections.push('');
|
|
253
|
+
sections.push(this.formatSection('project-conventions'));
|
|
254
|
+
|
|
255
|
+
return sections.join('\n');
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Update house rules intelligently
|
|
260
|
+
*/
|
|
261
|
+
async updateHouseRules(options = {}) {
|
|
262
|
+
const { createIfMissing = true, backupExisting = true } = options;
|
|
263
|
+
|
|
264
|
+
// Find or create house rules file
|
|
265
|
+
if (!this.houseRulesPath) {
|
|
266
|
+
if (!createIfMissing) {
|
|
267
|
+
return { updated: false, reason: 'No house rules file found' };
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
this.houseRulesPath = path.join(this.projectRoot, 'houserules.md');
|
|
271
|
+
const content = this.createNewHouseRules();
|
|
272
|
+
fs.writeFileSync(this.houseRulesPath, content);
|
|
273
|
+
|
|
274
|
+
return {
|
|
275
|
+
updated: true,
|
|
276
|
+
created: true,
|
|
277
|
+
path: this.houseRulesPath,
|
|
278
|
+
sections: Object.keys(MANAGED_SECTIONS)
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// Read existing content
|
|
283
|
+
const existingContent = fs.readFileSync(this.houseRulesPath, 'utf8');
|
|
284
|
+
const existingSections = this.extractManagedSections(existingContent);
|
|
285
|
+
|
|
286
|
+
// Check what needs updating
|
|
287
|
+
const updates = [];
|
|
288
|
+
const additions = [];
|
|
289
|
+
|
|
290
|
+
for (const [sectionName, sectionData] of Object.entries(MANAGED_SECTIONS)) {
|
|
291
|
+
if (existingSections[sectionName]) {
|
|
292
|
+
// Section exists - check if needs update
|
|
293
|
+
if (this.needsUpdate(sectionName, existingSections[sectionName].version, existingSections[sectionName].checksum)) {
|
|
294
|
+
updates.push(sectionName);
|
|
295
|
+
}
|
|
296
|
+
} else {
|
|
297
|
+
// Section doesn't exist - needs to be added
|
|
298
|
+
additions.push(sectionName);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// If no updates needed, return
|
|
303
|
+
if (updates.length === 0 && additions.length === 0) {
|
|
304
|
+
return { updated: false, reason: 'All sections are up to date' };
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// Create backup if requested
|
|
308
|
+
if (backupExisting) {
|
|
309
|
+
const backupPath = `${this.houseRulesPath}.backup.${Date.now()}`;
|
|
310
|
+
fs.copyFileSync(this.houseRulesPath, backupPath);
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// Build new content
|
|
314
|
+
let newContent = existingContent;
|
|
315
|
+
|
|
316
|
+
// Update existing sections
|
|
317
|
+
for (const sectionName of updates) {
|
|
318
|
+
const existingSection = existingSections[sectionName];
|
|
319
|
+
const newSection = this.formatSection(sectionName);
|
|
320
|
+
|
|
321
|
+
// Replace the old section with the new one
|
|
322
|
+
const beforeSection = newContent.substring(0, existingSection.startIndex);
|
|
323
|
+
const afterSection = newContent.substring(existingSection.endIndex);
|
|
324
|
+
newContent = beforeSection + newSection + afterSection;
|
|
325
|
+
|
|
326
|
+
// Recalculate positions for remaining sections
|
|
327
|
+
const diff = newSection.length - (existingSection.endIndex - existingSection.startIndex);
|
|
328
|
+
for (const section of Object.values(existingSections)) {
|
|
329
|
+
if (section.startIndex > existingSection.startIndex) {
|
|
330
|
+
section.startIndex += diff;
|
|
331
|
+
section.endIndex += diff;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// Add new sections
|
|
337
|
+
if (additions.length > 0) {
|
|
338
|
+
// Find the best place to insert new sections
|
|
339
|
+
let insertPosition = 0;
|
|
340
|
+
|
|
341
|
+
// Try to insert after the main header
|
|
342
|
+
const headerMatch = /^# .+\n/m.exec(newContent);
|
|
343
|
+
if (headerMatch) {
|
|
344
|
+
insertPosition = headerMatch.index + headerMatch[0].length;
|
|
345
|
+
|
|
346
|
+
// Skip any immediate description
|
|
347
|
+
const descMatch = /\*\*IMPORTANT:.+\*\*\n/m.exec(newContent.substring(insertPosition));
|
|
348
|
+
if (descMatch && descMatch.index === 0) {
|
|
349
|
+
insertPosition += descMatch[0].length;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// Add each new section
|
|
354
|
+
const sectionsToAdd = additions.map(name => '\n' + this.formatSection(name) + '\n').join('');
|
|
355
|
+
newContent = newContent.substring(0, insertPosition) + sectionsToAdd + newContent.substring(insertPosition);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// Write updated content
|
|
359
|
+
fs.writeFileSync(this.houseRulesPath, newContent);
|
|
360
|
+
|
|
361
|
+
return {
|
|
362
|
+
updated: true,
|
|
363
|
+
path: this.houseRulesPath,
|
|
364
|
+
updatedSections: updates,
|
|
365
|
+
addedSections: additions,
|
|
366
|
+
totalChanges: updates.length + additions.length
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Get status of house rules
|
|
372
|
+
*/
|
|
373
|
+
getStatus() {
|
|
374
|
+
if (!this.houseRulesPath) {
|
|
375
|
+
return {
|
|
376
|
+
exists: false,
|
|
377
|
+
path: null,
|
|
378
|
+
managedSections: {},
|
|
379
|
+
needsUpdate: true
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
const content = fs.readFileSync(this.houseRulesPath, 'utf8');
|
|
384
|
+
const existingSections = this.extractManagedSections(content);
|
|
385
|
+
const status = {
|
|
386
|
+
exists: true,
|
|
387
|
+
path: this.houseRulesPath,
|
|
388
|
+
managedSections: {},
|
|
389
|
+
needsUpdate: false
|
|
390
|
+
};
|
|
391
|
+
|
|
392
|
+
// Check each managed section
|
|
393
|
+
for (const [sectionName, sectionData] of Object.entries(MANAGED_SECTIONS)) {
|
|
394
|
+
if (existingSections[sectionName]) {
|
|
395
|
+
const existing = existingSections[sectionName];
|
|
396
|
+
const needsUpdate = this.needsUpdate(sectionName, existing.version, existing.checksum);
|
|
397
|
+
|
|
398
|
+
status.managedSections[sectionName] = {
|
|
399
|
+
installed: true,
|
|
400
|
+
installedVersion: existing.version,
|
|
401
|
+
currentVersion: sectionData.version,
|
|
402
|
+
needsUpdate
|
|
403
|
+
};
|
|
404
|
+
|
|
405
|
+
if (needsUpdate) {
|
|
406
|
+
status.needsUpdate = true;
|
|
407
|
+
}
|
|
408
|
+
} else {
|
|
409
|
+
status.managedSections[sectionName] = {
|
|
410
|
+
installed: false,
|
|
411
|
+
currentVersion: sectionData.version,
|
|
412
|
+
needsUpdate: true
|
|
413
|
+
};
|
|
414
|
+
status.needsUpdate = true;
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
return status;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
export default HouseRulesManager;
|
|
423
|
+
|
|
424
|
+
// CLI interface when run directly
|
|
425
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
426
|
+
const manager = new HouseRulesManager();
|
|
427
|
+
const command = process.argv[2];
|
|
428
|
+
|
|
429
|
+
switch (command) {
|
|
430
|
+
case 'status':
|
|
431
|
+
console.log('House Rules Status:', JSON.stringify(manager.getStatus(), null, 2));
|
|
432
|
+
break;
|
|
433
|
+
|
|
434
|
+
case 'update':
|
|
435
|
+
manager.updateHouseRules().then(result => {
|
|
436
|
+
console.log('Update Result:', JSON.stringify(result, null, 2));
|
|
437
|
+
});
|
|
438
|
+
break;
|
|
439
|
+
|
|
440
|
+
default:
|
|
441
|
+
console.log('Usage: node house-rules-manager.js [status|update]');
|
|
442
|
+
}
|
|
443
|
+
}
|
|
@@ -461,7 +461,13 @@ class SessionCoordinator {
|
|
|
461
461
|
});
|
|
462
462
|
|
|
463
463
|
console.log(`\n${CONFIG.colors.yellow}═══ Auto-merge Configuration ═══${CONFIG.colors.reset}`);
|
|
464
|
-
console.log(`${CONFIG.colors.dim}
|
|
464
|
+
console.log(`${CONFIG.colors.dim}Automatically merge your daily work branches into a target branch.${CONFIG.colors.reset}`);
|
|
465
|
+
console.log();
|
|
466
|
+
console.log(`${CONFIG.colors.bright}How it works:${CONFIG.colors.reset}`);
|
|
467
|
+
console.log(` • The agent creates dated branches (e.g., ${CONFIG.colors.blue}agent_dev_2025-10-01${CONFIG.colors.reset})`);
|
|
468
|
+
console.log(` • At the end of each day, your work is automatically merged`);
|
|
469
|
+
console.log(` • This keeps your target branch (main/develop) up to date`);
|
|
470
|
+
console.log(` • Prevents accumulation of stale feature branches`);
|
|
465
471
|
|
|
466
472
|
// Ask if they want auto-merge
|
|
467
473
|
const autoMerge = await new Promise((resolve) => {
|
|
@@ -784,6 +790,28 @@ INSTRUCTIONS:
|
|
|
784
790
|
- **Worktree Path:** \`${worktreePath}\`
|
|
785
791
|
- **Branch:** \`${branchName}\`
|
|
786
792
|
|
|
793
|
+
## 🚨 CRITICAL: File Coordination Protocol
|
|
794
|
+
|
|
795
|
+
**BEFORE editing any files, you MUST:**
|
|
796
|
+
|
|
797
|
+
1. **Declare your intent** by creating:
|
|
798
|
+
\`\`\`json
|
|
799
|
+
// File: .file-coordination/active-edits/<agent>-${sessionId}.json
|
|
800
|
+
{
|
|
801
|
+
"agent": "<your-name>",
|
|
802
|
+
"session": "${sessionId}",
|
|
803
|
+
"files": ["list", "files", "to", "edit"],
|
|
804
|
+
"operation": "edit",
|
|
805
|
+
"reason": "${task}",
|
|
806
|
+
"declaredAt": "<ISO-8601-timestamp>",
|
|
807
|
+
"estimatedDuration": 300
|
|
808
|
+
}
|
|
809
|
+
\`\`\`
|
|
810
|
+
|
|
811
|
+
2. **Check for conflicts** - read all files in \`.file-coordination/active-edits/\`
|
|
812
|
+
3. **Only proceed if no conflicts** - wait or choose different files if blocked
|
|
813
|
+
4. **Release files when done** - delete your declaration after edits
|
|
814
|
+
|
|
787
815
|
## Instructions for Claude/Cline
|
|
788
816
|
|
|
789
817
|
### Step 1: Navigate to Your Worktree
|
|
@@ -797,18 +825,25 @@ git branch --show-current
|
|
|
797
825
|
# Should output: ${branchName}
|
|
798
826
|
\`\`\`
|
|
799
827
|
|
|
800
|
-
### Step 3:
|
|
828
|
+
### Step 3: Declare Files Before Editing
|
|
829
|
+
Create your declaration in \`.file-coordination/active-edits/\`
|
|
830
|
+
|
|
831
|
+
### Step 4: Work on Your Task
|
|
801
832
|
Make changes for: **${task}**
|
|
802
833
|
|
|
803
|
-
### Step
|
|
834
|
+
### Step 5: Commit Your Changes
|
|
804
835
|
Write your commit message to the session-specific file:
|
|
805
836
|
\`\`\`bash
|
|
806
837
|
echo "feat: your commit message here" > .devops-commit-${sessionId}.msg
|
|
807
838
|
\`\`\`
|
|
808
839
|
|
|
809
|
-
### Step
|
|
840
|
+
### Step 6: Release Your File Locks
|
|
841
|
+
Delete your declaration from \`.file-coordination/active-edits/\`
|
|
842
|
+
|
|
843
|
+
### Step 7: Automatic Processing
|
|
810
844
|
The DevOps agent will automatically:
|
|
811
845
|
- Detect your changes
|
|
846
|
+
- Check for coordination conflicts
|
|
812
847
|
- Read your commit message
|
|
813
848
|
- Commit and push to the remote repository
|
|
814
849
|
- Clear the message file
|
|
@@ -853,11 +888,21 @@ The DevOps agent will automatically:
|
|
|
853
888
|
console.log(`- Working Directory: ${instructions.worktreePath}`);
|
|
854
889
|
console.log(`- Task: ${task || 'development'}`);
|
|
855
890
|
console.log(``);
|
|
856
|
-
console.log(`
|
|
857
|
-
console.log(`
|
|
891
|
+
console.log(`CRITICAL FIRST STEP:`);
|
|
892
|
+
console.log(`1. Read and follow the house rules: cat "${instructions.worktreePath}/houserules.md"`);
|
|
893
|
+
console.log(`2. Switch to the working directory: cd "${instructions.worktreePath}"`);
|
|
894
|
+
console.log(``);
|
|
895
|
+
console.log(`FILE COORDINATION PROTOCOL (from house rules at ${instructions.worktreePath}/houserules.md):`);
|
|
896
|
+
console.log(`Before editing ANY files, you MUST:`);
|
|
897
|
+
console.log(`- Declare your intent in .file-coordination/active-edits/<agent>-${sessionId}.json`);
|
|
898
|
+
console.log(`- Check for conflicts with other agents`);
|
|
899
|
+
console.log(`- Only edit files you've declared`);
|
|
900
|
+
console.log(`- Release files when done`);
|
|
858
901
|
console.log(``);
|
|
859
902
|
console.log(`Write commit messages to: .devops-commit-${sessionId}.msg`);
|
|
860
903
|
console.log(`The DevOps agent will automatically commit and push changes.`);
|
|
904
|
+
console.log(``);
|
|
905
|
+
console.log(`Remember: ALWAYS check house rules first for the latest protocols!`);
|
|
861
906
|
console.log();
|
|
862
907
|
|
|
863
908
|
console.log(`${CONFIG.colors.yellow}══════════════════════════════════════════════════════════════${CONFIG.colors.reset}`);
|
|
@@ -735,7 +735,8 @@ export AC_MSG_MIN_BYTES="20"
|
|
|
735
735
|
export AC_DEBOUNCE_MS="1500"
|
|
736
736
|
export AC_MSG_DEBOUNCE_MS="3000"
|
|
737
737
|
export AC_CLEAR_MSG_WHEN="push"
|
|
738
|
-
|
|
738
|
+
# Daily rollover is automatic - no prompting needed
|
|
739
|
+
export AC_ROLLOVER_PROMPT="false"
|
|
739
740
|
export AC_DEBUG="false"
|
|
740
741
|
|
|
741
742
|
# Check for debug flag
|
|
@@ -784,7 +785,8 @@ AC_MSG_DEBOUNCE_MS=3000
|
|
|
784
785
|
|
|
785
786
|
# Behavior
|
|
786
787
|
AC_CLEAR_MSG_WHEN=push
|
|
787
|
-
|
|
788
|
+
# Daily rollover is automatic
|
|
789
|
+
AC_ROLLOVER_PROMPT=false
|
|
788
790
|
AC_DEBUG=false
|
|
789
791
|
`;
|
|
790
792
|
|
|
@@ -826,7 +828,7 @@ function printInstructions(initials) {
|
|
|
826
828
|
log.title('🎯 Daily Workflow:');
|
|
827
829
|
console.log('');
|
|
828
830
|
console.log(`• Your daily branches will be: ${colors.bright}dev_${initials}_YYYY-MM-DD${colors.reset}`);
|
|
829
|
-
console.log('• The worker
|
|
831
|
+
console.log('• The worker automatically creates new daily branches at midnight');
|
|
830
832
|
console.log('• Commits require valid conventional format (feat/fix/docs/etc)');
|
|
831
833
|
console.log('• Message file is cleared after successful push');
|
|
832
834
|
console.log('');
|