@k1e1n04/mav 0.1.25 → 0.1.28

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 CHANGED
@@ -123,11 +123,16 @@ mav tracks each agent's working directory. When an agent changes directory (e.g.
123
123
  | `claude-code` | IPC + PostToolUse hook | ✅ Auto-injected via `--settings` |
124
124
  | `gemini-cli` | IPC + AfterTool hook | ✅ Auto-injected via `.gemini/settings.local.json` |
125
125
  | `codex` | IPC + PostToolUse hook | ✅ Auto-injected via `--profile-v2` |
126
- | `copilot` | lsof polling only | Not supported (no hook API) |
126
+ | `copilot` | IPC + PostToolUse hook | Auto-injected via `.github/hooks/*.json` |
127
+ | `cursor` | lsof polling only | ❌ Not supported |
127
128
  | Other | lsof polling only | ❌ Not supported |
128
129
 
129
- > **Copilot** and unlisted agents use process polling to track the working directory.
130
+ > **Cursor** and unlisted agents use process polling to track the working directory.
130
131
  > Directory changes made in child processes (e.g., git worktrees) may not be detected.
132
+ >
133
+ > **Codex / Copilot / Gemini note:** even when `mav` tracks a session's latest `cwd`, these agents may not keep a persistent shell `cd` across turns in this environment. In practice, they can follow the worktree by running each command with that directory as its `workdir`, rather than by changing their own long-lived terminal state.
134
+ >
135
+ > If you want shell-like directory changes to feel most natural inside the agent session itself, `claude-code` is currently the safest choice.
131
136
 
132
137
  ## Keybindings
133
138
 
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@k1e1n04/mav",
3
- "version": "0.1.25",
3
+ "version": "0.1.28",
4
4
  "description": "Multi-agent view — manage multiple AI CLI sessions in one terminal",
5
5
  "type": "module",
