247-cli 1.2.0 → 1.4.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/agent/dist/db/index.d.ts.map +1 -1
- package/agent/dist/db/index.js +78 -0
- package/agent/dist/db/index.js.map +1 -1
- package/agent/dist/db/schema.d.ts +14 -2
- package/agent/dist/db/schema.d.ts.map +1 -1
- package/agent/dist/db/schema.js +10 -2
- package/agent/dist/db/schema.js.map +1 -1
- package/agent/dist/db/sessions.d.ts +35 -0
- package/agent/dist/db/sessions.d.ts.map +1 -1
- package/agent/dist/db/sessions.js +149 -3
- package/agent/dist/db/sessions.js.map +1 -1
- package/agent/dist/routes/index.d.ts +1 -0
- package/agent/dist/routes/index.d.ts.map +1 -1
- package/agent/dist/routes/index.js +1 -0
- package/agent/dist/routes/index.js.map +1 -1
- package/agent/dist/routes/notification.d.ts.map +1 -1
- package/agent/dist/routes/notification.js +54 -10
- package/agent/dist/routes/notification.js.map +1 -1
- package/agent/dist/routes/sessions.d.ts.map +1 -1
- package/agent/dist/routes/sessions.js +90 -0
- package/agent/dist/routes/sessions.js.map +1 -1
- package/agent/dist/routes/stop.d.ts +9 -0
- package/agent/dist/routes/stop.d.ts.map +1 -0
- package/agent/dist/routes/stop.js +121 -0
- package/agent/dist/routes/stop.js.map +1 -0
- package/agent/dist/server.d.ts.map +1 -1
- package/agent/dist/server.js +2 -1
- package/agent/dist/server.js.map +1 -1
- package/agent/dist/services/cleanup.d.ts +45 -0
- package/agent/dist/services/cleanup.d.ts.map +1 -0
- package/agent/dist/services/cleanup.js +130 -0
- package/agent/dist/services/cleanup.js.map +1 -0
- package/agent/dist/services/execution.d.ts +53 -0
- package/agent/dist/services/execution.d.ts.map +1 -0
- package/agent/dist/services/execution.js +75 -0
- package/agent/dist/services/execution.js.map +1 -0
- package/agent/dist/services/index.d.ts +7 -0
- package/agent/dist/services/index.d.ts.map +1 -0
- package/agent/dist/services/index.js +5 -0
- package/agent/dist/services/index.js.map +1 -0
- package/agent/dist/services/worktree.d.ts +41 -0
- package/agent/dist/services/worktree.d.ts.map +1 -0
- package/agent/dist/services/worktree.js +139 -0
- package/agent/dist/services/worktree.js.map +1 -0
- package/agent/dist/setup-statusline.d.ts.map +1 -1
- package/agent/dist/setup-statusline.js +62 -4
- package/agent/dist/setup-statusline.js.map +1 -1
- package/agent/dist/websocket-handlers.d.ts.map +1 -1
- package/agent/dist/websocket-handlers.js +49 -6
- package/agent/dist/websocket-handlers.js.map +1 -1
- package/agent/node_modules/247-shared/dist/types/index.d.ts +2 -0
- package/agent/node_modules/247-shared/dist/types/index.d.ts.map +1 -1
- package/agent/node_modules/247-shared/dist/types/index.js.map +1 -1
- package/agent/node_modules/247-shared/package.json +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { getCleanableWorktreeSessions, clearSessionWorktree } from '../db/sessions.js';
|
|
2
|
+
import { worktreeManager } from './worktree.js';
|
|
3
|
+
// Default: 72 hours before cleaning up archived session worktrees
|
|
4
|
+
const DEFAULT_MAX_IDLE_MS = 72 * 60 * 60 * 1000;
|
|
5
|
+
// Default: run cleanup every 30 minutes
|
|
6
|
+
const DEFAULT_CLEANUP_INTERVAL_MS = 30 * 60 * 1000;
|
|
7
|
+
/**
|
|
8
|
+
* CleanupService - Automatically cleans up stale worktrees.
|
|
9
|
+
* Runs periodically to remove worktrees from archived sessions.
|
|
10
|
+
*/
|
|
11
|
+
export class CleanupService {
|
|
12
|
+
intervalHandle = null;
|
|
13
|
+
config;
|
|
14
|
+
projectPathResolver;
|
|
15
|
+
constructor(projectPathResolver, config = {}) {
|
|
16
|
+
this.projectPathResolver = projectPathResolver;
|
|
17
|
+
this.config = {
|
|
18
|
+
maxIdleMs: config.maxIdleMs ?? DEFAULT_MAX_IDLE_MS,
|
|
19
|
+
intervalMs: config.intervalMs ?? DEFAULT_CLEANUP_INTERVAL_MS,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Start the cleanup job.
|
|
24
|
+
*/
|
|
25
|
+
start() {
|
|
26
|
+
if (this.intervalHandle) {
|
|
27
|
+
console.log('[Cleanup] Already running');
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
console.log(`[Cleanup] Starting cleanup job (interval: ${this.config.intervalMs / 1000 / 60}min, max idle: ${this.config.maxIdleMs / 1000 / 60 / 60}h)`);
|
|
31
|
+
// Run immediately on start
|
|
32
|
+
this.runCleanup().catch((err) => {
|
|
33
|
+
console.error('[Cleanup] Initial cleanup failed:', err);
|
|
34
|
+
});
|
|
35
|
+
// Then run periodically
|
|
36
|
+
this.intervalHandle = setInterval(() => {
|
|
37
|
+
this.runCleanup().catch((err) => {
|
|
38
|
+
console.error('[Cleanup] Periodic cleanup failed:', err);
|
|
39
|
+
});
|
|
40
|
+
}, this.config.intervalMs);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Stop the cleanup job.
|
|
44
|
+
*/
|
|
45
|
+
stop() {
|
|
46
|
+
if (this.intervalHandle) {
|
|
47
|
+
clearInterval(this.intervalHandle);
|
|
48
|
+
this.intervalHandle = null;
|
|
49
|
+
console.log('[Cleanup] Stopped cleanup job');
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Run a cleanup cycle.
|
|
54
|
+
* Returns info about what was cleaned up.
|
|
55
|
+
*/
|
|
56
|
+
async runCleanup() {
|
|
57
|
+
const result = {
|
|
58
|
+
cleanedSessions: [],
|
|
59
|
+
errors: [],
|
|
60
|
+
};
|
|
61
|
+
try {
|
|
62
|
+
// Get archived sessions with worktrees that are old enough to clean
|
|
63
|
+
const sessions = getCleanableWorktreeSessions(this.config.maxIdleMs);
|
|
64
|
+
if (sessions.length === 0) {
|
|
65
|
+
return result;
|
|
66
|
+
}
|
|
67
|
+
console.log(`[Cleanup] Found ${sessions.length} sessions to clean up`);
|
|
68
|
+
for (const session of sessions) {
|
|
69
|
+
if (!session.worktree_path)
|
|
70
|
+
continue;
|
|
71
|
+
try {
|
|
72
|
+
const projectPath = this.projectPathResolver(session.project);
|
|
73
|
+
// Remove the worktree
|
|
74
|
+
const removed = await worktreeManager.remove(projectPath, session.worktree_path);
|
|
75
|
+
if (removed) {
|
|
76
|
+
// Clear worktree info in DB
|
|
77
|
+
clearSessionWorktree(session.name);
|
|
78
|
+
result.cleanedSessions.push(session.name);
|
|
79
|
+
console.log(`[Cleanup] Cleaned up worktree for session ${session.name}`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
84
|
+
result.errors.push({ session: session.name, error: errorMsg });
|
|
85
|
+
console.error(`[Cleanup] Failed to clean up session ${session.name}:`, error);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
if (result.cleanedSessions.length > 0) {
|
|
89
|
+
console.log(`[Cleanup] Cleaned up ${result.cleanedSessions.length} worktrees`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
console.error('[Cleanup] Error during cleanup:', error);
|
|
94
|
+
}
|
|
95
|
+
return result;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Check if cleanup job is running.
|
|
99
|
+
*/
|
|
100
|
+
isRunning() {
|
|
101
|
+
return this.intervalHandle !== null;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Update cleanup configuration.
|
|
105
|
+
*/
|
|
106
|
+
updateConfig(config) {
|
|
107
|
+
if (config.maxIdleMs !== undefined) {
|
|
108
|
+
this.config.maxIdleMs = config.maxIdleMs;
|
|
109
|
+
}
|
|
110
|
+
if (config.intervalMs !== undefined) {
|
|
111
|
+
this.config.intervalMs = config.intervalMs;
|
|
112
|
+
// Restart with new interval if running
|
|
113
|
+
if (this.isRunning()) {
|
|
114
|
+
this.stop();
|
|
115
|
+
this.start();
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
// Factory function to create cleanup service
|
|
121
|
+
// Needs to be initialized with project path resolver
|
|
122
|
+
let cleanupService = null;
|
|
123
|
+
export function initCleanupService(projectPathResolver, config) {
|
|
124
|
+
cleanupService = new CleanupService(projectPathResolver, config);
|
|
125
|
+
return cleanupService;
|
|
126
|
+
}
|
|
127
|
+
export function getCleanupService() {
|
|
128
|
+
return cleanupService;
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=cleanup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cleanup.js","sourceRoot":"","sources":["../../src/services/cleanup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ExecutionManager - Manages parallel session execution limits.
|
|
3
|
+
* Limits the number of concurrent Claude sessions to prevent resource exhaustion.
|
|
4
|
+
*/
|
|
5
|
+
export interface SessionInfo {
|
|
6
|
+
project: string;
|
|
7
|
+
worktreePath: string | null;
|
|
8
|
+
startedAt: number;
|
|
9
|
+
}
|
|
10
|
+
export interface CapacityInfo {
|
|
11
|
+
max: number;
|
|
12
|
+
running: number;
|
|
13
|
+
available: number;
|
|
14
|
+
}
|
|
15
|
+
export declare class ExecutionManager {
|
|
16
|
+
private maxParallel;
|
|
17
|
+
private running;
|
|
18
|
+
constructor(maxParallel?: number);
|
|
19
|
+
/**
|
|
20
|
+
* Check if a new session can be started.
|
|
21
|
+
*/
|
|
22
|
+
canStart(): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Register a running session.
|
|
25
|
+
*/
|
|
26
|
+
register(sessionName: string, project: string, worktreePath: string | null): void;
|
|
27
|
+
/**
|
|
28
|
+
* Unregister a session when it stops.
|
|
29
|
+
*/
|
|
30
|
+
unregister(sessionName: string): void;
|
|
31
|
+
/**
|
|
32
|
+
* Get current capacity information.
|
|
33
|
+
*/
|
|
34
|
+
getCapacity(): CapacityInfo;
|
|
35
|
+
/**
|
|
36
|
+
* Get information about a specific running session.
|
|
37
|
+
*/
|
|
38
|
+
getSession(sessionName: string): SessionInfo | undefined;
|
|
39
|
+
/**
|
|
40
|
+
* Get all running sessions.
|
|
41
|
+
*/
|
|
42
|
+
getRunningSessions(): Map<string, SessionInfo>;
|
|
43
|
+
/**
|
|
44
|
+
* Check if a specific session is running.
|
|
45
|
+
*/
|
|
46
|
+
isRunning(sessionName: string): boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Update the maximum parallel sessions limit.
|
|
49
|
+
*/
|
|
50
|
+
setMaxParallel(max: number): void;
|
|
51
|
+
}
|
|
52
|
+
export declare const executionManager: ExecutionManager;
|
|
53
|
+
//# sourceMappingURL=execution.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution.d.ts","sourceRoot":"","sources":["../../src/services/execution.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,OAAO,CAA2B;gBAE9B,WAAW,GAAE,MAAU;IAKnC;;OAEG;IACH,QAAQ,IAAI,OAAO;IAInB;;OAEG;IACH,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAWjF;;OAEG;IACH,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAQrC;;OAEG;IACH,WAAW,IAAI,YAAY;IAQ3B;;OAEG;IACH,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;IAIxD;;OAEG;IACH,kBAAkB,IAAI,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC;IAI9C;;OAEG;IACH,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO;IAIvC;;OAEG;IACH,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;CAIlC;AAGD,eAAO,MAAM,gBAAgB,kBAA0B,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ExecutionManager - Manages parallel session execution limits.
|
|
3
|
+
* Limits the number of concurrent Claude sessions to prevent resource exhaustion.
|
|
4
|
+
*/
|
|
5
|
+
export class ExecutionManager {
|
|
6
|
+
maxParallel;
|
|
7
|
+
running;
|
|
8
|
+
constructor(maxParallel = 3) {
|
|
9
|
+
this.maxParallel = maxParallel;
|
|
10
|
+
this.running = new Map();
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Check if a new session can be started.
|
|
14
|
+
*/
|
|
15
|
+
canStart() {
|
|
16
|
+
return this.running.size < this.maxParallel;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Register a running session.
|
|
20
|
+
*/
|
|
21
|
+
register(sessionName, project, worktreePath) {
|
|
22
|
+
this.running.set(sessionName, {
|
|
23
|
+
project,
|
|
24
|
+
worktreePath,
|
|
25
|
+
startedAt: Date.now(),
|
|
26
|
+
});
|
|
27
|
+
console.log(`[Execution] Registered session ${sessionName} (${this.running.size}/${this.maxParallel})`);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Unregister a session when it stops.
|
|
31
|
+
*/
|
|
32
|
+
unregister(sessionName) {
|
|
33
|
+
if (this.running.delete(sessionName)) {
|
|
34
|
+
console.log(`[Execution] Unregistered session ${sessionName} (${this.running.size}/${this.maxParallel})`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Get current capacity information.
|
|
39
|
+
*/
|
|
40
|
+
getCapacity() {
|
|
41
|
+
return {
|
|
42
|
+
max: this.maxParallel,
|
|
43
|
+
running: this.running.size,
|
|
44
|
+
available: this.maxParallel - this.running.size,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Get information about a specific running session.
|
|
49
|
+
*/
|
|
50
|
+
getSession(sessionName) {
|
|
51
|
+
return this.running.get(sessionName);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Get all running sessions.
|
|
55
|
+
*/
|
|
56
|
+
getRunningSessions() {
|
|
57
|
+
return new Map(this.running);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Check if a specific session is running.
|
|
61
|
+
*/
|
|
62
|
+
isRunning(sessionName) {
|
|
63
|
+
return this.running.has(sessionName);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Update the maximum parallel sessions limit.
|
|
67
|
+
*/
|
|
68
|
+
setMaxParallel(max) {
|
|
69
|
+
this.maxParallel = max;
|
|
70
|
+
console.log(`[Execution] Max parallel sessions set to ${max}`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// Singleton instance with default max of 3
|
|
74
|
+
export const executionManager = new ExecutionManager(3);
|
|
75
|
+
//# sourceMappingURL=execution.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution.js","sourceRoot":"","sources":["../../src/services/execution.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAcH,MAAM,OAAO,gBAAgB;IACnB,WAAW,CAAS;IACpB,OAAO,CAA2B;IAE1C,YAAY,cAAsB,CAAC;QACjC,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,OAAO,GAAG,IAAI,GAAG,EAAE,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,QAAQ;QACN,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC;IAC9C,CAAC;IAED;;OAEG;IACH,QAAQ,CAAC,WAAmB,EAAE,OAAe,EAAE,YAA2B;QACxE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE;YAC5B,OAAO;YACP,YAAY;YACZ,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACtB,CAAC,CAAC;QACH,OAAO,CAAC,GAAG,CACT,kCAAkC,WAAW,KAAK,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,WAAW,GAAG,CAC3F,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,UAAU,CAAC,WAAmB;QAC5B,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC;YACrC,OAAO,CAAC,GAAG,CACT,oCAAoC,WAAW,KAAK,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,WAAW,GAAG,CAC7F,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;OAEG;IACH,WAAW;QACT,OAAO;YACL,GAAG,EAAE,IAAI,CAAC,WAAW;YACrB,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI;YAC1B,SAAS,EAAE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI;SAChD,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,UAAU,CAAC,WAAmB;QAC5B,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IACvC,CAAC;IAED;;OAEG;IACH,kBAAkB;QAChB,OAAO,IAAI,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IAED;;OAEG;IACH,SAAS,CAAC,WAAmB;QAC3B,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IACvC,CAAC;IAED;;OAEG;IACH,cAAc,CAAC,GAAW;QACxB,IAAI,CAAC,WAAW,GAAG,GAAG,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,4CAA4C,GAAG,EAAE,CAAC,CAAC;IACjE,CAAC;CACF;AAED,2CAA2C;AAC3C,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,gBAAgB,CAAC,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { WorktreeManager, worktreeManager } from './worktree.js';
|
|
2
|
+
export type { WorktreeInfo } from './worktree.js';
|
|
3
|
+
export { ExecutionManager, executionManager } from './execution.js';
|
|
4
|
+
export type { SessionInfo, CapacityInfo } from './execution.js';
|
|
5
|
+
export { CleanupService, initCleanupService, getCleanupService } from './cleanup.js';
|
|
6
|
+
export type { CleanupConfig, CleanupResult } from './cleanup.js';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACjE,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACpE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEhE,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACrF,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// Services index - centralized exports for all services
|
|
2
|
+
export { WorktreeManager, worktreeManager } from './worktree.js';
|
|
3
|
+
export { ExecutionManager, executionManager } from './execution.js';
|
|
4
|
+
export { CleanupService, initCleanupService, getCleanupService } from './cleanup.js';
|
|
5
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA,wDAAwD;AAExD,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGjE,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAGpE,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export interface WorktreeInfo {
|
|
2
|
+
worktreePath: string;
|
|
3
|
+
branch: string;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Manages Git worktrees for session isolation.
|
|
7
|
+
* Each session gets its own worktree with a dedicated branch.
|
|
8
|
+
*/
|
|
9
|
+
export declare class WorktreeManager {
|
|
10
|
+
private basePath;
|
|
11
|
+
constructor(basePath?: string);
|
|
12
|
+
/**
|
|
13
|
+
* Create a new worktree for a session.
|
|
14
|
+
* If branchName is not provided, creates a branch named `session/<sessionName>`.
|
|
15
|
+
*/
|
|
16
|
+
create(projectPath: string, sessionName: string, branchName?: string): Promise<WorktreeInfo>;
|
|
17
|
+
/**
|
|
18
|
+
* Remove a worktree.
|
|
19
|
+
* Uses --force to remove even if there are uncommitted changes.
|
|
20
|
+
*/
|
|
21
|
+
remove(projectPath: string, worktreePath: string): Promise<boolean>;
|
|
22
|
+
/**
|
|
23
|
+
* List all worktrees for a project.
|
|
24
|
+
*/
|
|
25
|
+
list(projectPath: string): Promise<string[]>;
|
|
26
|
+
/**
|
|
27
|
+
* Check if a worktree exists for a session.
|
|
28
|
+
*/
|
|
29
|
+
exists(sessionName: string): Promise<boolean>;
|
|
30
|
+
/**
|
|
31
|
+
* Get the worktree path for a session.
|
|
32
|
+
*/
|
|
33
|
+
getPath(sessionName: string): string;
|
|
34
|
+
/**
|
|
35
|
+
* Copy Claude configuration files (CLAUDE.md, .claude/) from source to destination.
|
|
36
|
+
* These files contain project-specific context that Claude needs.
|
|
37
|
+
*/
|
|
38
|
+
private copyClaudeConfig;
|
|
39
|
+
}
|
|
40
|
+
export declare const worktreeManager: WorktreeManager;
|
|
41
|
+
//# sourceMappingURL=worktree.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worktree.d.ts","sourceRoot":"","sources":["../../src/services/worktree.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAS;gBAEb,QAAQ,GAAE,MAAuB;IAI7C;;;OAGG;IACG,MAAM,CACV,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,YAAY,CAAC;IAwCxB;;;OAGG;IACG,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAsBzE;;OAEG;IACG,IAAI,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAmBlD;;OAEG;IACG,MAAM,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKnD;;OAEG;IACH,OAAO,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM;IAIpC;;;OAGG;YACW,gBAAgB;CAsB/B;AAGD,eAAO,MAAM,eAAe,iBAAwB,CAAC"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { execa } from 'execa';
|
|
2
|
+
import { existsSync } from 'fs';
|
|
3
|
+
import { mkdir, stat, copyFile, cp } from 'fs/promises';
|
|
4
|
+
import { join } from 'path';
|
|
5
|
+
const WORKTREES_BASE = '/tmp/247-workspaces';
|
|
6
|
+
/**
|
|
7
|
+
* Manages Git worktrees for session isolation.
|
|
8
|
+
* Each session gets its own worktree with a dedicated branch.
|
|
9
|
+
*/
|
|
10
|
+
export class WorktreeManager {
|
|
11
|
+
basePath;
|
|
12
|
+
constructor(basePath = WORKTREES_BASE) {
|
|
13
|
+
this.basePath = basePath;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Create a new worktree for a session.
|
|
17
|
+
* If branchName is not provided, creates a branch named `session/<sessionName>`.
|
|
18
|
+
*/
|
|
19
|
+
async create(projectPath, sessionName, branchName) {
|
|
20
|
+
const branch = branchName || `session/${sessionName}`;
|
|
21
|
+
const worktreePath = join(this.basePath, sessionName);
|
|
22
|
+
// Ensure base directory exists
|
|
23
|
+
await mkdir(this.basePath, { recursive: true });
|
|
24
|
+
// Check if worktree already exists
|
|
25
|
+
if (existsSync(worktreePath)) {
|
|
26
|
+
console.log(`[Worktree] Worktree already exists at ${worktreePath}`);
|
|
27
|
+
return { worktreePath, branch };
|
|
28
|
+
}
|
|
29
|
+
// Check if branch already exists
|
|
30
|
+
const { exitCode } = await execa('git', ['rev-parse', '--verify', branch], {
|
|
31
|
+
cwd: projectPath,
|
|
32
|
+
reject: false,
|
|
33
|
+
});
|
|
34
|
+
if (exitCode !== 0) {
|
|
35
|
+
// Branch doesn't exist - create new branch with worktree
|
|
36
|
+
console.log(`[Worktree] Creating new worktree with branch ${branch}`);
|
|
37
|
+
await execa('git', ['worktree', 'add', '-b', branch, worktreePath], {
|
|
38
|
+
cwd: projectPath,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
// Branch exists - create worktree on existing branch
|
|
43
|
+
console.log(`[Worktree] Creating worktree on existing branch ${branch}`);
|
|
44
|
+
await execa('git', ['worktree', 'add', worktreePath, branch], {
|
|
45
|
+
cwd: projectPath,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
// Copy Claude configuration files
|
|
49
|
+
await this.copyClaudeConfig(projectPath, worktreePath);
|
|
50
|
+
console.log(`[Worktree] Created worktree at ${worktreePath} on branch ${branch}`);
|
|
51
|
+
return { worktreePath, branch };
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Remove a worktree.
|
|
55
|
+
* Uses --force to remove even if there are uncommitted changes.
|
|
56
|
+
*/
|
|
57
|
+
async remove(projectPath, worktreePath) {
|
|
58
|
+
try {
|
|
59
|
+
// First try to prune any stale worktrees
|
|
60
|
+
await execa('git', ['worktree', 'prune'], {
|
|
61
|
+
cwd: projectPath,
|
|
62
|
+
reject: false,
|
|
63
|
+
});
|
|
64
|
+
// Then remove the specific worktree
|
|
65
|
+
await execa('git', ['worktree', 'remove', worktreePath, '--force'], {
|
|
66
|
+
cwd: projectPath,
|
|
67
|
+
reject: false,
|
|
68
|
+
});
|
|
69
|
+
console.log(`[Worktree] Removed worktree at ${worktreePath}`);
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
console.error(`[Worktree] Failed to remove worktree at ${worktreePath}:`, error);
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* List all worktrees for a project.
|
|
79
|
+
*/
|
|
80
|
+
async list(projectPath) {
|
|
81
|
+
try {
|
|
82
|
+
const { stdout } = await execa('git', ['worktree', 'list', '--porcelain'], {
|
|
83
|
+
cwd: projectPath,
|
|
84
|
+
});
|
|
85
|
+
const worktrees = [];
|
|
86
|
+
for (const line of stdout.split('\n')) {
|
|
87
|
+
if (line.startsWith('worktree ')) {
|
|
88
|
+
worktrees.push(line.replace('worktree ', ''));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return worktrees;
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
console.error(`[Worktree] Failed to list worktrees:`, error);
|
|
95
|
+
return [];
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Check if a worktree exists for a session.
|
|
100
|
+
*/
|
|
101
|
+
async exists(sessionName) {
|
|
102
|
+
const worktreePath = join(this.basePath, sessionName);
|
|
103
|
+
return existsSync(worktreePath);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Get the worktree path for a session.
|
|
107
|
+
*/
|
|
108
|
+
getPath(sessionName) {
|
|
109
|
+
return join(this.basePath, sessionName);
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Copy Claude configuration files (CLAUDE.md, .claude/) from source to destination.
|
|
113
|
+
* These files contain project-specific context that Claude needs.
|
|
114
|
+
*/
|
|
115
|
+
async copyClaudeConfig(src, dest) {
|
|
116
|
+
const filesToCopy = ['CLAUDE.md', '.claude'];
|
|
117
|
+
for (const file of filesToCopy) {
|
|
118
|
+
const srcPath = join(src, file);
|
|
119
|
+
const destPath = join(dest, file);
|
|
120
|
+
try {
|
|
121
|
+
const fileStat = await stat(srcPath);
|
|
122
|
+
if (fileStat.isDirectory()) {
|
|
123
|
+
await cp(srcPath, destPath, { recursive: true });
|
|
124
|
+
console.log(`[Worktree] Copied directory ${file}`);
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
await copyFile(srcPath, destPath);
|
|
128
|
+
console.log(`[Worktree] Copied file ${file}`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
// File doesn't exist, skip silently
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// Singleton instance
|
|
138
|
+
export const worktreeManager = new WorktreeManager();
|
|
139
|
+
//# sourceMappingURL=worktree.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worktree.js","sourceRoot":"","sources":["../../src/services/worktree.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup-statusline.d.ts","sourceRoot":"","sources":["../src/setup-statusline.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"setup-statusline.d.ts","sourceRoot":"","sources":["../src/setup-statusline.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAeH;;;GAGG;AACH,wBAAgB,0BAA0B,IAAI,IAAI,CAUjD"}
|
|
@@ -9,6 +9,7 @@ const CLAUDE_SETTINGS_PATH = join(homedir(), '.claude', 'settings.json');
|
|
|
9
9
|
const STATUSLINE_DIR = join(homedir(), '.247');
|
|
10
10
|
const STATUSLINE_SCRIPT_PATH = join(STATUSLINE_DIR, 'statusline.sh');
|
|
11
11
|
const NOTIFICATION_SCRIPT_PATH = join(STATUSLINE_DIR, 'notification.sh');
|
|
12
|
+
const STOP_SCRIPT_PATH = join(STATUSLINE_DIR, 'stop.sh');
|
|
12
13
|
// Pattern to detect old 247 hooks that need cleanup
|
|
13
14
|
const OLD_HOOK_PATTERN = /notify-status\.sh|packages\/hooks/;
|
|
14
15
|
/**
|
|
@@ -19,6 +20,7 @@ export function ensureStatusLineConfigured() {
|
|
|
19
20
|
try {
|
|
20
21
|
ensureStatusLineScript();
|
|
21
22
|
ensureNotificationScript();
|
|
23
|
+
ensureStopScript();
|
|
22
24
|
ensureClaudeSettings();
|
|
23
25
|
console.log('[Setup] StatusLine and hooks configured successfully');
|
|
24
26
|
}
|
|
@@ -85,6 +87,36 @@ exit 0
|
|
|
85
87
|
chmodSync(NOTIFICATION_SCRIPT_PATH, 0o755);
|
|
86
88
|
console.log(`[Setup] Created notification script at ${NOTIFICATION_SCRIPT_PATH}`);
|
|
87
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* Create the stop.sh script that forwards Claude Code stop notifications to the agent.
|
|
92
|
+
* This script is called by the Stop hook when Claude finishes responding.
|
|
93
|
+
*/
|
|
94
|
+
function ensureStopScript() {
|
|
95
|
+
if (!existsSync(STATUSLINE_DIR)) {
|
|
96
|
+
mkdirSync(STATUSLINE_DIR, { recursive: true });
|
|
97
|
+
}
|
|
98
|
+
const script = `#!/bin/bash
|
|
99
|
+
# 247 Stop Hook - forwards Claude Code stop events to agent
|
|
100
|
+
# Auto-generated by 247 agent - do not edit manually
|
|
101
|
+
|
|
102
|
+
INPUT=$(cat)
|
|
103
|
+
TMUX_SESSION="\${CLAUDE_TMUX_SESSION:-}"
|
|
104
|
+
|
|
105
|
+
# Only forward if we're in a tmux session managed by 247
|
|
106
|
+
[ -z "$TMUX_SESSION" ] && exit 0
|
|
107
|
+
|
|
108
|
+
# Forward JSON to agent (add tmux_session field)
|
|
109
|
+
echo "$INPUT" | jq --arg ts "$TMUX_SESSION" '. + {tmux_session: $ts}' | \\
|
|
110
|
+
curl -s -X POST "http://localhost:4678/api/stop" \\
|
|
111
|
+
-H "Content-Type: application/json" \\
|
|
112
|
+
-d @- > /dev/null 2>&1 &
|
|
113
|
+
|
|
114
|
+
exit 0
|
|
115
|
+
`;
|
|
116
|
+
writeFileSync(STOP_SCRIPT_PATH, script);
|
|
117
|
+
chmodSync(STOP_SCRIPT_PATH, 0o755);
|
|
118
|
+
console.log(`[Setup] Created stop script at ${STOP_SCRIPT_PATH}`);
|
|
119
|
+
}
|
|
88
120
|
/**
|
|
89
121
|
* Remove old 247 hooks from settings.json.
|
|
90
122
|
* These hooks used the deprecated notify-status.sh script.
|
|
@@ -101,7 +133,8 @@ function cleanupOldHooks(settings) {
|
|
|
101
133
|
return true;
|
|
102
134
|
}
|
|
103
135
|
/**
|
|
104
|
-
* Configure Claude settings.json to use our statusLine script and
|
|
136
|
+
* Configure Claude settings.json to use our statusLine script and hooks.
|
|
137
|
+
* Configures: statusLine, Notification hook, Stop hook
|
|
105
138
|
* Also cleans up deprecated hooks if found.
|
|
106
139
|
*/
|
|
107
140
|
function ensureClaudeSettings() {
|
|
@@ -124,6 +157,7 @@ function ensureClaudeSettings() {
|
|
|
124
157
|
const hooksRemoved = cleanupOldHooks(settings);
|
|
125
158
|
const expectedStatusLineCommand = `bash ${STATUSLINE_SCRIPT_PATH}`;
|
|
126
159
|
const expectedNotificationCommand = `bash ${NOTIFICATION_SCRIPT_PATH}`;
|
|
160
|
+
const expectedStopCommand = `bash ${STOP_SCRIPT_PATH}`;
|
|
127
161
|
// Check if statusLine is already configured correctly
|
|
128
162
|
const currentStatusLine = settings.statusLine;
|
|
129
163
|
const statusLineConfigured = currentStatusLine?.command === expectedStatusLineCommand;
|
|
@@ -131,7 +165,10 @@ function ensureClaudeSettings() {
|
|
|
131
165
|
const currentHooks = settings.hooks;
|
|
132
166
|
const notificationHooks = currentHooks?.Notification;
|
|
133
167
|
const notificationConfigured = notificationHooks?.some((h) => h.hooks?.some((hook) => hook.command === expectedNotificationCommand));
|
|
134
|
-
if
|
|
168
|
+
// Check if Stop hook is already configured correctly
|
|
169
|
+
const stopHooks = currentHooks?.Stop;
|
|
170
|
+
const stopConfigured = stopHooks?.some((h) => h.hooks?.some((hook) => hook.command === expectedStopCommand));
|
|
171
|
+
if (statusLineConfigured && notificationConfigured && stopConfigured && !hooksRemoved) {
|
|
135
172
|
console.log('[Setup] StatusLine and hooks already configured');
|
|
136
173
|
return;
|
|
137
174
|
}
|
|
@@ -146,7 +183,7 @@ function ensureClaudeSettings() {
|
|
|
146
183
|
command: expectedStatusLineCommand,
|
|
147
184
|
};
|
|
148
185
|
}
|
|
149
|
-
// Configure
|
|
186
|
+
// Configure hooks (merge with existing hooks)
|
|
150
187
|
const hooks = (settings.hooks || {});
|
|
151
188
|
// Only add our Notification hook if not already configured
|
|
152
189
|
if (!notificationConfigured) {
|
|
@@ -167,9 +204,30 @@ function ensureClaudeSettings() {
|
|
|
167
204
|
],
|
|
168
205
|
},
|
|
169
206
|
];
|
|
170
|
-
settings.hooks = hooks;
|
|
171
207
|
console.log('[Setup] Configured Notification hook');
|
|
172
208
|
}
|
|
209
|
+
// Only add our Stop hook if not already configured
|
|
210
|
+
if (!stopConfigured) {
|
|
211
|
+
// Get existing Stop hooks (user-defined ones we should preserve)
|
|
212
|
+
const existingStopHooks = (hooks.Stop || []);
|
|
213
|
+
// Filter out any old 247 stop hooks that might exist
|
|
214
|
+
const userStopHooks = existingStopHooks.filter((h) => !h.hooks?.some((hook) => hook.command?.includes('.247/stop.sh')));
|
|
215
|
+
// Add our Stop hook
|
|
216
|
+
hooks.Stop = [
|
|
217
|
+
...userStopHooks,
|
|
218
|
+
{
|
|
219
|
+
matcher: '*',
|
|
220
|
+
hooks: [
|
|
221
|
+
{
|
|
222
|
+
type: 'command',
|
|
223
|
+
command: expectedStopCommand,
|
|
224
|
+
},
|
|
225
|
+
],
|
|
226
|
+
},
|
|
227
|
+
];
|
|
228
|
+
console.log('[Setup] Configured Stop hook');
|
|
229
|
+
}
|
|
230
|
+
settings.hooks = hooks;
|
|
173
231
|
writeFileSync(CLAUDE_SETTINGS_PATH, JSON.stringify(settings, null, 2));
|
|
174
232
|
console.log(`[Setup] Configured Claude settings in ${CLAUDE_SETTINGS_PATH}`);
|
|
175
233
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup-statusline.js","sourceRoot":"","sources":["../src/setup-statusline.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AACnF,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,MAAM,oBAAoB,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,eAAe,CAAC,CAAC;AACzE,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,MAAM,CAAC,CAAC;AAC/C,MAAM,sBAAsB,GAAG,IAAI,CAAC,cAAc,EAAE,eAAe,CAAC,CAAC;AACrE,MAAM,wBAAwB,GAAG,IAAI,CAAC,cAAc,EAAE,iBAAiB,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"setup-statusline.js","sourceRoot":"","sources":["../src/setup-statusline.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"websocket-handlers.d.ts","sourceRoot":"","sources":["../src/websocket-handlers.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"websocket-handlers.d.ts","sourceRoot":"","sources":["../src/websocket-handlers.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AA+C/B;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG,GAAG,IAAI,CAkQtE;AA6KD;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,CAAC,EAAE,GAAG,GAAG,IAAI,CAiHrE"}
|