Skip to content

Commit c9e2579

Browse files
author
StackMemory Bot (CLI)
committed
refactor(conductor): rename scripts/symphony dir to scripts/conductor
1 parent 6d7ade1 commit c9e2579

File tree

10 files changed

+90
-222
lines changed

10 files changed

+90
-222
lines changed
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ Add to your config:
1818

1919
```toml
2020
[hooks]
21-
after_create = "scripts/symphony/after-create.sh"
22-
after_run = "scripts/symphony/after-run.sh"
23-
before_remove = "scripts/symphony/before-remove.sh"
21+
after_create = "scripts/conductor/after-create.sh"
22+
after_run = "scripts/conductor/after-run.sh"
23+
before_remove = "scripts/conductor/before-remove.sh"
2424
```
2525

2626
## Environment Variables

src/cli/commands/capture.ts

Lines changed: 0 additions & 127 deletions
This file was deleted.

src/cli/commands/orchestrator.ts

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ const DEFAULT_CONFIG: ConductorConfig = {
101101
'..',
102102
'..',
103103
'scripts',
104-
'symphony',
104+
'conductor',
105105
'claude-app-server.cjs'
106106
),
107107
turnTimeoutMs: 3600000,
@@ -381,14 +381,18 @@ export class Conductor {
381381
try {
382382
const checker = new PreflightChecker(this.config.repoRoot);
383383

384-
// Build task definitions from running + candidate issues
385-
const runningTasks: TaskDefinition[] = Array.from(
386-
this.running.values()
387-
).map((r) => ({
388-
name: r.issue.identifier,
389-
description: r.issue.title,
390-
keywords: this.extractIssueKeywords(r.issue),
391-
}));
384+
// Predict files for running tasks ONCE (avoid N+1 re-prediction)
385+
const runningFileSets: Set<string>[] = [];
386+
const runningNames: string[] = [];
387+
for (const run of this.running.values()) {
388+
const task: TaskDefinition = {
389+
name: run.issue.identifier,
390+
description: run.issue.title,
391+
keywords: this.extractIssueKeywords(run.issue),
392+
};
393+
runningFileSets.push(checker.predictFiles(task));
394+
runningNames.push(run.issue.identifier);
395+
}
392396

393397
const safe: LinearIssue[] = [];
394398

@@ -398,32 +402,33 @@ export class Conductor {
398402
description: candidate.title,
399403
keywords: this.extractIssueKeywords(candidate),
400404
};
405+
const candidateFiles = checker.predictFiles(candidateTask);
401406

402-
// Check this candidate against all running tasks
403-
const allTasks = [...runningTasks, candidateTask];
404-
const result = checker.check(allTasks);
407+
// Check overlap against each running task's pre-computed file set
408+
const conflictFiles: string[] = [];
409+
const conflictTasks: string[] = [];
405410

406-
// Filter overlaps once, reuse for checks and logging
407-
const candidateOverlaps = result.allOverlaps.filter(
408-
(o) => o.tasks.includes(candidate.identifier) && o.confidence >= 0.6
409-
);
411+
for (let i = 0; i < runningFileSets.length; i++) {
412+
const shared = [...candidateFiles].filter((f) =>
413+
runningFileSets[i].has(f)
414+
);
415+
if (shared.length > 0) {
416+
conflictFiles.push(...shared);
417+
conflictTasks.push(runningNames[i]);
418+
}
419+
}
410420

411-
if (candidateOverlaps.length > 0) {
412-
const conflictFiles = candidateOverlaps
413-
.map((o) => o.file)
414-
.slice(0, 3);
415-
const conflictTasks = candidateOverlaps
416-
.flatMap((o) => o.tasks)
417-
.filter((t) => t !== candidate.identifier);
421+
if (conflictFiles.length > 0) {
422+
const uniqueFiles = [...new Set(conflictFiles)].slice(0, 3);
418423

419424
logger.info('Preflight: skipping conflicting issue', {
420425
identifier: candidate.identifier,
421426
conflictsWith: conflictTasks,
422-
files: conflictFiles,
427+
files: uniqueFiles,
423428
});
424429

425430
console.log(
426-
`[${candidate.identifier}] Deferred — file overlap with running work (${conflictFiles.join(', ')})`
431+
`[${candidate.identifier}] Deferred — file overlap with running work (${uniqueFiles.join(', ')})`
427432
);
428433
} else {
429434
safe.push(candidate);
@@ -588,7 +593,7 @@ export class Conductor {
588593
}
589594

590595
// Create git worktree
591-
const branchName = `symphony/${wsKey}`;
596+
const branchName = `conductor/${wsKey}`;
592597

593598
try {
594599
// Fetch latest
@@ -908,7 +913,7 @@ export class Conductor {
908913
const hookPath = join(
909914
this.config.repoRoot,
910915
'scripts',
911-
'symphony',
916+
'conductor',
912917
`${hookName}.sh`
913918
);
914919

src/cli/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ import { createTeamCommands } from './commands/team.js';
6666
import { createDesiresCommands } from './commands/desires.js';
6767
import { createConductorCommands } from './commands/orchestrate.js';
6868
import { createPreflightCommand } from './commands/preflight.js';
69-
import { createSnapshotCommand } from './commands/capture.js';
69+
import { createSnapshotCommand } from './commands/snapshot.js';
7070
import chalk from 'chalk';
7171
import * as fs from 'fs';
7272
import * as path from 'path';

src/core/worktree/capture.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66

77
import { execFileSync } from 'child_process';
8+
import { formatDuration } from '../../utils/formatting.js';
89
import {
910
existsSync,
1011
mkdirSync,
@@ -271,7 +272,7 @@ export class ContextCapture {
271272
[
272273
'log',
273274
`${baseBranch}..HEAD`,
274-
'--pretty=format:%H|%s|%an|%aI',
275+
'--pretty=format:%H%x00%s%x00%an%x00%aI',
275276
'--no-merges',
276277
],
277278
{ cwd: this.repoPath, encoding: 'utf-8', timeout: 10000 }
@@ -281,7 +282,7 @@ export class ContextCapture {
281282
.split('\n')
282283
.filter((l) => l.trim())
283284
.map((line) => {
284-
const [hash, message, author, date] = line.split('|');
285+
const [hash, message, author, date] = line.split('\0');
285286
return { hash, message, author, date };
286287
});
287288
} catch {
@@ -324,12 +325,7 @@ export class ContextCapture {
324325
const first = new Date(commits[commits.length - 1].date);
325326
const last = new Date(commits[0].date);
326327
const diffMs = last.getTime() - first.getTime();
327-
const diffMin = Math.round(diffMs / 60000);
328-
329-
if (diffMin < 60) return `${diffMin}min`;
330-
const hours = Math.floor(diffMin / 60);
331-
const mins = diffMin % 60;
332-
return `${hours}h${mins > 0 ? ` ${mins}min` : ''}`;
328+
return formatDuration(diffMs);
333329
}
334330

335331
private save(result: CaptureResult): void {

0 commit comments

Comments
 (0)