baxian 0.0.1 → 0.2.0
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/LICENSE +201 -0
- package/README.md +19 -1
- package/dist/agent/bootstrap-poller.d.ts +34 -0
- package/dist/agent/bootstrap-poller.d.ts.map +1 -0
- package/dist/agent/bootstrap-poller.js +93 -0
- package/dist/agent/bootstrap-poller.js.map +1 -0
- package/dist/agent/bootstrap.d.ts +39 -0
- package/dist/agent/bootstrap.d.ts.map +1 -0
- package/dist/agent/bootstrap.js +214 -0
- package/dist/agent/bootstrap.js.map +1 -0
- package/dist/agent/index.d.ts +8 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +8 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/agent/manager.d.ts +280 -0
- package/dist/agent/manager.d.ts.map +1 -0
- package/dist/agent/manager.js +3666 -0
- package/dist/agent/manager.js.map +1 -0
- package/dist/agent/marker-protocol.d.ts +12 -0
- package/dist/agent/marker-protocol.d.ts.map +1 -0
- package/dist/agent/marker-protocol.js +52 -0
- package/dist/agent/marker-protocol.js.map +1 -0
- package/dist/agent/pane-streamer-manager.d.ts +24 -0
- package/dist/agent/pane-streamer-manager.d.ts.map +1 -0
- package/dist/agent/pane-streamer-manager.js +107 -0
- package/dist/agent/pane-streamer-manager.js.map +1 -0
- package/dist/agent/pane-streamer.d.ts +97 -0
- package/dist/agent/pane-streamer.d.ts.map +1 -0
- package/dist/agent/pane-streamer.js +382 -0
- package/dist/agent/pane-streamer.js.map +1 -0
- package/dist/agent/post-approve-marker-watcher.d.ts +29 -0
- package/dist/agent/post-approve-marker-watcher.d.ts.map +1 -0
- package/dist/agent/post-approve-marker-watcher.js +160 -0
- package/dist/agent/post-approve-marker-watcher.js.map +1 -0
- package/dist/agent/preflight.d.ts +9 -0
- package/dist/agent/preflight.d.ts.map +1 -0
- package/dist/agent/preflight.js +164 -0
- package/dist/agent/preflight.js.map +1 -0
- package/dist/agent/prompt.d.ts +44 -0
- package/dist/agent/prompt.d.ts.map +1 -0
- package/dist/agent/prompt.js +252 -0
- package/dist/agent/prompt.js.map +1 -0
- package/dist/agent/repo-store.d.ts +27 -0
- package/dist/agent/repo-store.d.ts.map +1 -0
- package/dist/agent/repo-store.js +152 -0
- package/dist/agent/repo-store.js.map +1 -0
- package/dist/agent/runner.d.ts +46 -0
- package/dist/agent/runner.d.ts.map +1 -0
- package/dist/agent/runner.js +241 -0
- package/dist/agent/runner.js.map +1 -0
- package/dist/agent/spec-review-marker-watcher.d.ts +33 -0
- package/dist/agent/spec-review-marker-watcher.d.ts.map +1 -0
- package/dist/agent/spec-review-marker-watcher.js +180 -0
- package/dist/agent/spec-review-marker-watcher.js.map +1 -0
- package/dist/agent/tmux-probe-poller.d.ts +78 -0
- package/dist/agent/tmux-probe-poller.d.ts.map +1 -0
- package/dist/agent/tmux-probe-poller.js +418 -0
- package/dist/agent/tmux-probe-poller.js.map +1 -0
- package/dist/agent/tmux.d.ts +78 -0
- package/dist/agent/tmux.d.ts.map +1 -0
- package/dist/agent/tmux.js +395 -0
- package/dist/agent/tmux.js.map +1 -0
- package/dist/agent/worktree.d.ts +10 -0
- package/dist/agent/worktree.d.ts.map +1 -0
- package/dist/agent/worktree.js +41 -0
- package/dist/agent/worktree.js.map +1 -0
- package/dist/api/agents.d.ts +3 -0
- package/dist/api/agents.d.ts.map +1 -0
- package/dist/api/agents.js +29 -0
- package/dist/api/agents.js.map +1 -0
- package/dist/api/config.d.ts +5 -0
- package/dist/api/config.d.ts.map +1 -0
- package/dist/api/config.js +114 -0
- package/dist/api/config.js.map +1 -0
- package/dist/api/events.d.ts +3 -0
- package/dist/api/events.d.ts.map +1 -0
- package/dist/api/events.js +11 -0
- package/dist/api/events.js.map +1 -0
- package/dist/api/pollers.d.ts +3 -0
- package/dist/api/pollers.d.ts.map +1 -0
- package/dist/api/pollers.js +4 -0
- package/dist/api/pollers.js.map +1 -0
- package/dist/api/probe.d.ts +9 -0
- package/dist/api/probe.d.ts.map +1 -0
- package/dist/api/probe.js +87 -0
- package/dist/api/probe.js.map +1 -0
- package/dist/api/projects.d.ts +3 -0
- package/dist/api/projects.d.ts.map +1 -0
- package/dist/api/projects.js +602 -0
- package/dist/api/projects.js.map +1 -0
- package/dist/api/restart.d.ts +3 -0
- package/dist/api/restart.d.ts.map +1 -0
- package/dist/api/restart.js +20 -0
- package/dist/api/restart.js.map +1 -0
- package/dist/api/tasks.d.ts +3 -0
- package/dist/api/tasks.d.ts.map +1 -0
- package/dist/api/tasks.js +136 -0
- package/dist/api/tasks.js.map +1 -0
- package/dist/app.d.ts +51 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +169 -0
- package/dist/app.js.map +1 -0
- package/dist/cli.d.ts +20 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +319 -0
- package/dist/cli.js.map +1 -0
- package/dist/config/backup.d.ts +3 -0
- package/dist/config/backup.d.ts.map +1 -0
- package/dist/config/backup.js +44 -0
- package/dist/config/backup.js.map +1 -0
- package/dist/config/index.d.ts +5 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +5 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/loader.d.ts +42 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +197 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/mutex.d.ts +2 -0
- package/dist/config/mutex.d.ts.map +1 -0
- package/dist/config/mutex.js +7 -0
- package/dist/config/mutex.js.map +1 -0
- package/dist/config/normalizer.d.ts +2 -0
- package/dist/config/normalizer.d.ts.map +1 -0
- package/dist/config/normalizer.js +42 -0
- package/dist/config/normalizer.js.map +1 -0
- package/dist/config/validator.d.ts +7 -0
- package/dist/config/validator.d.ts.map +1 -0
- package/dist/config/validator.js +278 -0
- package/dist/config/validator.js.map +1 -0
- package/dist/errors.d.ts +5 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +9 -0
- package/dist/errors.js.map +1 -0
- package/dist/event/broker.d.ts +11 -0
- package/dist/event/broker.d.ts.map +1 -0
- package/dist/event/broker.js +47 -0
- package/dist/event/broker.js.map +1 -0
- package/dist/event/bus.d.ts +12 -0
- package/dist/event/bus.d.ts.map +1 -0
- package/dist/event/bus.js +35 -0
- package/dist/event/bus.js.map +1 -0
- package/dist/event/handlers.d.ts +6 -0
- package/dist/event/handlers.d.ts.map +1 -0
- package/dist/event/handlers.js +1121 -0
- package/dist/event/handlers.js.map +1 -0
- package/dist/event/index.d.ts +4 -0
- package/dist/event/index.d.ts.map +1 -0
- package/dist/event/index.js +4 -0
- package/dist/event/index.js.map +1 -0
- package/dist/event/log.d.ts +9 -0
- package/dist/event/log.d.ts.map +1 -0
- package/dist/event/log.js +43 -0
- package/dist/event/log.js.map +1 -0
- package/dist/event/publish.d.ts +37 -0
- package/dist/event/publish.d.ts.map +1 -0
- package/dist/event/publish.js +197 -0
- package/dist/event/publish.js.map +1 -0
- package/dist/event/ws.d.ts +3 -0
- package/dist/event/ws.d.ts.map +1 -0
- package/dist/event/ws.js +169 -0
- package/dist/event/ws.js.map +1 -0
- package/dist/github/index.d.ts +4 -0
- package/dist/github/index.d.ts.map +1 -0
- package/dist/github/index.js +3 -0
- package/dist/github/index.js.map +1 -0
- package/dist/github/mapper.d.ts +51 -0
- package/dist/github/mapper.d.ts.map +1 -0
- package/dist/github/mapper.js +191 -0
- package/dist/github/mapper.js.map +1 -0
- package/dist/github/poller.d.ts +64 -0
- package/dist/github/poller.d.ts.map +1 -0
- package/dist/github/poller.js +513 -0
- package/dist/github/poller.js.map +1 -0
- package/dist/github/resolver.d.ts +8 -0
- package/dist/github/resolver.d.ts.map +1 -0
- package/dist/github/resolver.js +24 -0
- package/dist/github/resolver.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +310 -0
- package/dist/index.js.map +1 -0
- package/dist/lifecycle/restart-sentinel.d.ts +18 -0
- package/dist/lifecycle/restart-sentinel.d.ts.map +1 -0
- package/dist/lifecycle/restart-sentinel.js +61 -0
- package/dist/lifecycle/restart-sentinel.js.map +1 -0
- package/dist/lifecycle/restart.d.ts +21 -0
- package/dist/lifecycle/restart.d.ts.map +1 -0
- package/dist/lifecycle/restart.js +57 -0
- package/dist/lifecycle/restart.js.map +1 -0
- package/dist/shared/constants.d.ts +18 -0
- package/dist/shared/constants.d.ts.map +1 -0
- package/dist/shared/constants.js +60 -0
- package/dist/shared/constants.js.map +1 -0
- package/dist/shared/index.d.ts +3 -0
- package/dist/shared/index.d.ts.map +1 -0
- package/dist/shared/index.js +3 -0
- package/dist/shared/index.js.map +1 -0
- package/dist/shared/types.d.ts +263 -0
- package/dist/shared/types.d.ts.map +1 -0
- package/dist/shared/types.js +2 -0
- package/dist/shared/types.js.map +1 -0
- package/dist/skill/index.d.ts +2 -0
- package/dist/skill/index.d.ts.map +1 -0
- package/dist/skill/index.js +2 -0
- package/dist/skill/index.js.map +1 -0
- package/dist/skill/registry.d.ts +30 -0
- package/dist/skill/registry.d.ts.map +1 -0
- package/dist/skill/registry.js +174 -0
- package/dist/skill/registry.js.map +1 -0
- package/dist/skills/UPSTREAM.md +38 -0
- package/dist/skills/baxian-rules/SKILL.md +68 -0
- package/dist/skills/merge-sync/SKILL.md +42 -0
- package/dist/skills/pr-feedback/SKILL.md +117 -0
- package/dist/skills/pr-recheck/SKILL.md +52 -0
- package/dist/skills/pr-review/SKILL.md +60 -0
- package/dist/skills/spells/SKILL.md +41 -0
- package/dist/skills/task-check/SKILL.md +26 -0
- package/dist/state/agent-store.d.ts +21 -0
- package/dist/state/agent-store.d.ts.map +1 -0
- package/dist/state/agent-store.js +145 -0
- package/dist/state/agent-store.js.map +1 -0
- package/dist/state/error-record-store.d.ts +40 -0
- package/dist/state/error-record-store.d.ts.map +1 -0
- package/dist/state/error-record-store.js +203 -0
- package/dist/state/error-record-store.js.map +1 -0
- package/dist/state/index.d.ts +5 -0
- package/dist/state/index.d.ts.map +1 -0
- package/dist/state/index.js +5 -0
- package/dist/state/index.js.map +1 -0
- package/dist/state/init.d.ts +2 -0
- package/dist/state/init.d.ts.map +1 -0
- package/dist/state/init.js +13 -0
- package/dist/state/init.js.map +1 -0
- package/dist/state/lock.d.ts +9 -0
- package/dist/state/lock.d.ts.map +1 -0
- package/dist/state/lock.js +36 -0
- package/dist/state/lock.js.map +1 -0
- package/dist/state/post-approve-store.d.ts +23 -0
- package/dist/state/post-approve-store.d.ts.map +1 -0
- package/dist/state/post-approve-store.js +79 -0
- package/dist/state/post-approve-store.js.map +1 -0
- package/dist/state/process-lock.d.ts +24 -0
- package/dist/state/process-lock.d.ts.map +1 -0
- package/dist/state/process-lock.js +175 -0
- package/dist/state/process-lock.js.map +1 -0
- package/dist/state/snapshot.d.ts +38 -0
- package/dist/state/snapshot.d.ts.map +1 -0
- package/dist/state/snapshot.js +134 -0
- package/dist/state/snapshot.js.map +1 -0
- package/dist/state/task-store.d.ts +25 -0
- package/dist/state/task-store.d.ts.map +1 -0
- package/dist/state/task-store.js +167 -0
- package/dist/state/task-store.js.map +1 -0
- package/dist/terminal/attach.d.ts +7 -0
- package/dist/terminal/attach.d.ts.map +1 -0
- package/dist/terminal/attach.js +26 -0
- package/dist/terminal/attach.js.map +1 -0
- package/dist/terminal/index.d.ts +3 -0
- package/dist/terminal/index.d.ts.map +1 -0
- package/dist/terminal/index.js +3 -0
- package/dist/terminal/index.js.map +1 -0
- package/dist/terminal/key-sanitizer.d.ts +2 -0
- package/dist/terminal/key-sanitizer.d.ts.map +1 -0
- package/dist/terminal/key-sanitizer.js +9 -0
- package/dist/terminal/key-sanitizer.js.map +1 -0
- package/dist/terminal/stream-ws.d.ts +3 -0
- package/dist/terminal/stream-ws.d.ts.map +1 -0
- package/dist/terminal/stream-ws.js +426 -0
- package/dist/terminal/stream-ws.js.map +1 -0
- package/dist/terminal/ws-auth.d.ts +5 -0
- package/dist/terminal/ws-auth.d.ts.map +1 -0
- package/dist/terminal/ws-auth.js +45 -0
- package/dist/terminal/ws-auth.js.map +1 -0
- package/dist/timing/debounced-task.d.ts +9 -0
- package/dist/timing/debounced-task.d.ts.map +1 -0
- package/dist/timing/debounced-task.js +23 -0
- package/dist/timing/debounced-task.js.map +1 -0
- package/dist/timing/periodic-task-runner.d.ts +21 -0
- package/dist/timing/periodic-task-runner.d.ts.map +1 -0
- package/dist/timing/periodic-task-runner.js +61 -0
- package/dist/timing/periodic-task-runner.js.map +1 -0
- package/dist/web/assets/index-53CBbz4w.js +4 -0
- package/dist/web/assets/index-B9D6BV08.css +1 -0
- package/dist/web/assets/react-BG4Iuztk.js +40 -0
- package/dist/web/assets/router-B_Nv0oRz.js +12 -0
- package/dist/web/assets/xterm-CFbL2ovg.css +32 -0
- package/dist/web/assets/xterm-D5X2JljJ.js +9 -0
- package/dist/web/index.html +17 -0
- package/package.json +44 -5
- package/index.js +0 -1
package/dist/index.js
ADDED
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
import { resolve, dirname, join } from 'node:path';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
import { rename, stat } from 'node:fs/promises';
|
|
4
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
5
|
+
import { loadConfig, resolveConfigPath, resolveStateDir, userConfigPath, createDefaultConfig, } from './config/loader.js';
|
|
6
|
+
import { initStateDir } from './state/init.js';
|
|
7
|
+
import { AgentStore } from './state/agent-store.js';
|
|
8
|
+
import { TaskStore } from './state/task-store.js';
|
|
9
|
+
import { ErrorRecordStore } from './state/error-record-store.js';
|
|
10
|
+
import { PostApproveStore } from './state/post-approve-store.js';
|
|
11
|
+
import { LockManager } from './state/lock.js';
|
|
12
|
+
import { ProcessLock, ProcessLockError } from './state/process-lock.js';
|
|
13
|
+
import { EventBus } from './event/bus.js';
|
|
14
|
+
import { EventLog } from './event/log.js';
|
|
15
|
+
import { SkillRegistry } from './skill/registry.js';
|
|
16
|
+
import { AgentManager } from './agent/manager.js';
|
|
17
|
+
import { PaneStreamerManager } from './agent/pane-streamer-manager.js';
|
|
18
|
+
import { EventBroker } from './event/broker.js';
|
|
19
|
+
import { EventPublisher } from './event/publish.js';
|
|
20
|
+
import { autoBootstrapAgentIds, bootstrapAutoRepos } from './agent/bootstrap.js';
|
|
21
|
+
import { registerEventHandlers } from './event/handlers.js';
|
|
22
|
+
import { GitHubPoller } from './github/poller.js';
|
|
23
|
+
import { resolveEventRouting } from './github/resolver.js';
|
|
24
|
+
import { createRunner } from './agent/runner.js';
|
|
25
|
+
import { TmuxProbePoller, TmuxSessionStatusStore } from './agent/tmux-probe-poller.js';
|
|
26
|
+
import { BootstrapPoller } from './agent/bootstrap-poller.js';
|
|
27
|
+
import { buildApp } from './app.js';
|
|
28
|
+
import { RestartCoordinator } from './lifecycle/restart.js';
|
|
29
|
+
import { consumeRestartSentinel } from './lifecycle/restart-sentinel.js';
|
|
30
|
+
// All-miss returns first candidate so caller surfaces ENOENT instead of silently using wrong path.
|
|
31
|
+
export function pickExistingPath(base, candidates) {
|
|
32
|
+
for (const rel of candidates) {
|
|
33
|
+
const p = resolve(base, rel);
|
|
34
|
+
if (existsSync(p))
|
|
35
|
+
return p;
|
|
36
|
+
}
|
|
37
|
+
return resolve(base, candidates[0]);
|
|
38
|
+
}
|
|
39
|
+
export async function migrateLegacyPollerStateFile(stateDir, legacyProjectIds, newStatePath) {
|
|
40
|
+
try {
|
|
41
|
+
await stat(newStatePath);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
if (err.code !== 'ENOENT') {
|
|
46
|
+
console.warn(`[startup] poller cursor migration: stat(${newStatePath}) failed:`, err);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
for (const legacyId of legacyProjectIds) {
|
|
51
|
+
const legacyPath = join(stateDir, 'state', `poller-${legacyId}.json`);
|
|
52
|
+
try {
|
|
53
|
+
await rename(legacyPath, newStatePath);
|
|
54
|
+
console.log(`[startup] migrated poller cursor ${legacyPath} → ${newStatePath}`);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
const code = err.code;
|
|
59
|
+
if (code === 'ENOENT')
|
|
60
|
+
continue;
|
|
61
|
+
console.warn(`[startup] poller cursor migration ${legacyPath} → ${newStatePath} failed:`, err);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
export async function scanLegacyPending(taskStore) {
|
|
67
|
+
const legacyPending = (await taskStore.list({ status: 'pending' }))
|
|
68
|
+
.filter(t => !t.preferredAgentId);
|
|
69
|
+
if (legacyPending.length > 0) {
|
|
70
|
+
console.warn(`[startup] ${legacyPending.length} legacy pending task(s) without preferredAgentId; ` +
|
|
71
|
+
`they will be skipped by drainQueue until you assign a dev. ` +
|
|
72
|
+
`Fix via: PATCH /api/tasks/<id> { preferredAgentId: 'dev-...' } or cancel them. ` +
|
|
73
|
+
`Task IDs: ${legacyPending.map(t => t.id).join(', ')}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
export function scheduleBackgroundDrain(agentManager, projects) {
|
|
77
|
+
return (async () => {
|
|
78
|
+
for (const project of projects) {
|
|
79
|
+
try {
|
|
80
|
+
await agentManager.drainQueue(project.id);
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
console.error(`[startup] drainQueue failed for project ${project.id}:`, err);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
})();
|
|
87
|
+
}
|
|
88
|
+
export async function startServer(configPath) {
|
|
89
|
+
// Zero-config first run: auto-create a minimal user-level config at ~/.baxian/config.json
|
|
90
|
+
// so `baxian` works straight after `npm install -g baxian`. UI then populates project/agent
|
|
91
|
+
// via saveConfig writebacks. Explicit -c <path> doesn't auto-create — surface ENOENT instead.
|
|
92
|
+
let cfgPath = await resolveConfigPath(configPath);
|
|
93
|
+
if (!cfgPath) {
|
|
94
|
+
cfgPath = userConfigPath();
|
|
95
|
+
await createDefaultConfig(cfgPath);
|
|
96
|
+
console.log(`Initialized config at ${cfgPath} (no baxian.json found in cwd, no ~/.baxian/config.json yet)`);
|
|
97
|
+
}
|
|
98
|
+
const config = await loadConfig(cfgPath);
|
|
99
|
+
const cfgDir = dirname(cfgPath);
|
|
100
|
+
const stateDir = resolveStateDir(cfgPath);
|
|
101
|
+
await initStateDir(stateDir);
|
|
102
|
+
const processLock = new ProcessLock(stateDir);
|
|
103
|
+
try {
|
|
104
|
+
await processLock.acquire();
|
|
105
|
+
}
|
|
106
|
+
catch (err) {
|
|
107
|
+
if (err instanceof ProcessLockError) {
|
|
108
|
+
console.error('[startup] process lock acquisition failed', err);
|
|
109
|
+
}
|
|
110
|
+
throw err;
|
|
111
|
+
}
|
|
112
|
+
const releaseLockStrict = () => processLock.release();
|
|
113
|
+
const releaseLockBestEffort = async () => {
|
|
114
|
+
try {
|
|
115
|
+
await releaseLockStrict();
|
|
116
|
+
}
|
|
117
|
+
catch (e) {
|
|
118
|
+
console.warn('[shutdown] processLock.release failed', e);
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
process.once('exit', () => { processLock.releaseSync(); });
|
|
122
|
+
process.once('SIGINT', () => { void (async () => { await releaseLockBestEffort(); process.exit(130); })(); });
|
|
123
|
+
process.once('SIGTERM', () => { void (async () => { await releaseLockBestEffort(); process.exit(143); })(); });
|
|
124
|
+
try {
|
|
125
|
+
const sentinel = await consumeRestartSentinel(stateDir);
|
|
126
|
+
if (sentinel) {
|
|
127
|
+
console.log(`[startup] restart confirmed (parentPid=${sentinel.parentPid}, ` +
|
|
128
|
+
`actor=${sentinel.actor}, age=${Date.now() - sentinel.createdAt}ms)`);
|
|
129
|
+
}
|
|
130
|
+
const skillSource = resolve(cfgDir, 'skills');
|
|
131
|
+
const serverDistDir = dirname(fileURLToPath(import.meta.url));
|
|
132
|
+
const builtinSkills = pickExistingPath(serverDistDir, ['./skills', '../../../skills']);
|
|
133
|
+
const agentStore = new AgentStore(`${stateDir}/state/agents`);
|
|
134
|
+
const taskStore = new TaskStore(`${stateDir}/state/tasks`);
|
|
135
|
+
const errorRecordStore = new ErrorRecordStore(`${stateDir}/state/errors`);
|
|
136
|
+
const postApproveStore = new PostApproveStore(`${stateDir}/state/post-approve`);
|
|
137
|
+
const lockManager = new LockManager(`${stateDir}/locks`);
|
|
138
|
+
const eventLog = new EventLog(`${stateDir}/events`);
|
|
139
|
+
const eventBus = new EventBus(eventLog);
|
|
140
|
+
const eventBroker = new EventBroker();
|
|
141
|
+
const tmuxSessionStatusStore = new TmuxSessionStatusStore();
|
|
142
|
+
const registry = new SkillRegistry(skillSource, builtinSkills);
|
|
143
|
+
await registry.scan();
|
|
144
|
+
const paneStreamerManager = new PaneStreamerManager({
|
|
145
|
+
runnerFactory: (agent) => createRunner(agent.mode, agent.host),
|
|
146
|
+
});
|
|
147
|
+
const agentManager = new AgentManager({
|
|
148
|
+
config,
|
|
149
|
+
agentStore,
|
|
150
|
+
taskStore,
|
|
151
|
+
lockManager,
|
|
152
|
+
eventBus,
|
|
153
|
+
skillRegistry: registry,
|
|
154
|
+
paneStreamerManager,
|
|
155
|
+
postApproveStore,
|
|
156
|
+
errorRecordStore,
|
|
157
|
+
});
|
|
158
|
+
const tmuxProbePoller = new TmuxProbePoller({
|
|
159
|
+
config,
|
|
160
|
+
store: tmuxSessionStatusStore,
|
|
161
|
+
agentManager,
|
|
162
|
+
agentStore,
|
|
163
|
+
errorRecordStore,
|
|
164
|
+
});
|
|
165
|
+
await agentManager.recover();
|
|
166
|
+
registerEventHandlers(eventBus, agentManager, config);
|
|
167
|
+
// Arm marker watchers AFTER handlers register so emits land on live listeners.
|
|
168
|
+
await agentManager.armRecoveredPostApproveMarkers();
|
|
169
|
+
await agentManager.armRecoveredSpecMarkers();
|
|
170
|
+
const snapshotCtx = { agentManager, agentStore, taskStore, tmuxSessionStatusStore, errorRecordStore };
|
|
171
|
+
const eventPublisher = new EventPublisher(eventBroker, snapshotCtx, taskStore);
|
|
172
|
+
agentStore.onChange((kind, id) => eventPublisher.publishAgentChange(kind, id));
|
|
173
|
+
tmuxSessionStatusStore.onChange((kind, id) => eventPublisher.publishAgentChange(kind, id));
|
|
174
|
+
taskStore.onChange((kind, id) => eventPublisher.publishTaskChange(kind, id));
|
|
175
|
+
// Notify subscribers when bootstrap touches an agent's error state; agentStore alone misses
|
|
176
|
+
// failure paths since those don't mutate any binding. Must be wired AFTER publisher exists.
|
|
177
|
+
const onBootstrapAgentAffected = (ids) => {
|
|
178
|
+
for (const id of ids)
|
|
179
|
+
eventPublisher.publishAgentChange('set', id);
|
|
180
|
+
};
|
|
181
|
+
const bootstrapPoller = new BootstrapPoller({
|
|
182
|
+
config,
|
|
183
|
+
agentStore,
|
|
184
|
+
eventBus,
|
|
185
|
+
repoCache: agentManager.getRepoCache(),
|
|
186
|
+
errorRecordStore,
|
|
187
|
+
onAgentAffected: onBootstrapAgentAffected,
|
|
188
|
+
});
|
|
189
|
+
const migrationResult = await taskStore.migrateLegacyFiles();
|
|
190
|
+
if (migrationResult.migrated > 0 || migrationResult.failed > 0) {
|
|
191
|
+
console.log(`[startup] task-store migration: ${migrationResult.migrated} migrated, ${migrationResult.failed} failed`);
|
|
192
|
+
}
|
|
193
|
+
await scanLegacyPending(taskStore);
|
|
194
|
+
// Sweep stale bootstrap errors for agents no longer in the auto-bootstrap set. Covers:
|
|
195
|
+
// (a) agent deleted while server was down; (b) agent transitioned to explicit workdir
|
|
196
|
+
// mode (id stays, leaves bootstrap); (c) PATCH /config restartRequired window where the
|
|
197
|
+
// old poller appended a fresh stale record before the operator restarted.
|
|
198
|
+
try {
|
|
199
|
+
const result = await errorRecordStore.sweepStaleBootstrapErrors(autoBootstrapAgentIds(config));
|
|
200
|
+
if (result.removed > 0) {
|
|
201
|
+
console.log(`[startup] swept ${result.removed} stale bootstrap error records for agents no longer in auto-bootstrap`);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
catch (err) {
|
|
205
|
+
console.warn('[startup] sweepStaleBootstrapErrors failed:', err);
|
|
206
|
+
}
|
|
207
|
+
void bootstrapAutoRepos({
|
|
208
|
+
config,
|
|
209
|
+
agentStore,
|
|
210
|
+
eventBus,
|
|
211
|
+
repoCache: agentManager.getRepoCache(),
|
|
212
|
+
errorRecordStore,
|
|
213
|
+
onAgentAffected: onBootstrapAgentAffected,
|
|
214
|
+
}).catch(err => console.error('[baxian] bootstrap failed:', err));
|
|
215
|
+
const poller = new GitHubPoller({
|
|
216
|
+
runner: createRunner('local'),
|
|
217
|
+
onEvent: async (projectId, mapped) => {
|
|
218
|
+
const routing = await resolveEventRouting(agentManager, mapped);
|
|
219
|
+
await eventBus.emit({
|
|
220
|
+
id: '',
|
|
221
|
+
type: mapped.type,
|
|
222
|
+
timestamp: new Date().toISOString(),
|
|
223
|
+
projectId,
|
|
224
|
+
...(routing.taskId ? { taskId: routing.taskId } : {}),
|
|
225
|
+
...(routing.agentId ? { agentId: routing.agentId } : {}),
|
|
226
|
+
data: mapped.data,
|
|
227
|
+
});
|
|
228
|
+
},
|
|
229
|
+
});
|
|
230
|
+
const seenRepos = new Set();
|
|
231
|
+
for (const project of config.project) {
|
|
232
|
+
const repoKey = project.repo.toLowerCase();
|
|
233
|
+
if (seenRepos.has(repoKey))
|
|
234
|
+
continue;
|
|
235
|
+
seenRepos.add(repoKey);
|
|
236
|
+
const repoFileKey = encodeURIComponent(repoKey);
|
|
237
|
+
const newStatePath = join(stateDir, 'state', `poller-${repoFileKey}.json`);
|
|
238
|
+
const legacyIds = config.project
|
|
239
|
+
.filter(p => p.repo.toLowerCase() === repoKey)
|
|
240
|
+
.map(p => p.id);
|
|
241
|
+
await migrateLegacyPollerStateFile(stateDir, legacyIds, newStatePath);
|
|
242
|
+
poller.add({ projectId: project.id, repo: project.repo, statePath: newStatePath });
|
|
243
|
+
}
|
|
244
|
+
poller.setLifecycleHook(() => {
|
|
245
|
+
eventPublisher.publishPollersChange(() => poller.snapshots());
|
|
246
|
+
});
|
|
247
|
+
poller.start(config.server.githubPollIntervalMs ?? 30_000);
|
|
248
|
+
const httpsOpts = config.server.https
|
|
249
|
+
? {
|
|
250
|
+
key: readFileSync(config.server.https.keyFile),
|
|
251
|
+
cert: readFileSync(config.server.https.certFile),
|
|
252
|
+
}
|
|
253
|
+
: undefined;
|
|
254
|
+
const webRoot = pickExistingPath(serverDistDir, ['./web', '../../web/dist']);
|
|
255
|
+
const app = await buildApp({
|
|
256
|
+
config,
|
|
257
|
+
agentManager,
|
|
258
|
+
agentStore,
|
|
259
|
+
taskStore,
|
|
260
|
+
lockManager,
|
|
261
|
+
eventBus,
|
|
262
|
+
eventLog,
|
|
263
|
+
tmuxSessionStatusStore,
|
|
264
|
+
tmuxProbePoller,
|
|
265
|
+
bootstrapPoller,
|
|
266
|
+
configPath: cfgPath,
|
|
267
|
+
poller,
|
|
268
|
+
paneStreamerManager,
|
|
269
|
+
eventBroker,
|
|
270
|
+
errorRecordStore,
|
|
271
|
+
}, {
|
|
272
|
+
...(httpsOpts ? { https: httpsOpts } : {}),
|
|
273
|
+
webRoot,
|
|
274
|
+
...(config.server.allowedHosts ? { allowedHosts: config.server.allowedHosts } : {}),
|
|
275
|
+
});
|
|
276
|
+
app.addHook('onClose', releaseLockStrict);
|
|
277
|
+
const restartCoordinator = new RestartCoordinator({
|
|
278
|
+
app,
|
|
279
|
+
configPath: cfgPath,
|
|
280
|
+
stateDir,
|
|
281
|
+
beforeExit: releaseLockStrict,
|
|
282
|
+
});
|
|
283
|
+
app.ctx.restartCoordinator = restartCoordinator;
|
|
284
|
+
const host = config.server.host ?? '127.0.0.1';
|
|
285
|
+
if (host !== '127.0.0.1' && !config.server.token) {
|
|
286
|
+
console.warn(`[baxian] server.host=${host} but no server.token configured — API is unauthenticated. Set a token before exposing the server.`);
|
|
287
|
+
}
|
|
288
|
+
await app.listen({ port: config.server.port, host });
|
|
289
|
+
tmuxProbePoller.start();
|
|
290
|
+
bootstrapPoller.start();
|
|
291
|
+
void scheduleBackgroundDrain(agentManager, config.project);
|
|
292
|
+
// Print user-clickable URL. 0.0.0.0/:: bind addresses aren't connectable in browsers,
|
|
293
|
+
// so swap to 127.0.0.1 for the printed link; the underlying listen address is unchanged.
|
|
294
|
+
const browsable = host === '0.0.0.0' || host === '::' ? '127.0.0.1' : host;
|
|
295
|
+
const scheme = config.server.https ? 'https' : 'http';
|
|
296
|
+
console.log(`baxian server running on ${host}:${config.server.port}`);
|
|
297
|
+
console.log(`Open ${scheme}://${browsable}:${config.server.port} in your browser to manage projects.`);
|
|
298
|
+
}
|
|
299
|
+
catch (err) {
|
|
300
|
+
await releaseLockBestEffort();
|
|
301
|
+
throw err;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
if (process.argv[1]?.endsWith('index.js')) {
|
|
305
|
+
startServer().catch(err => {
|
|
306
|
+
console.error(err);
|
|
307
|
+
process.exit(1);
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface RestartSentinel {
|
|
2
|
+
kind: 'restart';
|
|
3
|
+
restartId: string;
|
|
4
|
+
parentPid: number;
|
|
5
|
+
createdAt: number;
|
|
6
|
+
ttlMs: number;
|
|
7
|
+
actor: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function writeRestartSentinelSync(opts: {
|
|
10
|
+
stateDir: string;
|
|
11
|
+
restartId: string;
|
|
12
|
+
parentPid: number;
|
|
13
|
+
actor: string;
|
|
14
|
+
ttlMs?: number;
|
|
15
|
+
}): void;
|
|
16
|
+
export declare function clearRestartSentinelSync(stateDir: string): void;
|
|
17
|
+
export declare function consumeRestartSentinel(stateDir: string): Promise<RestartSentinel | null>;
|
|
18
|
+
//# sourceMappingURL=restart-sentinel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"restart-sentinel.d.ts","sourceRoot":"","sources":["../../src/lifecycle/restart-sentinel.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,SAAS,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAQD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,IAAI,CAYP;AAED,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAM/D;AAED,wBAAsB,sBAAsB,CAC1C,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CA2BjC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
const SENTINEL_FILENAME = 'restart-intent.json';
|
|
4
|
+
function sentinelPath(stateDir) {
|
|
5
|
+
return path.join(stateDir, 'state', SENTINEL_FILENAME);
|
|
6
|
+
}
|
|
7
|
+
export function writeRestartSentinelSync(opts) {
|
|
8
|
+
const payload = {
|
|
9
|
+
kind: 'restart',
|
|
10
|
+
restartId: opts.restartId,
|
|
11
|
+
parentPid: opts.parentPid,
|
|
12
|
+
createdAt: Date.now(),
|
|
13
|
+
ttlMs: opts.ttlMs ?? 60_000,
|
|
14
|
+
actor: opts.actor,
|
|
15
|
+
};
|
|
16
|
+
const target = sentinelPath(opts.stateDir);
|
|
17
|
+
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
18
|
+
fs.writeFileSync(target, JSON.stringify(payload) + '\n');
|
|
19
|
+
}
|
|
20
|
+
export function clearRestartSentinelSync(stateDir) {
|
|
21
|
+
try {
|
|
22
|
+
fs.unlinkSync(sentinelPath(stateDir));
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
/* best-effort */
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
export async function consumeRestartSentinel(stateDir) {
|
|
29
|
+
const target = sentinelPath(stateDir);
|
|
30
|
+
let raw;
|
|
31
|
+
try {
|
|
32
|
+
raw = await fs.promises.readFile(target, 'utf-8');
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
await fs.promises.unlink(target).catch(() => { });
|
|
38
|
+
let parsed;
|
|
39
|
+
try {
|
|
40
|
+
parsed = JSON.parse(raw);
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
if (parsed.kind !== 'restart')
|
|
46
|
+
return null;
|
|
47
|
+
if (typeof parsed.restartId !== 'string')
|
|
48
|
+
return null;
|
|
49
|
+
if (typeof parsed.parentPid !== 'number')
|
|
50
|
+
return null;
|
|
51
|
+
if (typeof parsed.createdAt !== 'number')
|
|
52
|
+
return null;
|
|
53
|
+
if (typeof parsed.ttlMs !== 'number')
|
|
54
|
+
return null;
|
|
55
|
+
if (typeof parsed.actor !== 'string')
|
|
56
|
+
return null;
|
|
57
|
+
if (Date.now() - parsed.createdAt > parsed.ttlMs)
|
|
58
|
+
return null;
|
|
59
|
+
return parsed;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=restart-sentinel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"restart-sentinel.js","sourceRoot":"","sources":["../../src/lifecycle/restart-sentinel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAW7B,MAAM,iBAAiB,GAAG,qBAAqB,CAAC;AAEhD,SAAS,YAAY,CAAC,QAAgB;IACpC,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,iBAAiB,CAAC,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,IAMxC;IACC,MAAM,OAAO,GAAoB;QAC/B,IAAI,EAAE,SAAS;QACf,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;QACrB,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,MAAM;QAC3B,KAAK,EAAE,IAAI,CAAC,KAAK;KAClB,CAAC;IACF,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC3C,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACxD,EAAE,CAAC,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;AAC3D,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,QAAgB;IACvD,IAAI,CAAC;QACH,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,iBAAiB;IACnB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,QAAgB;IAEhB,MAAM,MAAM,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IACtC,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAEjD,IAAI,MAAgC,CAAC;IACrC,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAC3C,IAAI,OAAO,MAAM,CAAC,SAAS,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACtD,IAAI,OAAO,MAAM,CAAC,SAAS,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACtD,IAAI,OAAO,MAAM,CAAC,SAAS,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACtD,IAAI,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAClD,IAAI,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAElD,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IAE9D,OAAO,MAAyB,CAAC;AACnC,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { FastifyInstance } from 'fastify';
|
|
2
|
+
export interface RestartCoordinatorOptions {
|
|
3
|
+
app: Pick<FastifyInstance, 'close'>;
|
|
4
|
+
configPath: string;
|
|
5
|
+
stateDir: string;
|
|
6
|
+
/** Runs between app.close() and process.exit(); throws here abort restart. */
|
|
7
|
+
beforeExit?: () => Promise<void>;
|
|
8
|
+
}
|
|
9
|
+
export declare class RestartCoordinator {
|
|
10
|
+
private opts;
|
|
11
|
+
private restarting;
|
|
12
|
+
private actor;
|
|
13
|
+
private restartId;
|
|
14
|
+
constructor(opts: RestartCoordinatorOptions);
|
|
15
|
+
isRestarting(): boolean;
|
|
16
|
+
beginRestart(audit: {
|
|
17
|
+
actor: string;
|
|
18
|
+
}): void;
|
|
19
|
+
execute(): Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=restart.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"restart.d.ts","sourceRoot":"","sources":["../../src/lifecycle/restart.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAQ/C,MAAM,WAAW,yBAAyB;IACxC,GAAG,EAAE,IAAI,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,8EAA8E;IAC9E,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAClC;AAED,qBAAa,kBAAkB;IAKjB,OAAO,CAAC,IAAI;IAJxB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,SAAS,CAAM;gBAEH,IAAI,EAAE,yBAAyB;IAEnD,YAAY,IAAI,OAAO;IAIvB,YAAY,CAAC,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAStC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAsC/B"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { clearRestartSentinelSync, writeRestartSentinelSync, } from './restart-sentinel.js';
|
|
3
|
+
const APP_CLOSE_GRACE_MS = 5000;
|
|
4
|
+
export class RestartCoordinator {
|
|
5
|
+
opts;
|
|
6
|
+
restarting = false;
|
|
7
|
+
actor = 'unknown';
|
|
8
|
+
restartId = '';
|
|
9
|
+
constructor(opts) {
|
|
10
|
+
this.opts = opts;
|
|
11
|
+
}
|
|
12
|
+
isRestarting() {
|
|
13
|
+
return this.restarting;
|
|
14
|
+
}
|
|
15
|
+
beginRestart(audit) {
|
|
16
|
+
if (this.restarting) {
|
|
17
|
+
throw new Error('restart already in progress');
|
|
18
|
+
}
|
|
19
|
+
this.restarting = true;
|
|
20
|
+
this.actor = audit.actor;
|
|
21
|
+
this.restartId = randomUUID();
|
|
22
|
+
}
|
|
23
|
+
async execute() {
|
|
24
|
+
try {
|
|
25
|
+
writeRestartSentinelSync({
|
|
26
|
+
stateDir: this.opts.stateDir,
|
|
27
|
+
restartId: this.restartId,
|
|
28
|
+
parentPid: process.pid,
|
|
29
|
+
actor: this.actor,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
catch (err) {
|
|
33
|
+
console.error(`[restart] sentinel write failed (restartId=${this.restartId}, actor=${this.actor}):`, err);
|
|
34
|
+
this.restarting = false;
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
await Promise.race([
|
|
39
|
+
this.opts.app.close(),
|
|
40
|
+
new Promise(r => setTimeout(r, APP_CLOSE_GRACE_MS)),
|
|
41
|
+
]);
|
|
42
|
+
if (this.opts.beforeExit) {
|
|
43
|
+
await this.opts.beforeExit();
|
|
44
|
+
}
|
|
45
|
+
// Exit only; an external supervisor (systemd Restart=always in prod, or whoever ran
|
|
46
|
+
// `baxian start` in dev) is responsible for relaunching. Self-spawn would race with
|
|
47
|
+
// systemd and leave a stale detached process holding the lock.
|
|
48
|
+
process.exit(0);
|
|
49
|
+
}
|
|
50
|
+
catch (err) {
|
|
51
|
+
console.error(`[restart] failed before exit (restartId=${this.restartId}, actor=${this.actor}):`, err);
|
|
52
|
+
clearRestartSentinelSync(this.opts.stateDir);
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=restart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"restart.js","sourceRoot":"","sources":["../../src/lifecycle/restart.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,EACL,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,uBAAuB,CAAC;AAE/B,MAAM,kBAAkB,GAAG,IAAI,CAAC;AAUhC,MAAM,OAAO,kBAAkB;IAKT;IAJZ,UAAU,GAAG,KAAK,CAAC;IACnB,KAAK,GAAG,SAAS,CAAC;IAClB,SAAS,GAAG,EAAE,CAAC;IAEvB,YAAoB,IAA+B;QAA/B,SAAI,GAAJ,IAAI,CAA2B;IAAG,CAAC;IAEvD,YAAY;QACV,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED,YAAY,CAAC,KAAwB;QACnC,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;QACjD,CAAC;QACD,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;QACzB,IAAI,CAAC,SAAS,GAAG,UAAU,EAAE,CAAC;IAChC,CAAC;IAED,KAAK,CAAC,OAAO;QACX,IAAI,CAAC;YACH,wBAAwB,CAAC;gBACvB,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ;gBAC5B,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,SAAS,EAAE,OAAO,CAAC,GAAG;gBACtB,KAAK,EAAE,IAAI,CAAC,KAAK;aAClB,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CACX,8CAA8C,IAAI,CAAC,SAAS,WAAW,IAAI,CAAC,KAAK,IAAI,EACrF,GAAG,CACJ,CAAC;YACF,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;YACxB,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,MAAM,OAAO,CAAC,IAAI,CAAC;gBACjB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE;gBACrB,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,kBAAkB,CAAC,CAAC;aAC1D,CAAC,CAAC;YACH,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;gBACzB,MAAM,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YAC/B,CAAC;YACD,oFAAoF;YACpF,oFAAoF;YACpF,+DAA+D;YAC/D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CACX,2CAA2C,IAAI,CAAC,SAAS,WAAW,IAAI,CAAC,KAAK,IAAI,EAClF,GAAG,CACJ,CAAC;YACF,wBAAwB,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { AgentRole, TaskStatus } from './types.js';
|
|
2
|
+
export declare const DEFAULT_REVIEW_ROUNDS = 10;
|
|
3
|
+
export declare const DEFAULT_SERVER_PORT = 3000;
|
|
4
|
+
export declare const BRANCH_PREFIX = "bx/";
|
|
5
|
+
export declare const WORKTREE_DIR = ".baxian-worktrees";
|
|
6
|
+
export declare const STATE_DIR = ".baxian";
|
|
7
|
+
export declare const CONFIG_FILE = "baxian.json";
|
|
8
|
+
export declare const MAX_CONFIG_BACKUPS = 7;
|
|
9
|
+
export declare const USER_CONFIG_REL = ".baxian/config.json";
|
|
10
|
+
export declare const USER_STATE_REL = ".baxian";
|
|
11
|
+
export declare const AGENT_PHASES: Record<AgentRole, Record<string, {
|
|
12
|
+
skills: string[];
|
|
13
|
+
}>>;
|
|
14
|
+
export declare const PHASE_EXPECTED_STATUS: Record<string, TaskStatus[]>;
|
|
15
|
+
export declare const PHASE_REQUIRES_AGENT_BOUND_TO_TASK: Record<string, boolean>;
|
|
16
|
+
export declare const TASK_TERMINAL_STATUSES: readonly TaskStatus[];
|
|
17
|
+
export declare const TASK_TERMINAL_STATUS_SET: ReadonlySet<TaskStatus>;
|
|
18
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/shared/constants.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExD,eAAO,MAAM,qBAAqB,KAAK,CAAC;AACxC,eAAO,MAAM,mBAAmB,OAAO,CAAC;AAExC,eAAO,MAAM,aAAa,QAAQ,CAAC;AACnC,eAAO,MAAM,YAAY,sBAAsB,CAAC;AAChD,eAAO,MAAM,SAAS,YAAY,CAAC;AACnC,eAAO,MAAM,WAAW,gBAAgB,CAAC;AACzC,eAAO,MAAM,kBAAkB,IAAI,CAAC;AAMpC,eAAO,MAAM,eAAe,wBAAwB,CAAC;AACrD,eAAO,MAAM,cAAc,YAAY,CAAC;AAExC,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAehF,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,CAU9D,CAAC;AAEF,eAAO,MAAM,kCAAkC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAUtE,CAAC;AAGF,eAAO,MAAM,sBAAsB,EAAE,SAAS,UAAU,EAKvD,CAAC;AAEF,eAAO,MAAM,wBAAwB,EAAE,WAAW,CAAC,UAAU,CAAmC,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
export const DEFAULT_REVIEW_ROUNDS = 10;
|
|
2
|
+
export const DEFAULT_SERVER_PORT = 3000;
|
|
3
|
+
export const BRANCH_PREFIX = 'bx/';
|
|
4
|
+
export const WORKTREE_DIR = '.baxian-worktrees';
|
|
5
|
+
export const STATE_DIR = '.baxian';
|
|
6
|
+
export const CONFIG_FILE = 'baxian.json';
|
|
7
|
+
export const MAX_CONFIG_BACKUPS = 7;
|
|
8
|
+
// User-level fallback under $HOME, used when cwd has no baxian.json.
|
|
9
|
+
// Mirrors the cwd-mode layout: `~/.baxian/config.json` is the config, `~/.baxian/`
|
|
10
|
+
// itself is the state dir (state/, locks/, events/ live directly under it).
|
|
11
|
+
// Same naming as the cwd-mode `./.baxian/` so users see one consistent label.
|
|
12
|
+
export const USER_CONFIG_REL = '.baxian/config.json';
|
|
13
|
+
export const USER_STATE_REL = '.baxian';
|
|
14
|
+
export const AGENT_PHASES = {
|
|
15
|
+
dev: {
|
|
16
|
+
develop: { skills: ['baxian-rules', 'task-check', 'spells'] },
|
|
17
|
+
fix: { skills: ['baxian-rules', 'pr-feedback', 'spells'] },
|
|
18
|
+
post_approve: { skills: ['baxian-rules', 'pr-feedback', 'spells'] },
|
|
19
|
+
merge: { skills: ['baxian-rules', 'merge-sync', 'spells'] },
|
|
20
|
+
'spec-fix': { skills: ['baxian-rules', 'spells'] },
|
|
21
|
+
code: { skills: ['baxian-rules', 'task-check', 'spells'] },
|
|
22
|
+
},
|
|
23
|
+
qa: {
|
|
24
|
+
review: { skills: ['baxian-rules', 'pr-review', 'spells'] },
|
|
25
|
+
recheck: { skills: ['baxian-rules', 'pr-recheck', 'spells'] },
|
|
26
|
+
merge: { skills: ['baxian-rules', 'merge-sync', 'spells'] },
|
|
27
|
+
'spec-review': { skills: ['baxian-rules', 'spells'] },
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
export const PHASE_EXPECTED_STATUS = {
|
|
31
|
+
develop: ['in_progress'],
|
|
32
|
+
review: ['review'],
|
|
33
|
+
recheck: ['review'],
|
|
34
|
+
fix: ['fixing'],
|
|
35
|
+
post_approve: ['approved'],
|
|
36
|
+
merge: ['approved', 'review'],
|
|
37
|
+
'spec-review': ['review'],
|
|
38
|
+
'spec-fix': ['fixing'],
|
|
39
|
+
code: ['in_progress'],
|
|
40
|
+
};
|
|
41
|
+
export const PHASE_REQUIRES_AGENT_BOUND_TO_TASK = {
|
|
42
|
+
develop: true,
|
|
43
|
+
fix: true,
|
|
44
|
+
post_approve: true,
|
|
45
|
+
review: false,
|
|
46
|
+
recheck: false,
|
|
47
|
+
merge: false,
|
|
48
|
+
'spec-review': false,
|
|
49
|
+
'spec-fix': true,
|
|
50
|
+
code: true,
|
|
51
|
+
};
|
|
52
|
+
// Terminal statuses — no auto transitions fire from these.
|
|
53
|
+
export const TASK_TERMINAL_STATUSES = [
|
|
54
|
+
'merged',
|
|
55
|
+
'failed',
|
|
56
|
+
'max_rounds',
|
|
57
|
+
'cancelled',
|
|
58
|
+
];
|
|
59
|
+
export const TASK_TERMINAL_STATUS_SET = new Set(TASK_TERMINAL_STATUSES);
|
|
60
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/shared/constants.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,qBAAqB,GAAG,EAAE,CAAC;AACxC,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,CAAC;AAExC,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,CAAC;AACnC,MAAM,CAAC,MAAM,YAAY,GAAG,mBAAmB,CAAC;AAChD,MAAM,CAAC,MAAM,SAAS,GAAG,SAAS,CAAC;AACnC,MAAM,CAAC,MAAM,WAAW,GAAG,aAAa,CAAC;AACzC,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAEpC,qEAAqE;AACrE,mFAAmF;AACnF,4EAA4E;AAC5E,8EAA8E;AAC9E,MAAM,CAAC,MAAM,eAAe,GAAG,qBAAqB,CAAC;AACrD,MAAM,CAAC,MAAM,cAAc,GAAG,SAAS,CAAC;AAExC,MAAM,CAAC,MAAM,YAAY,GAA4D;IACnF,GAAG,EAAE;QACH,OAAO,EAAE,EAAE,MAAM,EAAE,CAAC,cAAc,EAAE,YAAY,EAAE,QAAQ,CAAC,EAAE;QAC7D,GAAG,EAAE,EAAE,MAAM,EAAE,CAAC,cAAc,EAAE,aAAa,EAAE,QAAQ,CAAC,EAAE;QAC1D,YAAY,EAAE,EAAE,MAAM,EAAE,CAAC,cAAc,EAAE,aAAa,EAAE,QAAQ,CAAC,EAAE;QACnE,KAAK,EAAE,EAAE,MAAM,EAAE,CAAC,cAAc,EAAE,YAAY,EAAE,QAAQ,CAAC,EAAE;QAC3D,UAAU,EAAE,EAAE,MAAM,EAAE,CAAC,cAAc,EAAE,QAAQ,CAAC,EAAE;QAClD,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,cAAc,EAAE,YAAY,EAAE,QAAQ,CAAC,EAAE;KAC3D;IACD,EAAE,EAAE;QACF,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,cAAc,EAAE,WAAW,EAAE,QAAQ,CAAC,EAAE;QAC3D,OAAO,EAAE,EAAE,MAAM,EAAE,CAAC,cAAc,EAAE,YAAY,EAAE,QAAQ,CAAC,EAAE;QAC7D,KAAK,EAAE,EAAE,MAAM,EAAE,CAAC,cAAc,EAAE,YAAY,EAAE,QAAQ,CAAC,EAAE;QAC3D,aAAa,EAAE,EAAE,MAAM,EAAE,CAAC,cAAc,EAAE,QAAQ,CAAC,EAAE;KACtD;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAiC;IACjE,OAAO,EAAE,CAAC,aAAa,CAAC;IACxB,MAAM,EAAE,CAAC,QAAQ,CAAC;IAClB,OAAO,EAAE,CAAC,QAAQ,CAAC;IACnB,GAAG,EAAE,CAAC,QAAQ,CAAC;IACf,YAAY,EAAE,CAAC,UAAU,CAAC;IAC1B,KAAK,EAAE,CAAC,UAAU,EAAE,QAAQ,CAAC;IAC7B,aAAa,EAAE,CAAC,QAAQ,CAAC;IACzB,UAAU,EAAE,CAAC,QAAQ,CAAC;IACtB,IAAI,EAAE,CAAC,aAAa,CAAC;CACtB,CAAC;AAEF,MAAM,CAAC,MAAM,kCAAkC,GAA4B;IACzE,OAAO,EAAE,IAAI;IACb,GAAG,EAAE,IAAI;IACT,YAAY,EAAE,IAAI;IAClB,MAAM,EAAE,KAAK;IACb,OAAO,EAAE,KAAK;IACd,KAAK,EAAE,KAAK;IACZ,aAAa,EAAE,KAAK;IACpB,UAAU,EAAE,IAAI;IAChB,IAAI,EAAE,IAAI;CACX,CAAC;AAEF,2DAA2D;AAC3D,MAAM,CAAC,MAAM,sBAAsB,GAA0B;IAC3D,QAAQ;IACR,QAAQ;IACR,YAAY;IACZ,WAAW;CACZ,CAAC;AAEF,MAAM,CAAC,MAAM,wBAAwB,GAA4B,IAAI,GAAG,CAAC,sBAAsB,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/shared/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/shared/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC"}
|