6
6
  "bin": {
@@ -13,6 +13,8 @@ export function buildHookArgs(agentType, baseArgs, hookCommand, options = {}) {
13
13
  return buildClaudeCodeHook(baseArgs, hookCommand);
14
14
  case 'gemini-cli':
15
15
  return buildGeminiHook(baseArgs, hookCommand, options.cwd);
16
+ case 'copilot':
17
+ return buildCopilotHook(baseArgs, hookCommand, options.cwd);
16
18
  case 'codex':
17
19
  return buildCodexHook(baseArgs, hookCommand);
18
20
  default:
@@ -20,9 +22,24 @@ export function buildHookArgs(agentType, baseArgs, hookCommand, options = {}) {
20
22
  }
21
23
  }
22
24
  function buildClaudeCodeHook(baseArgs, hookCommand) {
23
- const settings = {
25
+ const claudeSettingsPath = join(homedir(), '.claude', 'settings.json');
26
+ let existing = {};
27
+ if (existsSync(claudeSettingsPath)) {
28
+ try {
29
+ existing = JSON.parse(readFileSync(claudeSettingsPath, 'utf-8'));
30
+ }
31
+ catch {
32
+ // Unreadable/invalid JSON — start from empty
33
+ }
34
+ }
35
+ const existingHooks = (existing.hooks ?? {});
36
+ const existingPostToolUse = (existingHooks.PostToolUse ?? []);
37
+ const merged = {
38
+ ...existing,
24
39
  hooks: {
40
+ ...existingHooks,
25
41
  PostToolUse: [
42
+ ...existingPostToolUse,
26
43
  {
27
44
  matcher: '',
28
45
  hooks: [{ type: 'command', command: hookCommand }],
@@ -31,7 +48,7 @@ function buildClaudeCodeHook(baseArgs, hookCommand) {
31
48
  },
32
49
  };
33
50
  return {
34
- args: [...baseArgs, '--settings', JSON.stringify(settings)],
51
+ args: [...baseArgs, '--settings', JSON.stringify(merged)],
35
52
  hookFiles: [],
36
53
  };
37
54
  }
@@ -83,6 +100,28 @@ function buildCodexHook(baseArgs, hookCommand) {
83
100
  hookFiles: [tomlPath],
84
101
  };
85
102
  }
103
+ function buildCopilotHook(baseArgs, hookCommand, cwd) {
104
+ const projectDir = cwd ?? process.cwd();
105
+ const hooksDir = join(projectDir, '.github', 'hooks');
106
+ const hookPath = join(hooksDir, `mav-${randomUUID()}.json`);
107
+ const hookConfig = {
108
+ version: 1,
109
+ hooks: {
110
+ postToolUse: [
111
+ {
112
+ type: 'command',
113
+ command: hookCommand,
114
+ },
115
+ ],
116
+ },
117
+ };
118
+ mkdirSync(hooksDir, { recursive: true });
119
+ writeFileSync(hookPath, JSON.stringify(hookConfig, null, 2));
120
+ return {
121
+ args: baseArgs,
122
+ hookFiles: [hookPath],
123
+ };
124
+ }
86
125
  /**
87
126
  * Deletes temp files generated by buildHookArgs.
88
127
  * Call this when the agent process exits.
@@ -1 +1 @@
1
- {"version":3,"file":"hook-injector.js","sourceRoot":"","sources":["../../src/hook-injector.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hook-injector.js","sourceRoot":"","sources":["../../src/hook-injector.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@k1e1n04/mav",
3
- "version": "0.1.25",
3
+ "version": "0.1.28",
4
4
  "description": "Multi-agent view — manage multiple AI CLI sessions in one terminal",
5
5
  "type": "module",
6
6
  "bin": {
@@ -31,6 +31,8 @@ export function buildHookArgs(
31
31
  return buildClaudeCodeHook(baseArgs, hookCommand)
32
32
  case 'gemini-cli':
33
33
  return buildGeminiHook(baseArgs, hookCommand, options.cwd)
34
+ case 'copilot':
35
+ return buildCopilotHook(baseArgs, hookCommand, options.cwd)
34
36
  case 'codex':
35
37
  return buildCodexHook(baseArgs, hookCommand)
36
38
  default:
@@ -39,9 +41,25 @@ export function buildHookArgs(
39
41
  }
40
42
 
41
43
  function buildClaudeCodeHook(baseArgs: string[], hookCommand: string): HookInjectionResult {
42
- const settings = {
44
+ const claudeSettingsPath = join(homedir(), '.claude', 'settings.json')
45
+ let existing: Record<string, unknown> = {}
46
+ if (existsSync(claudeSettingsPath)) {
47
+ try {
48
+ existing = JSON.parse(readFileSync(claudeSettingsPath, 'utf-8')) as Record<string, unknown>
49
+ } catch {
50
+ // Unreadable/invalid JSON — start from empty
51
+ }
52
+ }
53
+
54
+ const existingHooks = (existing.hooks ?? {}) as Record<string, unknown[]>
55
+ const existingPostToolUse = (existingHooks.PostToolUse ?? []) as unknown[]
56
+
57
+ const merged = {
58
+ ...existing,
43
59
  hooks: {
60
+ ...existingHooks,
44
61
  PostToolUse: [
62
+ ...existingPostToolUse,
45
63
  {
46
64
  matcher: '',
47
65
  hooks: [{ type: 'command', command: hookCommand }],
@@ -49,8 +67,9 @@ function buildClaudeCodeHook(baseArgs: string[], hookCommand: string): HookInjec
49
67
  ],
50
68
  },
51
69
  }
70
+
52
71
  return {
53
- args: [...baseArgs, '--settings', JSON.stringify(settings)],
72
+ args: [...baseArgs, '--settings', JSON.stringify(merged)],
54
73
  hookFiles: [],
55
74
  }
56
75
  }
@@ -116,6 +135,35 @@ function buildCodexHook(baseArgs: string[], hookCommand: string): HookInjectionR
116
135
  }
117
136
  }
118
137
 
138
+ function buildCopilotHook(
139
+ baseArgs: string[],
140
+ hookCommand: string,
141
+ cwd?: string,
142
+ ): HookInjectionResult {
143
+ const projectDir = cwd ?? process.cwd()
144
+ const hooksDir = join(projectDir, '.github', 'hooks')
145
+ const hookPath = join(hooksDir, `mav-${randomUUID()}.json`)
146
+ const hookConfig = {
147
+ version: 1,
148
+ hooks: {
149
+ postToolUse: [
150
+ {
151
+ type: 'command',
152
+ command: hookCommand,
153
+ },
154
+ ],
155
+ },
156
+ }
157
+
158
+ mkdirSync(hooksDir, { recursive: true })
159
+ writeFileSync(hookPath, JSON.stringify(hookConfig, null, 2))
160
+
161
+ return {
162
+ args: baseArgs,
163
+ hookFiles: [hookPath],
164
+ }
165
+ }
166
+
119
167
  /**
120
168
  * Deletes temp files generated by buildHookArgs.
121
169
  * Call this when the agent process exits.