@k1e1n04/mav 0.1.24 → 0.1.25
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/README.md +15 -0
- package/bin/mav.ts +31 -0
- package/dist/bin/mav.js +27 -0
- package/dist/bin/mav.js.map +1 -1
- package/dist/package.json +1 -1
- package/dist/src/agent.d.ts +8 -1
- package/dist/src/agent.js +16 -2
- package/dist/src/agent.js.map +1 -1
- package/dist/src/hook-injector.d.ts +22 -0
- package/dist/src/hook-injector.js +101 -0
- package/dist/src/hook-injector.js.map +1 -0
- package/dist/src/index.js +43 -15
- package/dist/src/index.js.map +1 -1
- package/dist/src/ipc-server.d.ts +13 -0
- package/dist/src/ipc-server.js +58 -0
- package/dist/src/ipc-server.js.map +1 -0
- package/dist/src/session-manager.d.ts +2 -1
- package/dist/src/session-manager.js +2 -2
- package/dist/src/session-manager.js.map +1 -1
- package/dist/src/ui/app.d.ts +1 -1
- package/dist/src/ui/app.js +2 -2
- package/dist/src/ui/app.js.map +1 -1
- package/dist/src/ui/overview.d.ts +2 -1
- package/dist/src/ui/overview.js +20 -3
- package/dist/src/ui/overview.js.map +1 -1
- package/package.json +1 -1
- package/src/agent.ts +22 -2
- package/src/hook-injector.ts +131 -0
- package/src/index.ts +49 -15
- package/src/ipc-server.ts +72 -0
- package/src/session-manager.ts +3 -2
- package/src/ui/app.ts +2 -1
- package/src/ui/overview.ts +21 -2
package/README.md
CHANGED
|
@@ -114,6 +114,21 @@ agents:
|
|
|
114
114
|
| `opencode` | `opencode` |
|
|
115
115
|
| `antigravity-cli` | `agy` |
|
|
116
116
|
|
|
117
|
+
## CWD Tracking
|
|
118
|
+
|
|
119
|
+
mav tracks each agent's working directory. When an agent changes directory (e.g., via `git worktree`), the Overview panel reflects the new path.
|
|
120
|
+
|
|
121
|
+
| Agent | CWD Tracking | Hook Auto-injection |
|
|
122
|
+
|---|---|---|
|
|
123
|
+
| `claude-code` | IPC + PostToolUse hook | ✅ Auto-injected via `--settings` |
|
|
124
|
+
| `gemini-cli` | IPC + AfterTool hook | ✅ Auto-injected via `.gemini/settings.local.json` |
|
|
125
|
+
| `codex` | IPC + PostToolUse hook | ✅ Auto-injected via `--profile-v2` |
|
|
126
|
+
| `copilot` | lsof polling only | ❌ Not supported (no hook API) |
|
|
127
|
+
| Other | lsof polling only | ❌ Not supported |
|
|
128
|
+
|
|
129
|
+
> **Copilot** and unlisted agents use process polling to track the working directory.
|
|
130
|
+
> Directory changes made in child processes (e.g., git worktrees) may not be detected.
|
|
131
|
+
|
|
117
132
|
## Keybindings
|
|
118
133
|
|
|
119
134
|
| Key | Scope | Action |
|
package/bin/mav.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { Command } from 'commander'
|
|
3
3
|
import { readFileSync } from 'node:fs'
|
|
4
|
+
import { connect } from 'node:net'
|
|
4
5
|
import { join, dirname } from 'node:path'
|
|
5
6
|
import { fileURLToPath } from 'node:url'
|
|
6
7
|
import { start } from '../src/index.js'
|
|
@@ -28,4 +29,34 @@ program
|
|
|
28
29
|
})
|
|
29
30
|
})
|
|
30
31
|
|
|
32
|
+
const report = program.command('report')
|
|
33
|
+
.description('Report runtime state back to the mav TUI process')
|
|
34
|
+
|
|
35
|
+
report
|
|
36
|
+
.command('cwd <path>')
|
|
37
|
+
.description('Report current working directory change to mav')
|
|
38
|
+
.action((path: string) => {
|
|
39
|
+
const socketPath = process.env.MAV_SOCKET
|
|
40
|
+
const sessionId = process.env.MAV_SESSION_ID
|
|
41
|
+
|
|
42
|
+
if (!socketPath || !sessionId) {
|
|
43
|
+
// Called outside mav — silently exit
|
|
44
|
+
process.exit(0)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const msg = JSON.stringify({ type: 'cwd', sessionId, path }) + '\n'
|
|
48
|
+
const client = connect(socketPath, () => {
|
|
49
|
+
client.write(msg, () => {
|
|
50
|
+
client.destroy()
|
|
51
|
+
process.exit(0)
|
|
52
|
+
})
|
|
53
|
+
})
|
|
54
|
+
client.on('error', () => {
|
|
55
|
+
// Connection failed (mav already exited, etc.) — silently exit
|
|
56
|
+
process.exit(0)
|
|
57
|
+
})
|
|
58
|
+
// 3s timeout in case connection hangs
|
|
59
|
+
setTimeout(() => process.exit(0), 3000).unref()
|
|
60
|
+
})
|
|
61
|
+
|
|
31
62
|
program.parse()
|
package/dist/bin/mav.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { Command } from 'commander';
|
|
3
3
|
import { readFileSync } from 'node:fs';
|
|
4
|
+
import { connect } from 'node:net';
|
|
4
5
|
import { join, dirname } from 'node:path';
|
|
5
6
|
import { fileURLToPath } from 'node:url';
|
|
6
7
|
import { start } from '../src/index.js';
|
|
@@ -20,5 +21,31 @@ program
|
|
|
20
21
|
configPath: options.config,
|
|
21
22
|
});
|
|
22
23
|
});
|
|
24
|
+
const report = program.command('report')
|
|
25
|
+
.description('Report runtime state back to the mav TUI process');
|
|
26
|
+
report
|
|
27
|
+
.command('cwd <path>')
|
|
28
|
+
.description('Report current working directory change to mav')
|
|
29
|
+
.action((path) => {
|
|
30
|
+
const socketPath = process.env.MAV_SOCKET;
|
|
31
|
+
const sessionId = process.env.MAV_SESSION_ID;
|
|
32
|
+
if (!socketPath || !sessionId) {
|
|
33
|
+
// Called outside mav — silently exit
|
|
34
|
+
process.exit(0);
|
|
35
|
+
}
|
|
36
|
+
const msg = JSON.stringify({ type: 'cwd', sessionId, path }) + '\n';
|
|
37
|
+
const client = connect(socketPath, () => {
|
|
38
|
+
client.write(msg, () => {
|
|
39
|
+
client.destroy();
|
|
40
|
+
process.exit(0);
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
client.on('error', () => {
|
|
44
|
+
// Connection failed (mav already exited, etc.) — silently exit
|
|
45
|
+
process.exit(0);
|
|
46
|
+
});
|
|
47
|
+
// 3s timeout in case connection hangs
|
|
48
|
+
setTimeout(() => process.exit(0), 3000).unref();
|
|
49
|
+
});
|
|
23
50
|
program.parse();
|
|
24
51
|
//# sourceMappingURL=mav.js.map
|
package/dist/bin/mav.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mav.js","sourceRoot":"","sources":["../../bin/mav.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AAEvC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AACjD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;AACrC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CACpB,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CACtC,CAAA;AAExB,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAA;AAE7B,OAAO;KACJ,IAAI,CAAC,KAAK,CAAC;KACX,WAAW,CACV,oEAAoE,CACrE;KACA,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;KACpB,MAAM,CAAC,gBAAgB,EAAE,qCAAqC,CAAC;KAC/D,MAAM,CAAC,iBAAiB,EAAE,qBAAqB,CAAC;KAChD,MAAM,CAAC,CAAC,OAA4C,EAAE,EAAE;IACvD,KAAK,CAAC;QACJ,SAAS,EAAE,OAAO,CAAC,KAAK;QACxB,UAAU,EAAE,OAAO,CAAC,MAAM;KAC3B,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEJ,OAAO,CAAC,KAAK,EAAE,CAAA"}
|
|
1
|
+
{"version":3,"file":"mav.js","sourceRoot":"","sources":["../../bin/mav.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAA;AAClC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AAEvC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AACjD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;AACrC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CACpB,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CACtC,CAAA;AAExB,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAA;AAE7B,OAAO;KACJ,IAAI,CAAC,KAAK,CAAC;KACX,WAAW,CACV,oEAAoE,CACrE;KACA,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;KACpB,MAAM,CAAC,gBAAgB,EAAE,qCAAqC,CAAC;KAC/D,MAAM,CAAC,iBAAiB,EAAE,qBAAqB,CAAC;KAChD,MAAM,CAAC,CAAC,OAA4C,EAAE,EAAE;IACvD,KAAK,CAAC;QACJ,SAAS,EAAE,OAAO,CAAC,KAAK;QACxB,UAAU,EAAE,OAAO,CAAC,MAAM;KAC3B,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEJ,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC;KACrC,WAAW,CAAC,kDAAkD,CAAC,CAAA;AAElE,MAAM;KACH,OAAO,CAAC,YAAY,CAAC;KACrB,WAAW,CAAC,gDAAgD,CAAC;KAC7D,MAAM,CAAC,CAAC,IAAY,EAAE,EAAE;IACvB,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAA;IACzC,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAA;IAE5C,IAAI,CAAC,UAAU,IAAI,CAAC,SAAS,EAAE,CAAC;QAC9B,qCAAqC;QACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI,CAAA;IACnE,MAAM,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,GAAG,EAAE;QACtC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE;YACrB,MAAM,CAAC,OAAO,EAAE,CAAA;YAChB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IACF,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;QACtB,+DAA+D;QAC/D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC,CAAC,CAAA;IACF,sCAAsC;IACtC,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,KAAK,EAAE,CAAA;AACjD,CAAC,CAAC,CAAA;AAEJ,OAAO,CAAC,KAAK,EAAE,CAAA"}
|
package/dist/package.json
CHANGED
package/dist/src/agent.d.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { EventEmitter } from 'node:events';
|
|
2
2
|
import type { AgentConfig } from './config.js';
|
|
3
3
|
export type SessionStatus = 'running' | 'idle' | 'done' | 'error';
|
|
4
|
+
export interface IpcContext {
|
|
5
|
+
socketPath: string;
|
|
6
|
+
hookFiles: string[];
|
|
7
|
+
}
|
|
4
8
|
export declare class AgentSession extends EventEmitter {
|
|
5
9
|
private static readonly IDLE_TIMEOUT_MS;
|
|
6
10
|
private static readonly DISPLAY_NAME_MAX_LENGTH;
|
|
@@ -22,13 +26,16 @@ export declare class AgentSession extends EventEmitter {
|
|
|
22
26
|
private cwdPollTimer;
|
|
23
27
|
private displayNameLocked;
|
|
24
28
|
private initialInputBuffer;
|
|
25
|
-
|
|
29
|
+
private hookFiles;
|
|
30
|
+
constructor(config: AgentConfig, cols: number, rows: number, ipcContext?: IpcContext);
|
|
26
31
|
/** 保存されたdisplayNameを復元し、以降の入力で上書きされないようにロックする */
|
|
27
32
|
restoreDisplayName(name: string): void;
|
|
28
33
|
setDisplayName(name: string): void;
|
|
29
34
|
write(data: string): void;
|
|
30
35
|
kill(): void;
|
|
31
36
|
resize(cols: number, rows: number): void;
|
|
37
|
+
/** Update cwd via IPC notification */
|
|
38
|
+
notifyCwd(newCwd: string): void;
|
|
32
39
|
private appendLog;
|
|
33
40
|
private setStatus;
|
|
34
41
|
private scheduleIdleTimer;
|
package/dist/src/agent.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { EventEmitter } from 'node:events';
|
|
2
2
|
import * as pty from 'node-pty';
|
|
3
3
|
import { getProcessCwd } from './process-cwd.js';
|
|
4
|
+
import { cleanupHookFiles } from './hook-injector.js';
|
|
4
5
|
const counters = {};
|
|
5
6
|
export class AgentSession extends EventEmitter {
|
|
6
7
|
static IDLE_TIMEOUT_MS = 1500;
|
|
@@ -23,7 +24,8 @@ export class AgentSession extends EventEmitter {
|
|
|
23
24
|
cwdPollTimer = null;
|
|
24
25
|
displayNameLocked = false;
|
|
25
26
|
initialInputBuffer = '';
|
|
26
|
-
|
|
27
|
+
hookFiles = [];
|
|
28
|
+
constructor(config, cols, rows, ipcContext) {
|
|
27
29
|
super();
|
|
28
30
|
counters[config.type] = (counters[config.type] ?? 0) + 1;
|
|
29
31
|
this.id = `${config.type}#${counters[config.type]}`;
|
|
@@ -33,12 +35,18 @@ export class AgentSession extends EventEmitter {
|
|
|
33
35
|
this.displayName = `${config.type} ${counters[config.type]}`;
|
|
34
36
|
let proc;
|
|
35
37
|
try {
|
|
38
|
+
const env = { ...process.env };
|
|
39
|
+
if (ipcContext) {
|
|
40
|
+
env.MAV_SOCKET = ipcContext.socketPath;
|
|
41
|
+
env.MAV_SESSION_ID = this.id;
|
|
42
|
+
this.hookFiles = ipcContext.hookFiles;
|
|
43
|
+
}
|
|
36
44
|
proc = pty.spawn(config.cmd, config.args, {
|
|
37
45
|
name: 'xterm-256color',
|
|
38
46
|
cols,
|
|
39
47
|
rows,
|
|
40
48
|
cwd: this.cwd,
|
|
41
|
-
env
|
|
49
|
+
env,
|
|
42
50
|
});
|
|
43
51
|
}
|
|
44
52
|
catch (err) {
|
|
@@ -46,6 +54,7 @@ export class AgentSession extends EventEmitter {
|
|
|
46
54
|
this.exited = true;
|
|
47
55
|
this.status = 'error';
|
|
48
56
|
this.logBuffer.push(`Error: failed to spawn '${config.cmd}': ${msg}\r\n`);
|
|
57
|
+
cleanupHookFiles(this.hookFiles);
|
|
49
58
|
process.nextTick(() => this.emit('exit', 1));
|
|
50
59
|
return;
|
|
51
60
|
}
|
|
@@ -60,6 +69,7 @@ export class AgentSession extends EventEmitter {
|
|
|
60
69
|
this.ptyProcess.onExit(({ exitCode }) => {
|
|
61
70
|
this.clearIdleTimer();
|
|
62
71
|
this.clearCwdPollTimer();
|
|
72
|
+
cleanupHookFiles(this.hookFiles);
|
|
63
73
|
this.setStatus(exitCode === 0 ? 'done' : 'error');
|
|
64
74
|
this.exited = true;
|
|
65
75
|
this.ptyProcess = undefined;
|
|
@@ -100,6 +110,10 @@ export class AgentSession extends EventEmitter {
|
|
|
100
110
|
return;
|
|
101
111
|
this.ptyProcess?.resize(cols, rows);
|
|
102
112
|
}
|
|
113
|
+
/** Update cwd via IPC notification */
|
|
114
|
+
notifyCwd(newCwd) {
|
|
115
|
+
this.updateCwd(newCwd);
|
|
116
|
+
}
|
|
103
117
|
appendLog(chunk) {
|
|
104
118
|
this.logBuffer.push(chunk);
|
|
105
119
|
if (this.logBuffer.length > 500) {
|
package/dist/src/agent.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,KAAK,GAAG,MAAM,UAAU,CAAA;AAE/B,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/agent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface HookInjectionResult {
|
|
2
|
+
/** Injected startup args */
|
|
3
|
+
args: string[];
|
|
4
|
+
/** Temp file paths to delete on agent exit */
|
|
5
|
+
hookFiles: string[];
|
|
6
|
+
}
|
|
7
|
+
interface BuildHookArgsOptions {
|
|
8
|
+
/** Agent working directory (for gemini-cli) */
|
|
9
|
+
cwd?: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Injects a hook into the startup args for the given agent type and returns the result.
|
|
13
|
+
* Generated temp files are listed in hookFiles.
|
|
14
|
+
* Call cleanupHookFiles() after the agent exits.
|
|
15
|
+
*/
|
|
16
|
+
export declare function buildHookArgs(agentType: string, baseArgs: string[], hookCommand: string, options?: BuildHookArgsOptions): HookInjectionResult;
|
|
17
|
+
/**
|
|
18
|
+
* Deletes temp files generated by buildHookArgs.
|
|
19
|
+
* Call this when the agent process exits.
|
|
20
|
+
*/
|
|
21
|
+
export declare function cleanupHookFiles(hookFiles: string[]): void;
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { writeFileSync, readFileSync, existsSync, unlinkSync, mkdirSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
import { randomUUID } from 'node:crypto';
|
|
5
|
+
/**
|
|
6
|
+
* Injects a hook into the startup args for the given agent type and returns the result.
|
|
7
|
+
* Generated temp files are listed in hookFiles.
|
|
8
|
+
* Call cleanupHookFiles() after the agent exits.
|
|
9
|
+
*/
|
|
10
|
+
export function buildHookArgs(agentType, baseArgs, hookCommand, options = {}) {
|
|
11
|
+
switch (agentType) {
|
|
12
|
+
case 'claude-code':
|
|
13
|
+
return buildClaudeCodeHook(baseArgs, hookCommand);
|
|
14
|
+
case 'gemini-cli':
|
|
15
|
+
return buildGeminiHook(baseArgs, hookCommand, options.cwd);
|
|
16
|
+
case 'codex':
|
|
17
|
+
return buildCodexHook(baseArgs, hookCommand);
|
|
18
|
+
default:
|
|
19
|
+
return { args: baseArgs, hookFiles: [] };
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function buildClaudeCodeHook(baseArgs, hookCommand) {
|
|
23
|
+
const settings = {
|
|
24
|
+
hooks: {
|
|
25
|
+
PostToolUse: [
|
|
26
|
+
{
|
|
27
|
+
matcher: '',
|
|
28
|
+
hooks: [{ type: 'command', command: hookCommand }],
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
return {
|
|
34
|
+
args: [...baseArgs, '--settings', JSON.stringify(settings)],
|
|
35
|
+
hookFiles: [],
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
const MAV_MARKER = '_mavGenerated';
|
|
39
|
+
function buildGeminiHook(baseArgs, hookCommand, cwd) {
|
|
40
|
+
const projectDir = cwd ?? process.cwd();
|
|
41
|
+
const geminiDir = join(projectDir, '.gemini');
|
|
42
|
+
const settingsPath = join(geminiDir, 'settings.local.json');
|
|
43
|
+
// If the file exists and was NOT written by mav, skip to protect user's config
|
|
44
|
+
if (existsSync(settingsPath)) {
|
|
45
|
+
try {
|
|
46
|
+
const existing = JSON.parse(readFileSync(settingsPath, 'utf-8'));
|
|
47
|
+
if (!existing[MAV_MARKER]) {
|
|
48
|
+
// User-owned file — do not overwrite
|
|
49
|
+
return { args: baseArgs, hookFiles: [] };
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
// Unreadable/invalid JSON — treat as user-owned and skip
|
|
54
|
+
return { args: baseArgs, hookFiles: [] };
|
|
55
|
+
}
|
|
56
|
+
// File was written by mav (stale from crash) — overwrite below
|
|
57
|
+
}
|
|
58
|
+
const settings = {
|
|
59
|
+
[MAV_MARKER]: true,
|
|
60
|
+
hooks: {
|
|
61
|
+
AfterTool: [
|
|
62
|
+
{ matcher: '', hooks: [{ type: 'command', command: hookCommand }] },
|
|
63
|
+
],
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
mkdirSync(geminiDir, { recursive: true });
|
|
67
|
+
writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
|
|
68
|
+
return { args: baseArgs, hookFiles: [settingsPath] };
|
|
69
|
+
}
|
|
70
|
+
function buildCodexHook(baseArgs, hookCommand) {
|
|
71
|
+
const codexHome = process.env.CODEX_HOME ?? join(homedir(), '.codex');
|
|
72
|
+
mkdirSync(codexHome, { recursive: true });
|
|
73
|
+
const profileName = `mav-hook-${randomUUID()}`;
|
|
74
|
+
const tomlPath = join(codexHome, `${profileName}.config.toml`);
|
|
75
|
+
const tomlContent = [
|
|
76
|
+
'[hooks.post_tool_use]',
|
|
77
|
+
`cmd = ${JSON.stringify(hookCommand)}`,
|
|
78
|
+
'timeout_seconds = 10',
|
|
79
|
+
].join('\n');
|
|
80
|
+
writeFileSync(tomlPath, tomlContent);
|
|
81
|
+
return {
|
|
82
|
+
args: [...baseArgs, '--profile-v2', profileName],
|
|
83
|
+
hookFiles: [tomlPath],
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Deletes temp files generated by buildHookArgs.
|
|
88
|
+
* Call this when the agent process exits.
|
|
89
|
+
*/
|
|
90
|
+
export function cleanupHookFiles(hookFiles) {
|
|
91
|
+
for (const f of hookFiles) {
|
|
92
|
+
try {
|
|
93
|
+
if (existsSync(f))
|
|
94
|
+
unlinkSync(f);
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
// Ignore deletion failures (file may already be gone)
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=hook-injector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hook-injector.js","sourceRoot":"","sources":["../../src/hook-injector.ts"],"names":[],"mappings":"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"}
|
package/dist/src/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { homedir } from 'node:os';
|
|
1
|
+
import { homedir, tmpdir } from 'node:os';
|
|
2
2
|
import { join, dirname } from 'node:path';
|
|
3
3
|
import { loadConfig } from './config.js';
|
|
4
4
|
import { clearCurrentSessionState, saveCurrentSessionState } from './current-session.js';
|
|
@@ -6,6 +6,8 @@ import { loadState, saveState } from './state.js';
|
|
|
6
6
|
import { SessionManager } from './session-manager.js';
|
|
7
7
|
import { App } from './ui/app.js';
|
|
8
8
|
import { resolveSessionArgs } from './agent-launch.js';
|
|
9
|
+
import { createServer } from './ipc-server.js';
|
|
10
|
+
import { buildHookArgs } from './hook-injector.js';
|
|
9
11
|
export function start(options = {}) {
|
|
10
12
|
const configPath = options.configPath ?? join(homedir(), '.config', 'mav', 'config.yaml');
|
|
11
13
|
const statePath = join(dirname(configPath), 'state.json');
|
|
@@ -19,8 +21,15 @@ export function start(options = {}) {
|
|
|
19
21
|
process.exit(1);
|
|
20
22
|
}
|
|
21
23
|
const savedState = loadState(statePath);
|
|
24
|
+
// Start IPC server for cwd tracking (non-blocking)
|
|
25
|
+
const socketPath = join(tmpdir(), `mav-${process.pid}.sock`);
|
|
26
|
+
const ipcServer = createServer(socketPath);
|
|
27
|
+
ipcServer.listen().catch((err) => {
|
|
28
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
29
|
+
process.stderr.write(`mav: IPC server failed to start (${msg}), cwd tracking disabled\n`);
|
|
30
|
+
});
|
|
22
31
|
const manager = new SessionManager();
|
|
23
|
-
const app = new App(manager, statePath, undefined, config.agents);
|
|
32
|
+
const app = new App(manager, statePath, undefined, config.agents, socketPath);
|
|
24
33
|
const publishSelectedSession = () => {
|
|
25
34
|
const session = manager.selectedSession;
|
|
26
35
|
if (!session) {
|
|
@@ -42,11 +51,18 @@ export function start(options = {}) {
|
|
|
42
51
|
const savedSession = savedState?.sessions[predictedId];
|
|
43
52
|
const { args, newSessionId } = resolveSessionArgs(agentConfig.type, agentConfig.args, savedSession?.sessionId, savedSession != null);
|
|
44
53
|
const restoredCwd = savedSession?.cwd;
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
54
|
+
const hookCmd = `mav report cwd "$(pwd)"`;
|
|
55
|
+
let hookedArgs = args;
|
|
56
|
+
let hookFiles = [];
|
|
57
|
+
try {
|
|
58
|
+
const hookResult = buildHookArgs(agentConfig.type, args, hookCmd, { cwd: restoredCwd });
|
|
59
|
+
hookedArgs = hookResult.args;
|
|
60
|
+
hookFiles = hookResult.hookFiles;
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
// hook file I/O failed — start agent without hooks
|
|
64
|
+
}
|
|
65
|
+
const session = manager.addSession({ ...agentConfig, args: hookedArgs, ...(restoredCwd != null && { cwd: restoredCwd }) }, { socketPath, hookFiles });
|
|
50
66
|
session.baseArgs = agentConfig.args;
|
|
51
67
|
configSessionIds.add(session.id);
|
|
52
68
|
if (newSessionId != null) {
|
|
@@ -60,12 +76,18 @@ export function start(options = {}) {
|
|
|
60
76
|
continue;
|
|
61
77
|
const rc = savedSession.agentBase;
|
|
62
78
|
const { args, newSessionId } = resolveSessionArgs(rc.type, rc.args, savedSession.sessionId, true);
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
79
|
+
const hookCmd = `mav report cwd "$(pwd)"`;
|
|
80
|
+
let hookedArgs = args;
|
|
81
|
+
let hookFiles = [];
|
|
82
|
+
try {
|
|
83
|
+
const hookResult = buildHookArgs(rc.type, args, hookCmd, { cwd: savedSession.cwd });
|
|
84
|
+
hookedArgs = hookResult.args;
|
|
85
|
+
hookFiles = hookResult.hookFiles;
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
// hook file I/O failed — start agent without hooks
|
|
89
|
+
}
|
|
90
|
+
const session = manager.addSession({ type: rc.type, cmd: rc.cmd, args: hookedArgs, ...(savedSession.cwd != null && { cwd: savedSession.cwd }) }, { socketPath, hookFiles });
|
|
69
91
|
session.baseArgs = rc.args;
|
|
70
92
|
if (newSessionId != null) {
|
|
71
93
|
session.sessionId = newSessionId;
|
|
@@ -101,6 +123,12 @@ export function start(options = {}) {
|
|
|
101
123
|
publishSelectedSession();
|
|
102
124
|
});
|
|
103
125
|
publishSelectedSession();
|
|
126
|
+
ipcServer.onMessage((msg) => {
|
|
127
|
+
if (msg.type === 'cwd') {
|
|
128
|
+
const session = manager.sessions.find((s) => s.id === msg.sessionId);
|
|
129
|
+
session?.notifyCwd(msg.path);
|
|
130
|
+
}
|
|
131
|
+
});
|
|
104
132
|
// q/Ctrl+C 以外の終了(ウィンドウ閉じ等)でも state を保存する
|
|
105
133
|
const saveOnExit = () => {
|
|
106
134
|
try {
|
|
@@ -108,8 +136,8 @@ export function start(options = {}) {
|
|
|
108
136
|
}
|
|
109
137
|
catch { /* ignore */ }
|
|
110
138
|
};
|
|
111
|
-
process.once('SIGTERM', () => { saveOnExit(); process.exit(0); });
|
|
112
|
-
process.once('SIGHUP', () => { saveOnExit(); process.exit(0); });
|
|
139
|
+
process.once('SIGTERM', () => { ipcServer.close(); saveOnExit(); process.exit(0); });
|
|
140
|
+
process.once('SIGHUP', () => { ipcServer.close(); saveOnExit(); process.exit(0); });
|
|
113
141
|
app.start();
|
|
114
142
|
return manager;
|
|
115
143
|
}
|
package/dist/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AACzC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAA;AACxF,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAA;AAEjC,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAOlD,MAAM,UAAU,KAAK,CAAC,UAAwB,EAAE;IAC9C,MAAM,UAAU,GACd,OAAO,CAAC,UAAU,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa,CAAC,CAAA;IACxE,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,YAAY,CAAC,CAAA;IACzD,MAAM,kBAAkB,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,sBAAsB,CAAC,CAAA;IAC5F,MAAM,MAAM,GAAG,UAAU,CAAC,UAAU,CAAC,CAAA;IAErC,MAAM,aAAa,GAAG,OAAO,CAAC,SAAS;QACrC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,SAAS,CAAC;QAC3D,CAAC,CAAC,MAAM,CAAC,MAAM,CAAA;IAEjB,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;QACpD,OAAO,CAAC,KAAK,CAAC,6BAA6B,OAAO,CAAC,SAAS,EAAE,CAAC,CAAA;QAC/D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,MAAM,UAAU,GAAG,SAAS,CAAC,SAAS,CAAC,CAAA;IAEvC,mDAAmD;IACnD,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,OAAO,OAAO,CAAC,GAAG,OAAO,CAAC,CAAA;IAC5D,MAAM,SAAS,GAAG,YAAY,CAAC,UAAU,CAAC,CAAA;IAC1C,SAAS,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;QACxC,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QAC5D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,oCAAoC,GAAG,4BAA4B,CAAC,CAAA;IAC3F,CAAC,CAAC,CAAA;IAEF,MAAM,OAAO,GAAG,IAAI,cAAc,EAAE,CAAA;IACpC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;IAC7E,MAAM,sBAAsB,GAAG,GAAG,EAAE;QAClC,MAAM,OAAO,GAAG,OAAO,CAAC,eAAe,CAAA;QACvC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,wBAAwB,CAAC,kBAAkB,CAAC,CAAA;YAC5C,OAAM;QACR,CAAC;QAED,uBAAuB,CAAC,kBAAkB,EAAE;YAC1C,EAAE,EAAE,OAAO,CAAC,EAAE;YACd,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,GAAG,EAAE,OAAO,CAAC,GAAG;SACjB,CAAC,CAAA;IACJ,CAAC,CAAA;IAED,MAAM,YAAY,GAA2B,EAAE,CAAA;IAC/C,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAU,CAAA;IAE1C,KAAK,MAAM,WAAW,IAAI,aAAa,EAAE,CAAC;QACxC,YAAY,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAA;QAC1E,MAAM,WAAW,GAAG,GAAG,WAAW,CAAC,IAAI,IAAI,YAAY,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAA;QAC3E,MAAM,YAAY,GAAG,UAAU,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAA;QAEtD,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,kBAAkB,CAC/C,WAAW,CAAC,IAAI,EAChB,WAAW,CAAC,IAAI,EAChB,YAAY,EAAE,SAAS,EACvB,YAAY,IAAI,IAAI,CACrB,CAAA;QAED,MAAM,WAAW,GAAG,YAAY,EAAE,GAAG,CAAA;QACrC,MAAM,OAAO,GAAG,yBAAyB,CAAA;QACzC,IAAI,UAAU,GAAG,IAAI,CAAA;QACrB,IAAI,SAAS,GAAa,EAAE,CAAA;QAC5B,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,aAAa,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC,CAAA;YACvF,UAAU,GAAG,UAAU,CAAC,IAAI,CAAA;YAC5B,SAAS,GAAG,UAAU,CAAC,SAAS,CAAA;QAClC,CAAC;QAAC,MAAM,CAAC;YACP,mDAAmD;QACrD,CAAC;QACD,MAAM,OAAO,GAAG,OAAO,CAAC,UAAU,CAChC,EAAE,GAAG,WAAW,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,CAAC,WAAW,IAAI,IAAI,IAAI,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC,EAAE,EACtF,EAAE,UAAU,EAAE,SAAS,EAAE,CACe,CAAA;QAC1C,OAAO,CAAC,QAAQ,GAAG,WAAW,CAAC,IAAI,CAAA;QACnC,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QAEhC,IAAI,YAAY,IAAI,IAAI,EAAE,CAAC;YACzB,OAAO,CAAC,SAAS,GAAG,YAAY,CAAA;QAClC,CAAC;IACH,CAAC;IAED,yCAAyC;IACzC,IAAI,UAAU,EAAE,CAAC;QACf,KAAK,MAAM,CAAC,OAAO,EAAE,YAAY,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1E,IAAI,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,SAAS;gBAAE,SAAQ;YAEtE,MAAM,EAAE,GAAG,YAAY,CAAC,SAAS,CAAA;YACjC,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,kBAAkB,CAC/C,EAAE,CAAC,IAAI,EACP,EAAE,CAAC,IAAI,EACP,YAAY,CAAC,SAAS,EACtB,IAAI,CACL,CAAA;YACD,MAAM,OAAO,GAAG,yBAAyB,CAAA;YACzC,IAAI,UAAU,GAAG,IAAI,CAAA;YACrB,IAAI,SAAS,GAAa,EAAE,CAAA;YAC5B,IAAI,CAAC;gBACH,MAAM,UAAU,GAAG,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,GAAG,EAAE,YAAY,CAAC,GAAG,EAAE,CAAC,CAAA;gBACnF,UAAU,GAAG,UAAU,CAAC,IAAI,CAAA;gBAC5B,SAAS,GAAG,UAAU,CAAC,SAAS,CAAA;YAClC,CAAC;YAAC,MAAM,CAAC;gBACP,mDAAmD;YACrD,CAAC;YACD,MAAM,OAAO,GAAG,OAAO,CAAC,UAAU,CAChC,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,CAAC,YAAY,CAAC,GAAG,IAAI,IAAI,IAAI,EAAE,GAAG,EAAE,YAAY,CAAC,GAAG,EAAE,CAAC,EAAE,EAC5G,EAAE,UAAU,EAAE,SAAS,EAAE,CACe,CAAA;YAC1C,OAAO,CAAC,QAAQ,GAAG,EAAE,CAAC,IAAI,CAAA;YAC1B,IAAI,YAAY,IAAI,IAAI,EAAE,CAAC;gBACzB,OAAO,CAAC,SAAS,GAAG,YAAY,CAAA;YAClC,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAA;IACvC,CAAC;IAED,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,SAAiB,EAAE,IAAY,EAAE,EAAE;QACrD,IAAI,IAAI,KAAK,CAAC;YAAE,OAAM;QACtB,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,SAAS,CAAC,CAAA;QAChE,IAAI,CAAC,OAAO;YAAE,OAAM;QACpB,IAAI,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,uCAAuC,CAAC,CAAC,EAAE,CAAC;YAC/F,OAAO,CAAC,aAAa,CAAC,SAAS,CAAC,CAAA;QAClC,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,OAAO,CAAC,EAAE,CAAC,WAAW,EAAE,GAAG,EAAE;QAC3B,sBAAsB,EAAE,CAAA;IAC1B,CAAC,CAAC,CAAA;IAEF,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,SAAiB,EAAE,EAAE;QACtC,IAAI,OAAO,CAAC,eAAe,EAAE,EAAE,KAAK,SAAS,EAAE,CAAC;YAC9C,OAAM;QACR,CAAC;QACD,sBAAsB,EAAE,CAAA;IAC1B,CAAC,CAAC,CAAA;IAEF,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,SAAiB,EAAE,EAAE;QACvC,IAAI,OAAO,CAAC,eAAe,EAAE,EAAE,KAAK,SAAS,EAAE,CAAC;YAC9C,OAAM;QACR,CAAC;QACD,sBAAsB,EAAE,CAAA;IAC1B,CAAC,CAAC,CAAA;IAEF,sBAAsB,EAAE,CAAA;IAExB,SAAS,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE;QAC1B,IAAI,GAAG,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;YACvB,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,SAAS,CAAC,CAAA;YACpE,OAAO,EAAE,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QAC9B,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,yCAAyC;IACzC,MAAM,UAAU,GAAG,GAAG,EAAE;QACtB,IAAI,CAAC;YAAC,SAAS,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;IAC9D,CAAC,CAAA;IACD,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA,CAAC,CAAC,CAAC,CAAA;IACnF,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA,CAAC,CAAC,CAAC,CAAA;IAElF,GAAG,CAAC,KAAK,EAAE,CAAA;IACX,OAAO,OAAO,CAAA;AAChB,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface IpcMessage {
|
|
2
|
+
type: string;
|
|
3
|
+
sessionId: string;
|
|
4
|
+
path: string;
|
|
5
|
+
}
|
|
6
|
+
type MessageHandler = (msg: IpcMessage) => void;
|
|
7
|
+
export interface IpcServer {
|
|
8
|
+
listen(): Promise<void>;
|
|
9
|
+
onMessage(handler: MessageHandler): void;
|
|
10
|
+
close(): void;
|
|
11
|
+
}
|
|
12
|
+
export declare function createServer(socketPath: string): IpcServer;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { createServer as netCreateServer } from 'node:net';
|
|
2
|
+
import { existsSync, unlinkSync } from 'node:fs';
|
|
3
|
+
export function createServer(socketPath) {
|
|
4
|
+
const handlers = [];
|
|
5
|
+
let server = null;
|
|
6
|
+
return {
|
|
7
|
+
onMessage(handler) {
|
|
8
|
+
handlers.push(handler);
|
|
9
|
+
},
|
|
10
|
+
listen() {
|
|
11
|
+
return new Promise((resolve, reject) => {
|
|
12
|
+
if (existsSync(socketPath)) {
|
|
13
|
+
unlinkSync(socketPath);
|
|
14
|
+
}
|
|
15
|
+
server = netCreateServer((socket) => {
|
|
16
|
+
let buf = '';
|
|
17
|
+
socket.on('error', () => { }); // absorb socket errors (e.g. ECONNRESET)
|
|
18
|
+
socket.on('data', (chunk) => {
|
|
19
|
+
buf += chunk.toString();
|
|
20
|
+
const lines = buf.split('\n');
|
|
21
|
+
buf = lines.pop() ?? '';
|
|
22
|
+
for (const line of lines) {
|
|
23
|
+
if (!line.trim())
|
|
24
|
+
continue;
|
|
25
|
+
try {
|
|
26
|
+
const msg = JSON.parse(line);
|
|
27
|
+
if (msg.type && msg.sessionId && typeof msg.path === 'string') {
|
|
28
|
+
handlers.forEach((h) => h(msg));
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
// ignore
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
server.once('error', reject);
|
|
38
|
+
server.listen(socketPath, () => {
|
|
39
|
+
server.removeListener('error', reject);
|
|
40
|
+
server.on('error', () => { }); // absorb post-bind server errors
|
|
41
|
+
resolve();
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
},
|
|
45
|
+
close() {
|
|
46
|
+
const closingServer = server;
|
|
47
|
+
server = null;
|
|
48
|
+
if (existsSync(socketPath)) {
|
|
49
|
+
try {
|
|
50
|
+
unlinkSync(socketPath);
|
|
51
|
+
}
|
|
52
|
+
catch { /* ignore */ }
|
|
53
|
+
}
|
|
54
|
+
closingServer?.close();
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=ipc-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ipc-server.js","sourceRoot":"","sources":["../../src/ipc-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,IAAI,eAAe,EAAkB,MAAM,UAAU,CAAA;AAC1E,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAgBhD,MAAM,UAAU,YAAY,CAAC,UAAkB;IAC7C,MAAM,QAAQ,GAAqB,EAAE,CAAA;IACrC,IAAI,MAAM,GAAkB,IAAI,CAAA;IAEhC,OAAO;QACL,SAAS,CAAC,OAAO;YACf,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QACxB,CAAC;QAED,MAAM;YACJ,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBACrC,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;oBAC3B,UAAU,CAAC,UAAU,CAAC,CAAA;gBACxB,CAAC;gBAED,MAAM,GAAG,eAAe,CAAC,CAAC,MAAc,EAAE,EAAE;oBAC1C,IAAI,GAAG,GAAG,EAAE,CAAA;oBACZ,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA,CAAC,yCAAyC;oBACtE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;wBAC1B,GAAG,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAA;wBACvB,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;wBAC7B,GAAG,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,CAAA;wBACvB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;4BACzB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;gCAAE,SAAQ;4BAC1B,IAAI,CAAC;gCACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAe,CAAA;gCAC1C,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,SAAS,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oCAC9D,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;gCACjC,CAAC;4BACH,CAAC;4BAAC,MAAM,CAAC;gCACP,SAAS;4BACX,CAAC;wBACH,CAAC;oBACH,CAAC,CAAC,CAAA;gBACJ,CAAC,CAAC,CAAA;gBAEF,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;gBAC5B,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,GAAG,EAAE;oBAC7B,MAAO,CAAC,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;oBACvC,MAAO,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA,CAAC,iCAAiC;oBAC/D,OAAO,EAAE,CAAA;gBACX,CAAC,CAAC,CAAA;YACJ,CAAC,CAAC,CAAA;QACJ,CAAC;QAED,KAAK;YACH,MAAM,aAAa,GAAG,MAAM,CAAA;YAC5B,MAAM,GAAG,IAAI,CAAA;YACb,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC3B,IAAI,CAAC;oBAAC,UAAU,CAAC,UAAU,CAAC,CAAA;gBAAC,CAAC;gBAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;YACvD,CAAC;YACD,aAAa,EAAE,KAAK,EAAE,CAAA;QACxB,CAAC;KACF,CAAA;AACH,CAAC"}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { EventEmitter } from 'node:events';
|
|
2
2
|
import { AgentSession } from './agent.js';
|
|
3
3
|
import type { AgentConfig } from './config.js';
|
|
4
|
+
import type { IpcContext } from './agent.js';
|
|
4
5
|
import type { MavState } from './state.js';
|
|
5
6
|
export declare class SessionManager extends EventEmitter {
|
|
6
7
|
sessions: AgentSession[];
|
|
7
8
|
selectedIndex: number;
|
|
8
9
|
private sessionListeners;
|
|
9
10
|
private emitSelection;
|
|
10
|
-
addSession(config: AgentConfig, cols?: number, rows?: number): AgentSession;
|
|
11
|
+
addSession(config: AgentConfig, ipcContext?: IpcContext, cols?: number, rows?: number): AgentSession;
|
|
11
12
|
removeSession(id: string): void;
|
|
12
13
|
selectSession(index: number): void;
|
|
13
14
|
get selectedSession(): AgentSession | null;
|
|
@@ -7,8 +7,8 @@ export class SessionManager extends EventEmitter {
|
|
|
7
7
|
emitSelection() {
|
|
8
8
|
this.emit('selection', this.selectedSession);
|
|
9
9
|
}
|
|
10
|
-
addSession(config, cols = 80, rows = 24) {
|
|
11
|
-
const session = new AgentSession(config, cols, rows);
|
|
10
|
+
addSession(config, ipcContext, cols = 80, rows = 24) {
|
|
11
|
+
const session = new AgentSession(config, cols, rows, ipcContext);
|
|
12
12
|
const onData = (chunk) => { this.emit('data', session.id, chunk); };
|
|
13
13
|
const onExit = (code) => { this.emit('exit', session.id, code); };
|
|
14
14
|
const onStatus = (status) => { this.emit('status', session.id, status); };
|