## CHANGES

- Refreshed Maestro tagline across README and package metadata for clarity 
- Reset-on-completion now writes working copies into `Runs/` folder consistently 📁
- Auto Run working-copy IPC handler updated for new `Runs/` directory naming 🧭
- Working-copy relative paths now return `Runs/...` for downstream consumers 🔗
- Preload API docs updated to reflect `Runs/` working-copy location 🧩
- AutoRunner Help Modal now points users to `Runs/` audit-log folder 🪟
- Batch processor tracking/comments updated for `Runs/` audit log behavior 🧾
- Test suite updated to expect `Runs/` working-copy paths reliably 🧪
This commit is contained in:
Pedram Amini
2025-12-26 10:07:57 -06:00
parent 2b27208543
commit f724ef4c8c
8 changed files with 22 additions and 22 deletions

View File

@@ -3,7 +3,7 @@
[![Made with Maestro](docs/assets/made-with-maestro.svg)](https://github.com/pedramamini/Maestro)
[![Discord](https://img.shields.io/badge/Discord-Join%20Us-5865F2?logo=discord&logoColor=white)](https://discord.gg/SrBsykvG)
> Run AI coding agents autonomously for days.
> Maestro hones fractured attention into focused intent.
Maestro is a cross-platform desktop app for orchestrating your fleet of AI agents and projects. It's a high-velocity solution for hackers who are juggling multiple projects in parallel. Designed for power users who live on the keyboard and rarely touch the mouse.
@@ -459,7 +459,7 @@ Auto Run supports running multiple documents in sequence:
2. Click **+ Add Docs** to add more documents to the queue
3. Drag to reorder documents as needed
4. Configure options per document:
- **Reset on Completion** - Creates a working copy in `runs/` subfolder instead of modifying the original. The original document is never touched, and working copies (e.g., `TASK-1735192800000-loop-1.md`) serve as audit logs.
- **Reset on Completion** - Creates a working copy in `Runs/` subfolder instead of modifying the original. The original document is never touched, and working copies (e.g., `TASK-1735192800000-loop-1.md`) serve as audit logs.
- **Duplicate** - Add the same document multiple times
5. Enable **Loop Mode** to cycle back to the first document after completing the last
6. Click **Go** to start the batch run

View File

@@ -1,7 +1,7 @@
{
"name": "maestro",
"version": "0.12.1",
"description": "Run AI coding agents autonomously for days.",
"description": "Maestro hones fractured attention into focused intent.",
"main": "dist/main/index.js",
"author": {
"name": "Pedram Amini",

View File

@@ -620,7 +620,7 @@ describe('useBatchProcessor hook', () => {
// Set up window.maestro mocks
mockReadDoc = vi.fn().mockResolvedValue({ success: true, content: '# Tasks\n- [ ] Task 1\n- [ ] Task 2' });
mockWriteDoc = vi.fn().mockResolvedValue({ success: true });
mockCreateWorkingCopy = vi.fn().mockResolvedValue({ workingCopyPath: 'runs/tasks-run-1.md' });
mockCreateWorkingCopy = vi.fn().mockResolvedValue({ workingCopyPath: 'Runs/tasks-run-1.md' });
mockStatus = vi.fn().mockResolvedValue({ stdout: '' });
mockBranch = vi.fn().mockResolvedValue({ stdout: 'main' });
mockBroadcastAutoRunState = vi.fn();
@@ -1366,7 +1366,7 @@ describe('useBatchProcessor hook', () => {
describe('reset on completion', () => {
it('should create working copy when resetOnCompletion is enabled', async () => {
// Note: Reset-on-completion now uses working copies in /runs/ directory
// Note: Reset-on-completion now uses working copies in /Runs/ directory
// instead of modifying the original document. This preserves the original
// and allows the agent to work on a copy.
const sessions = [createMockSession()];
@@ -3205,7 +3205,7 @@ describe('useBatchProcessor hook', () => {
describe('reset-on-completion in loop mode', () => {
it('should create working copy when document has resetOnCompletion enabled', async () => {
// Note: Reset-on-completion now uses working copies in /runs/ directory
// Note: Reset-on-completion now uses working copies in /Runs/ directory
// instead of modifying the original document. This preserves the original
// and allows the agent to work on a copy each loop iteration.
const sessions = [createMockSession()];

View File

@@ -570,7 +570,7 @@ export function registerAutorunHandlers(deps: {
);
// Create a working copy of a document for reset-on-completion loops
// Working copies are stored in /runs/ subdirectory with format: {name}-{timestamp}-loop-{N}.md
// Working copies are stored in /Runs/ subdirectory with format: {name}-{timestamp}-loop-{N}.md
ipcMain.handle(
'autorun:createWorkingCopy',
createIpcHandler(
@@ -604,10 +604,10 @@ export function registerAutorunHandlers(deps: {
throw new Error('Source file not found');
}
// Create runs directory (with subdirectory if needed)
// Create Runs directory (with subdirectory if needed)
const runsDir = subDir
? path.join(folderPath, 'runs', subDir)
: path.join(folderPath, 'runs');
? path.join(folderPath, 'Runs', subDir)
: path.join(folderPath, 'Runs');
await fs.mkdir(runsDir, { recursive: true });
// Generate working copy filename: {name}-{timestamp}-loop-{N}.md
@@ -625,8 +625,8 @@ export function registerAutorunHandlers(deps: {
// Return the relative path (without .md for consistency with other APIs)
const relativePath = subDir
? `runs/${subDir}/${workingCopyName.slice(0, -3)}`
: `runs/${workingCopyName.slice(0, -3)}`;
? `Runs/${subDir}/${workingCopyName.slice(0, -3)}`
: `Runs/${workingCopyName.slice(0, -3)}`;
logger.info(`Created Auto Run working copy: ${relativePath}`, LOG_CONTEXT);
return { workingCopyPath: relativePath, originalPath: baseName };

View File

@@ -1050,7 +1050,7 @@ contextBridge.exposeInMainWorld('maestro', {
deleteBackups: (folderPath: string) =>
ipcRenderer.invoke('autorun:deleteBackups', folderPath),
// Working copy operations for reset-on-completion documents (preferred)
// Creates a copy in /runs/ subdirectory: {name}-{timestamp}-loop-{N}.md
// Creates a copy in /Runs/ subdirectory: {name}-{timestamp}-loop-{N}.md
createWorkingCopy: (folderPath: string, filename: string, loopNumber: number): Promise<{ workingCopyPath: string; originalPath: string }> =>
ipcRenderer.invoke('autorun:createWorkingCopy', folderPath, filename, loopNumber),
},

View File

@@ -283,7 +283,7 @@ export function AutoRunnerHelpModal({ theme, onClose }: AutoRunnerHelpModalProps
<p>
Enable the reset toggle (<RotateCcw className="w-3 h-3 inline" />) on any document to
keep it available for repeated runs. When enabled, Auto Run creates a <strong style={{ color: theme.colors.textMain }}>working copy</strong> in
the <code>runs/</code> subfolder and processes that copy—<em>the original document is never modified</em>.
the <code>Runs/</code> subfolder and processes that copy—<em>the original document is never modified</em>.
</p>
<p>
Working copies are named with timestamps (e.g., <code>TASK-1735192800000-loop-1.md</code>) and

View File

@@ -787,7 +787,7 @@ interface MaestroAPI {
restoreBackup: (folderPath: string, filename: string) => Promise<{ success: boolean; error?: string }>;
deleteBackups: (folderPath: string) => Promise<{ success: boolean; deletedCount?: number; error?: string }>;
// Working copy operations for reset-on-completion documents (preferred)
// Creates a copy in /runs/ subdirectory: {name}-{timestamp}-loop-{N}.md
// Creates a copy in /Runs/ subdirectory: {name}-{timestamp}-loop-{N}.md
createWorkingCopy: (folderPath: string, filename: string, loopNumber: number) => Promise<{ workingCopyPath: string; originalPath: string }>;
};
// Playbooks API (saved batch run configurations)

View File

@@ -557,7 +557,7 @@ export function useBatchProcessor({
const stalledDocuments: Map<string, string> = new Map();
// Track working copies for reset-on-completion documents (original filename -> working copy path)
// Working copies are stored in /runs/ and serve as audit logs
// Working copies are stored in /Runs/ and serve as audit logs
const workingCopies: Map<string, string> = new Map();
// Helper to add final loop summary (defined here so it has access to tracking vars)
@@ -643,7 +643,7 @@ export function useBatchProcessor({
let effectiveFilename = docEntry.filename;
// Create working copy for reset-on-completion documents
// Working copies are stored in /runs/ and the original is never modified
// Working copies are stored in /Runs/ and the original is never modified
if (docEntry.resetOnCompletion) {
try {
const { workingCopyPath } = await window.maestro.autorun.createWorkingCopy(
@@ -912,7 +912,7 @@ export function useBatchProcessor({
// Skip document handling if this document stalled (it didn't complete normally)
if (stalledDocuments.has(docEntry.filename)) {
// Working copy approach: stalled working copy stays in /runs/ as audit log
// Working copy approach: stalled working copy stays in /Runs/ as audit log
// Original document is untouched, so nothing to restore
workingCopies.delete(docEntry.filename);
// Reset consecutive no-change counter for next document
@@ -921,14 +921,14 @@ export function useBatchProcessor({
}
if (skipCurrentDocumentAfterError) {
// Working copy approach: errored working copy stays in /runs/ as audit log
// Working copy approach: errored working copy stays in /Runs/ as audit log
// Original document is untouched, so nothing to restore
workingCopies.delete(docEntry.filename);
continue;
}
// Document complete - for reset-on-completion docs, original is untouched
// Working copy in /runs/ serves as the audit log of this loop's work
// Working copy in /Runs/ serves as the audit log of this loop's work
if (docEntry.resetOnCompletion && docTasksCompleted > 0) {
// AUTORUN LOG: Document loop completed
window.maestro.logger.autorun(
@@ -956,7 +956,7 @@ export function useBatchProcessor({
}));
}
// Clear tracking - working copy stays in /runs/ as audit log
// Clear tracking - working copy stays in /Runs/ as audit log
workingCopies.delete(docEntry.filename);
} else if (docEntry.resetOnCompletion) {
// Document had reset enabled but no tasks were completed
@@ -1104,7 +1104,7 @@ export function useBatchProcessor({
// Working copy approach: no cleanup needed
// - Original documents are never modified
// - Working copies in /runs/ serve as audit logs and are kept
// - Working copies in /Runs/ serve as audit logs and are kept
// - User can delete them manually if desired
// Create PR if worktree was used, PR creation is enabled, and not stopped