@bill10/agent-007 0.7.0 → 0.7.1000
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/VERSION +1 -1
- package/package.json +1 -1
- package/server/git.js +8 -7
- package/server/jobs.js +14 -0
- package/server.js +4 -1
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.7.
|
|
1
|
+
0.7.1.0
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bill10/agent-007",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.1000",
|
|
4
4
|
"description": "From web terminals for your coding agents to a self-running agent company: Claude Code and Codex in parallel git worktrees, a job board they pick work from, and one agent that runs the board from a goal.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
package/server/git.js
CHANGED
|
@@ -342,13 +342,14 @@ export async function removeWorktree(session, { discardChanges = false } = {}) {
|
|
|
342
342
|
const local = (await gitExec(['-C', session.worktreePath, 'rev-parse', 'HEAD'])).trim();
|
|
343
343
|
const upstream = (await gitExec(['-C', session.worktreePath, 'rev-parse', '@{u}'])).trim();
|
|
344
344
|
fullyPushed = !!local && local === upstream;
|
|
345
|
-
} catch {
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
345
|
+
} catch {}
|
|
346
|
+
// No upstream git can resolve locally (a branch pushed to a raw URL,
|
|
347
|
+
// `git push -u https://…`, records the URL as branch.<name>.remote and
|
|
348
|
+
// creates no remote-tracking ref), or one that is stale: a push from
|
|
349
|
+
// inside the worktree after a rebase or a force-with-lease can leave the
|
|
350
|
+
// shared repo's refs/remotes/origin/<branch> on an old SHA. Ask the
|
|
351
|
+
// remote itself; anything short of a matching SHA stays not-pushed.
|
|
352
|
+
if (!fullyPushed) fullyPushed = await matchesRemote(session);
|
|
352
353
|
}
|
|
353
354
|
if (!reason && !fullyPushed) {
|
|
354
355
|
const baseBranch = await resolveBaseBranch(session.repoPath);
|
package/server/jobs.js
CHANGED
|
@@ -1086,6 +1086,20 @@ async function releaseOrphanedWorktree({ branchName, repoPath, worktreePath }, b
|
|
|
1086
1086
|
return true;
|
|
1087
1087
|
}
|
|
1088
1088
|
|
|
1089
|
+
// An "unpushed" orphan left by an older build (or a stale remote-tracking ref)
|
|
1090
|
+
// may be fully on the remote by now. Re-check each one at startup through the
|
|
1091
|
+
// same release path, so removeWorktree's rules decide: dirty stays, and only
|
|
1092
|
+
// an exact SHA match on the remote counts as pushed. A card still in progress
|
|
1093
|
+
// or in Review may want its agent re-adopted, so its orphan is left alone.
|
|
1094
|
+
export async function releasePushedOrphans(broadcast) {
|
|
1095
|
+
let released = 0;
|
|
1096
|
+
for (const entry of [...orphans.values()]) {
|
|
1097
|
+
if (entry.reason !== 'unpushed' || findJobForBranch(entry)) continue;
|
|
1098
|
+
if (await releaseOrphanedWorktree(entry, broadcast)) released++;
|
|
1099
|
+
}
|
|
1100
|
+
return released;
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1089
1103
|
export function updateSettings(fields, broadcast) {
|
|
1090
1104
|
const settings = boardSettings();
|
|
1091
1105
|
if (typeof fields.running === 'boolean') settings.running = fields.running;
|
package/server.js
CHANGED
|
@@ -29,7 +29,7 @@ import { addRepo, createWorktree, removeWorktree, pruneWorktrees, scanForOrphane
|
|
|
29
29
|
import { createSessionFromConfig } from './server/pty.js';
|
|
30
30
|
import { setupWebSocket, broadcast, sessionPayload, broadcastOrphansList, verifyClient } from './server/ws.js';
|
|
31
31
|
import { setupRoutes } from './server/http.js';
|
|
32
|
-
import { startDispatcher, stopDispatcher, boardSettings } from './server/jobs.js';
|
|
32
|
+
import { startDispatcher, stopDispatcher, boardSettings, releasePushedOrphans } from './server/jobs.js';
|
|
33
33
|
import { orphans, config } from './server/state.js';
|
|
34
34
|
import { sweepMcpConfigs } from './server/agent-mcp.js';
|
|
35
35
|
import { withDefaultPermission, envPermissionMode, PERMISSION_MODES, ENV_PERMISSION_MODE, sessionAgentFromCommand } from './lib/jobs.js';
|
|
@@ -238,6 +238,9 @@ async function startup() {
|
|
|
238
238
|
mkdirSync(WORKTREE_DIR, { recursive: true });
|
|
239
239
|
await pruneWorktrees();
|
|
240
240
|
await scanForOrphanedWorktrees(broadcast);
|
|
241
|
+
// Not awaited: each check can ask the remote, and boot must not wait on the network.
|
|
242
|
+
releasePushedOrphans(broadcast).then(n => { if (n) console.log(` Released ${n} orphaned worktree(s) now on the remote`); })
|
|
243
|
+
.catch(err => console.error('Orphan re-check failed:', err.message));
|
|
241
244
|
// The loop always runs; each tick is a no-op while settings.running is false.
|
|
242
245
|
// Keeping one timer alive (instead of creating/destroying it on toggle) means
|
|
243
246
|
// the Start button only has to flip a boolean, and a config restored with
|