@achieveai/hitl-mcp-server 2.9.1 → 2.11.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/dist/cli.d.ts +31 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +133 -5
- package/dist/cli.js.map +1 -1
- package/dist/git-context.d.ts +41 -2
- package/dist/git-context.d.ts.map +1 -1
- package/dist/git-context.js +86 -2
- package/dist/git-context.js.map +1 -1
- package/dist/host-settings.d.ts +68 -0
- package/dist/host-settings.d.ts.map +1 -0
- package/dist/host-settings.js +136 -0
- package/dist/host-settings.js.map +1 -0
- package/dist/mcp-server.d.ts +54 -1
- package/dist/mcp-server.d.ts.map +1 -1
- package/dist/mcp-server.js +421 -70
- package/dist/mcp-server.js.map +1 -1
- package/dist/ntfy-transport.d.ts +285 -13
- package/dist/ntfy-transport.d.ts.map +1 -1
- package/dist/ntfy-transport.js +747 -88
- package/dist/ntfy-transport.js.map +1 -1
- package/dist/payload.d.ts +80 -0
- package/dist/payload.d.ts.map +1 -0
- package/dist/payload.js +135 -0
- package/dist/payload.js.map +1 -0
- package/dist/plan-diff.d.ts +29 -0
- package/dist/plan-diff.d.ts.map +1 -0
- package/dist/plan-diff.js +138 -0
- package/dist/plan-diff.js.map +1 -0
- package/dist/plan-file.d.ts +24 -0
- package/dist/plan-file.d.ts.map +1 -0
- package/dist/plan-file.js +98 -0
- package/dist/plan-file.js.map +1 -0
- package/dist/plan-review.d.ts +54 -0
- package/dist/plan-review.d.ts.map +1 -0
- package/dist/plan-review.js +110 -0
- package/dist/plan-review.js.map +1 -0
- package/dist/setup.d.ts +22 -5
- package/dist/setup.d.ts.map +1 -1
- package/dist/setup.js +52 -15
- package/dist/setup.js.map +1 -1
- package/dist/snapshot-store.d.ts +104 -0
- package/dist/snapshot-store.d.ts.map +1 -0
- package/dist/snapshot-store.js +209 -0
- package/dist/snapshot-store.js.map +1 -0
- package/dist/types.d.ts +114 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -1
- package/dist/version.d.ts +13 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +15 -0
- package/dist/version.js.map +1 -0
- package/package.json +64 -61
- package/dist/bin/windows-x64/hitl-client.exe +0 -0
package/dist/cli.d.ts
CHANGED
|
@@ -1,3 +1,33 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
2
|
+
/** Result of merging HITL's entry into a host's global (user-level) settings. */
|
|
3
|
+
export interface HostSettingMergeResult {
|
|
4
|
+
updated: boolean;
|
|
5
|
+
path: string;
|
|
6
|
+
}
|
|
7
|
+
/** Injectable dependencies for {@link performClaudeCodeInstall}, for testing. */
|
|
8
|
+
export interface ClaudeCodeInstallDeps {
|
|
9
|
+
runClaudeMcpAdd: (args: string[]) => void;
|
|
10
|
+
mergeGlobalHostSetting: () => HostSettingMergeResult;
|
|
11
|
+
}
|
|
12
|
+
export interface ClaudeCodeInstallResult {
|
|
13
|
+
success: boolean;
|
|
14
|
+
registered: 'added' | 'already_registered' | 'error';
|
|
15
|
+
message: string;
|
|
16
|
+
hostSetting: HostSettingMergeResult;
|
|
17
|
+
restartInstruction: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Build the argv for `claude mcp add`, registering HITL as a user-scoped
|
|
21
|
+
* stdio MCP server launched via npx. Deliberately carries no `--env` flags:
|
|
22
|
+
* any "auto-launch client in the background" behavior belongs in global host
|
|
23
|
+
* settings (merged separately via mergeGlobalHostSetting), not baked into
|
|
24
|
+
* this per-registration command line.
|
|
25
|
+
*/
|
|
26
|
+
export declare function buildClaudeMcpAddArgs(): string[];
|
|
27
|
+
/**
|
|
28
|
+
* Register HITL as a Claude Code MCP server and merge the global host
|
|
29
|
+
* setting. Idempotent: re-running after a prior successful install reports
|
|
30
|
+
* `registered: 'already_registered'` (success) rather than an error.
|
|
31
|
+
*/
|
|
32
|
+
export declare function performClaudeCodeInstall(deps?: ClaudeCodeInstallDeps): ClaudeCodeInstallResult;
|
|
3
33
|
//# sourceMappingURL=cli.d.ts.map
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAuIA,iFAAiF;AACjF,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAaD,iFAAiF;AACjF,MAAM,WAAW,qBAAqB;IACpC,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IAC1C,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;CACtD;AAED,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,OAAO,GAAG,oBAAoB,GAAG,OAAO,CAAC;IACrD,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,sBAAsB,CAAC;IACpC,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,EAAE,CAQhD;AAmBD;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,GAAE,qBAGL,GACA,uBAAuB,CAwCzB"}
|
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import crypto from 'crypto';
|
|
3
|
+
import { execFileSync } from 'child_process';
|
|
3
4
|
import { loadConfig, saveConfig, generateDefaultConfig, getConfigPath } from './config.js';
|
|
4
5
|
import { findClientBinary, launchClient } from './setup.js';
|
|
6
|
+
import { applyAutoBackgroundSetting } from './host-settings.js';
|
|
5
7
|
import { dirname } from 'path';
|
|
6
8
|
import { fileURLToPath } from 'url';
|
|
7
9
|
const HELP = `
|
|
@@ -13,6 +15,7 @@ Usage:
|
|
|
13
15
|
hitl config set-topic <id> Update the topic ID
|
|
14
16
|
hitl test Send a test question through ntfy
|
|
15
17
|
hitl client Launch the HITL desktop client app
|
|
18
|
+
hitl claude-code install Register HITL as a Claude Code MCP server (user scope)
|
|
16
19
|
hitl help Show this help message
|
|
17
20
|
`;
|
|
18
21
|
async function main() {
|
|
@@ -27,6 +30,8 @@ async function main() {
|
|
|
27
30
|
return cmdTest();
|
|
28
31
|
case 'client':
|
|
29
32
|
return cmdClient();
|
|
33
|
+
case 'claude-code':
|
|
34
|
+
return cmdClaudeCode(args.slice(1));
|
|
30
35
|
case 'help':
|
|
31
36
|
case '--help':
|
|
32
37
|
case '-h':
|
|
@@ -108,6 +113,123 @@ function cmdClient() {
|
|
|
108
113
|
launchClient(binaryPath);
|
|
109
114
|
console.log(`HITL Client launched from ${binaryPath}`);
|
|
110
115
|
}
|
|
116
|
+
// --- claude-code install ---
|
|
117
|
+
const CLAUDE_CODE_MCP_NAME = 'hitl';
|
|
118
|
+
const CLAUDE_CODE_MCP_PACKAGE = '@achieveai/hitl-mcp-server';
|
|
119
|
+
const CLAUDE_CODE_RESTART_INSTRUCTION = 'Restart Claude Code (or start a new session) for the HITL MCP server to become available.';
|
|
120
|
+
/**
|
|
121
|
+
* Merge HITL's entry into Claude Code's global user-level settings
|
|
122
|
+
* (~/.claude/settings.json), setting CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS="0"
|
|
123
|
+
* so Claude Code never auto-backgrounds a blocking HITL tool call before the
|
|
124
|
+
* human gets a chance to respond. Delegates to host-settings.ts, which
|
|
125
|
+
* preserves every unrelated key and is idempotent.
|
|
126
|
+
*/
|
|
127
|
+
function defaultMergeGlobalHostSetting() {
|
|
128
|
+
return applyAutoBackgroundSetting();
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Build the argv for `claude mcp add`, registering HITL as a user-scoped
|
|
132
|
+
* stdio MCP server launched via npx. Deliberately carries no `--env` flags:
|
|
133
|
+
* any "auto-launch client in the background" behavior belongs in global host
|
|
134
|
+
* settings (merged separately via mergeGlobalHostSetting), not baked into
|
|
135
|
+
* this per-registration command line.
|
|
136
|
+
*/
|
|
137
|
+
export function buildClaudeMcpAddArgs() {
|
|
138
|
+
return [
|
|
139
|
+
'mcp', 'add', CLAUDE_CODE_MCP_NAME,
|
|
140
|
+
'--scope', 'user',
|
|
141
|
+
'--transport', 'stdio',
|
|
142
|
+
'--',
|
|
143
|
+
'npx', '-y', CLAUDE_CODE_MCP_PACKAGE,
|
|
144
|
+
];
|
|
145
|
+
}
|
|
146
|
+
function defaultRunClaudeMcpAdd(args) {
|
|
147
|
+
// execFileSync: argv passed as an array, no shell involved — safe against
|
|
148
|
+
// shell injection, unlike execSync/exec with a concatenated string.
|
|
149
|
+
execFileSync('claude', args, { stdio: 'pipe', encoding: 'utf-8' });
|
|
150
|
+
}
|
|
151
|
+
function errorText(err) {
|
|
152
|
+
if (err instanceof Error) {
|
|
153
|
+
const withStreams = err;
|
|
154
|
+
const parts = [withStreams.message, withStreams.stderr, withStreams.stdout]
|
|
155
|
+
.filter((p) => Boolean(p))
|
|
156
|
+
.map((p) => p.toString());
|
|
157
|
+
return parts.join('\n');
|
|
158
|
+
}
|
|
159
|
+
return String(err);
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Register HITL as a Claude Code MCP server and merge the global host
|
|
163
|
+
* setting. Idempotent: re-running after a prior successful install reports
|
|
164
|
+
* `registered: 'already_registered'` (success) rather than an error.
|
|
165
|
+
*/
|
|
166
|
+
export function performClaudeCodeInstall(deps = {
|
|
167
|
+
runClaudeMcpAdd: defaultRunClaudeMcpAdd,
|
|
168
|
+
mergeGlobalHostSetting: defaultMergeGlobalHostSetting,
|
|
169
|
+
}) {
|
|
170
|
+
let registered = 'added';
|
|
171
|
+
let message = `Registered "${CLAUDE_CODE_MCP_NAME}" as a user-scoped Claude Code MCP server.`;
|
|
172
|
+
try {
|
|
173
|
+
deps.runClaudeMcpAdd(buildClaudeMcpAddArgs());
|
|
174
|
+
}
|
|
175
|
+
catch (err) {
|
|
176
|
+
const text = errorText(err);
|
|
177
|
+
if (/already exists/i.test(text)) {
|
|
178
|
+
registered = 'already_registered';
|
|
179
|
+
message = `"${CLAUDE_CODE_MCP_NAME}" is already registered as a Claude Code MCP server.`;
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
return {
|
|
183
|
+
success: false,
|
|
184
|
+
registered: 'error',
|
|
185
|
+
message: `Failed to register "${CLAUDE_CODE_MCP_NAME}" with Claude Code: ${text}`,
|
|
186
|
+
hostSetting: { updated: false, path: '' },
|
|
187
|
+
restartInstruction: CLAUDE_CODE_RESTART_INSTRUCTION,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
try {
|
|
192
|
+
const hostSetting = deps.mergeGlobalHostSetting();
|
|
193
|
+
return {
|
|
194
|
+
success: true,
|
|
195
|
+
registered,
|
|
196
|
+
message,
|
|
197
|
+
hostSetting,
|
|
198
|
+
restartInstruction: CLAUDE_CODE_RESTART_INSTRUCTION,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
catch (err) {
|
|
202
|
+
return {
|
|
203
|
+
success: false,
|
|
204
|
+
registered,
|
|
205
|
+
message: `${message} Failed to update global host settings: ${errorText(err)}`,
|
|
206
|
+
hostSetting: { updated: false, path: '' },
|
|
207
|
+
restartInstruction: CLAUDE_CODE_RESTART_INSTRUCTION,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
function cmdClaudeCodeInstall() {
|
|
212
|
+
const result = performClaudeCodeInstall();
|
|
213
|
+
console.log(result.message);
|
|
214
|
+
if (result.hostSetting.updated) {
|
|
215
|
+
console.log(`Updated global host settings at ${result.hostSetting.path}`);
|
|
216
|
+
}
|
|
217
|
+
console.log(result.restartInstruction);
|
|
218
|
+
if (!result.success) {
|
|
219
|
+
process.exit(1);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
function cmdClaudeCode(args) {
|
|
223
|
+
const subcommand = args[0];
|
|
224
|
+
switch (subcommand) {
|
|
225
|
+
case 'install':
|
|
226
|
+
return cmdClaudeCodeInstall();
|
|
227
|
+
default:
|
|
228
|
+
console.error(`Unknown claude-code subcommand: ${subcommand}`);
|
|
229
|
+
console.log('Available: install');
|
|
230
|
+
process.exit(1);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
111
233
|
async function cmdTest() {
|
|
112
234
|
const config = loadConfig();
|
|
113
235
|
const { NtfyTransport } = await import('./ntfy-transport.js');
|
|
@@ -138,7 +260,7 @@ async function cmdTest() {
|
|
|
138
260
|
console.log('');
|
|
139
261
|
console.log('Waiting for response (60s timeout)...');
|
|
140
262
|
try {
|
|
141
|
-
const answer = await transport.waitForAnswer(messageId, 60000);
|
|
263
|
+
const answer = await transport.waitForAnswer(messageId, AbortSignal.timeout(60000));
|
|
142
264
|
console.log('');
|
|
143
265
|
console.log('✓ Response received!');
|
|
144
266
|
console.log(` From: ${answer.respondedFrom}`);
|
|
@@ -156,8 +278,14 @@ async function cmdTest() {
|
|
|
156
278
|
transport.close();
|
|
157
279
|
}
|
|
158
280
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
281
|
+
// Only run when executed directly (e.g. `node cli.js` / the `hitl` bin), not
|
|
282
|
+
// when imported as a module (e.g. from tests) — importing must not have the
|
|
283
|
+
// side effect of parsing real process.argv and dispatching a command.
|
|
284
|
+
const isMainModule = process.argv[1] === fileURLToPath(import.meta.url);
|
|
285
|
+
if (isMainModule) {
|
|
286
|
+
main().catch((err) => {
|
|
287
|
+
console.error('Error:', err.message);
|
|
288
|
+
process.exit(1);
|
|
289
|
+
});
|
|
290
|
+
}
|
|
163
291
|
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC3F,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,MAAM,IAAI,GAAG
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/git-context.d.ts
CHANGED
|
@@ -1,7 +1,46 @@
|
|
|
1
1
|
import type { RepoContext } from './types.js';
|
|
2
2
|
/**
|
|
3
|
-
* Auto-detect git repository context
|
|
4
|
-
*
|
|
3
|
+
* Auto-detect git repository context.
|
|
4
|
+
*
|
|
5
|
+
* `cwd` matters: a plan usually lives in a sibling repo while the agent's
|
|
6
|
+
* process cwd is the workspace root, so callers with a concrete file must pass
|
|
7
|
+
* `path.dirname(resolvedPlanPath)` rather than relying on the default (B-6).
|
|
8
|
+
* Returns null gracefully if git is unavailable or the directory is not a repo.
|
|
5
9
|
*/
|
|
6
10
|
export declare function detectRepoContext(cwd?: string): RepoContext | null;
|
|
11
|
+
/**
|
|
12
|
+
* Absolute path of the repository root containing `dir`, or null when `dir`
|
|
13
|
+
* is not inside a work tree.
|
|
14
|
+
*
|
|
15
|
+
* Runs `git -C <dir>` so the answer describes the plan file's repo, not the
|
|
16
|
+
* server process's cwd. The result is normalized, so two spellings of the same
|
|
17
|
+
* root (`B:\repo` vs `b:/repo`) produce one identity (B-10).
|
|
18
|
+
*/
|
|
19
|
+
export declare function resolveRepoRoot(dir: string): string | null;
|
|
20
|
+
/**
|
|
21
|
+
* Whether `absPath` is tracked by the git repo containing it.
|
|
22
|
+
*
|
|
23
|
+
* Used to pick the revision-1 diff baseline: a tracked plan diffs against
|
|
24
|
+
* `HEAD:<relpath>`, an untracked one renders as all-added (B-5).
|
|
25
|
+
*/
|
|
26
|
+
export declare function isTracked(repoRoot: string, absPath: string): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Content of `absPath` at git HEAD, or null when the path is untracked, the
|
|
29
|
+
* repo has no commits yet, or git is unavailable.
|
|
30
|
+
*
|
|
31
|
+
* Returned as a raw utf-8 string with line endings untouched — normalizing CRLF
|
|
32
|
+
* here would shift every anchor in the diff (B-11).
|
|
33
|
+
*/
|
|
34
|
+
export declare function readHeadContent(repoRoot: string, absPath: string): string | null;
|
|
35
|
+
/** Forward-slashed, repo-root-relative form of `absPath` — git's own spelling. */
|
|
36
|
+
export declare function toRepoRelative(repoRoot: string, absPath: string): string;
|
|
37
|
+
/**
|
|
38
|
+
* Canonical spelling of a path for hashing and comparison.
|
|
39
|
+
*
|
|
40
|
+
* Windows paths are case-insensitive and accept either separator, so `B:\a\b`
|
|
41
|
+
* and `b:/a/b` name the same file and must hash to one identity (B-10). Only
|
|
42
|
+
* the drive letter is case-folded — the rest of the path keeps its case, since
|
|
43
|
+
* the store is also read on case-sensitive filesystems.
|
|
44
|
+
*/
|
|
45
|
+
export declare function normalizePath(p: string): string;
|
|
7
46
|
//# sourceMappingURL=git-context.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git-context.d.ts","sourceRoot":"","sources":["../src/git-context.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"git-context.d.ts","sourceRoot":"","sources":["../src/git-context.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAwBlE;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAY1D;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAYpE;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAYhF;AAED,kFAAkF;AAClF,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAExE;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAG/C"}
|
package/dist/git-context.js
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import { execSync } from 'child_process';
|
|
2
|
+
import path from 'path';
|
|
2
3
|
/**
|
|
3
|
-
* Auto-detect git repository context
|
|
4
|
-
*
|
|
4
|
+
* Auto-detect git repository context.
|
|
5
|
+
*
|
|
6
|
+
* `cwd` matters: a plan usually lives in a sibling repo while the agent's
|
|
7
|
+
* process cwd is the workspace root, so callers with a concrete file must pass
|
|
8
|
+
* `path.dirname(resolvedPlanPath)` rather than relying on the default (B-6).
|
|
9
|
+
* Returns null gracefully if git is unavailable or the directory is not a repo.
|
|
5
10
|
*/
|
|
6
11
|
export function detectRepoContext(cwd) {
|
|
7
12
|
const opts = { cwd: cwd ?? process.cwd(), encoding: 'utf-8', timeout: 5000 };
|
|
@@ -26,4 +31,83 @@ export function detectRepoContext(cwd) {
|
|
|
26
31
|
const remoteUrl = run('git remote get-url origin');
|
|
27
32
|
return { name, branch, remoteUrl };
|
|
28
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* Absolute path of the repository root containing `dir`, or null when `dir`
|
|
36
|
+
* is not inside a work tree.
|
|
37
|
+
*
|
|
38
|
+
* Runs `git -C <dir>` so the answer describes the plan file's repo, not the
|
|
39
|
+
* server process's cwd. The result is normalized, so two spellings of the same
|
|
40
|
+
* root (`B:\repo` vs `b:/repo`) produce one identity (B-10).
|
|
41
|
+
*/
|
|
42
|
+
export function resolveRepoRoot(dir) {
|
|
43
|
+
try {
|
|
44
|
+
const out = execSync('git rev-parse --show-toplevel', {
|
|
45
|
+
cwd: dir,
|
|
46
|
+
encoding: 'utf-8',
|
|
47
|
+
timeout: 5000,
|
|
48
|
+
stdio: 'pipe',
|
|
49
|
+
}).trim();
|
|
50
|
+
return out ? normalizePath(out) : null;
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Whether `absPath` is tracked by the git repo containing it.
|
|
58
|
+
*
|
|
59
|
+
* Used to pick the revision-1 diff baseline: a tracked plan diffs against
|
|
60
|
+
* `HEAD:<relpath>`, an untracked one renders as all-added (B-5).
|
|
61
|
+
*/
|
|
62
|
+
export function isTracked(repoRoot, absPath) {
|
|
63
|
+
try {
|
|
64
|
+
execSync(`git ls-files --error-unmatch -- "${toRepoRelative(repoRoot, absPath)}"`, {
|
|
65
|
+
cwd: repoRoot,
|
|
66
|
+
encoding: 'utf-8',
|
|
67
|
+
timeout: 5000,
|
|
68
|
+
stdio: 'pipe',
|
|
69
|
+
});
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Content of `absPath` at git HEAD, or null when the path is untracked, the
|
|
78
|
+
* repo has no commits yet, or git is unavailable.
|
|
79
|
+
*
|
|
80
|
+
* Returned as a raw utf-8 string with line endings untouched — normalizing CRLF
|
|
81
|
+
* here would shift every anchor in the diff (B-11).
|
|
82
|
+
*/
|
|
83
|
+
export function readHeadContent(repoRoot, absPath) {
|
|
84
|
+
try {
|
|
85
|
+
const relative = toRepoRelative(repoRoot, absPath);
|
|
86
|
+
return execSync(`git show "HEAD:${relative}"`, {
|
|
87
|
+
cwd: repoRoot,
|
|
88
|
+
timeout: 5000,
|
|
89
|
+
stdio: 'pipe',
|
|
90
|
+
maxBuffer: 64 * 1024 * 1024,
|
|
91
|
+
}).toString('utf8');
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/** Forward-slashed, repo-root-relative form of `absPath` — git's own spelling. */
|
|
98
|
+
export function toRepoRelative(repoRoot, absPath) {
|
|
99
|
+
return path.relative(repoRoot, absPath).split(path.sep).join('/');
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Canonical spelling of a path for hashing and comparison.
|
|
103
|
+
*
|
|
104
|
+
* Windows paths are case-insensitive and accept either separator, so `B:\a\b`
|
|
105
|
+
* and `b:/a/b` name the same file and must hash to one identity (B-10). Only
|
|
106
|
+
* the drive letter is case-folded — the rest of the path keeps its case, since
|
|
107
|
+
* the store is also read on case-sensitive filesystems.
|
|
108
|
+
*/
|
|
109
|
+
export function normalizePath(p) {
|
|
110
|
+
const slashed = p.replace(/\\/g, '/').replace(/\/+$/, '');
|
|
111
|
+
return slashed.replace(/^([a-zA-Z]):/, (_m, drive) => `${drive.toUpperCase()}:`);
|
|
112
|
+
}
|
|
29
113
|
//# sourceMappingURL=git-context.js.map
|
package/dist/git-context.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git-context.js","sourceRoot":"","sources":["../src/git-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"git-context.js","sourceRoot":"","sources":["../src/git-context.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/** The env var Claude Code reads to decide when to auto-background a long-running MCP tool call. */
|
|
2
|
+
export declare const AUTO_BACKGROUND_ENV_KEY = "CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS";
|
|
3
|
+
/** The value that disables auto-backgrounding, so a blocking HITL tool call is never yanked away before the human answers. */
|
|
4
|
+
export declare const AUTO_BACKGROUND_TARGET_VALUE = "0";
|
|
5
|
+
/** Result of checking whether the auto-background guard is in effect. */
|
|
6
|
+
export interface AutoBackgroundStatus {
|
|
7
|
+
/** True if the guard is already effective now, or will be after the next Claude Code restart. */
|
|
8
|
+
active: boolean;
|
|
9
|
+
/** True if the *currently running* process inherited the target value (in effect right now). */
|
|
10
|
+
activeInEnv: boolean;
|
|
11
|
+
/** True if ~/.claude/settings.json has the target value queued for the next restart. */
|
|
12
|
+
configuredForRestart: boolean;
|
|
13
|
+
/** Raw value observed in the inherited env, if any. */
|
|
14
|
+
envValue?: string;
|
|
15
|
+
/** Raw value observed in settings.json's `env` block, if any. */
|
|
16
|
+
settingsValue?: string;
|
|
17
|
+
}
|
|
18
|
+
/** Locate the host Claude Code settings file: ~/.claude/settings.json */
|
|
19
|
+
export declare function getHostSettingsPath(): string;
|
|
20
|
+
/**
|
|
21
|
+
* Read a Claude Code settings.json file. Returns an empty object when the
|
|
22
|
+
* file is missing or blank, so callers can merge into the result unconditionally.
|
|
23
|
+
* Malformed JSON is not swallowed — it throws, so a caller can surface a clear
|
|
24
|
+
* error instead of silently discarding a user's existing settings.
|
|
25
|
+
*/
|
|
26
|
+
export declare function readHostSettings(settingsPath?: string): Record<string, unknown>;
|
|
27
|
+
/**
|
|
28
|
+
* Merge the auto-background remediation value into an existing settings
|
|
29
|
+
* object, preserving every other top-level key and every other `env` entry.
|
|
30
|
+
* Pure function — never mutates its input. Applying it to its own output is
|
|
31
|
+
* idempotent (produces an equal object).
|
|
32
|
+
*/
|
|
33
|
+
export declare function mergeAutoBackgroundSetting(existingSettings: Record<string, unknown>): Record<string, unknown>;
|
|
34
|
+
/** Result of writing the auto-background remediation to disk. */
|
|
35
|
+
export interface ApplySettingsResult {
|
|
36
|
+
/** True if the file was created or modified to reach the target state. */
|
|
37
|
+
updated: boolean;
|
|
38
|
+
/** Path to the settings file that was read/written. */
|
|
39
|
+
path: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Apply the auto-background remediation to disk: read the existing
|
|
43
|
+
* settings.json (if any), merge in the target env value via
|
|
44
|
+
* {@link mergeAutoBackgroundSetting}, and write the result back only if it
|
|
45
|
+
* actually changed. Re-running this after a prior successful run is a no-op
|
|
46
|
+
* (`updated: false`) rather than rewriting an identical file.
|
|
47
|
+
*
|
|
48
|
+
* The parent directory (e.g. ~/.claude) is created if missing. Writes are
|
|
49
|
+
* atomic — see {@link writeAtomic}.
|
|
50
|
+
*/
|
|
51
|
+
export declare function applyAutoBackgroundSetting(settingsPath?: string): ApplySettingsResult;
|
|
52
|
+
/**
|
|
53
|
+
* Detect whether the auto-background guard is already in effect:
|
|
54
|
+
* - `activeInEnv`: the currently running process inherited it — in effect now.
|
|
55
|
+
* - `configuredForRestart`: ~/.claude/settings.json has it queued — takes
|
|
56
|
+
* effect the next time Claude Code restarts, not for the current session.
|
|
57
|
+
*
|
|
58
|
+
* Never throws: a missing or malformed settings.json is treated the same as
|
|
59
|
+
* "not configured", since this is a read-only diagnostic.
|
|
60
|
+
*/
|
|
61
|
+
export declare function detectAutoBackgroundStatus(env?: NodeJS.ProcessEnv, settingsPath?: string): AutoBackgroundStatus;
|
|
62
|
+
/**
|
|
63
|
+
* Build reusable, human-readable remediation text for when the auto-background
|
|
64
|
+
* guard is not yet active. Shared by the setup diagnostic step, and any future
|
|
65
|
+
* CLI/UX surface that needs to explain the same fix.
|
|
66
|
+
*/
|
|
67
|
+
export declare function buildAutoBackgroundRemediationText(settingsPath?: string): string;
|
|
68
|
+
//# sourceMappingURL=host-settings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host-settings.d.ts","sourceRoot":"","sources":["../src/host-settings.ts"],"names":[],"mappings":"AAKA,oGAAoG;AACpG,eAAO,MAAM,uBAAuB,uCAAuC,CAAC;AAE5E,8HAA8H;AAC9H,eAAO,MAAM,4BAA4B,MAAM,CAAC;AAEhD,yEAAyE;AACzE,MAAM,WAAW,oBAAoB;IACnC,iGAAiG;IACjG,MAAM,EAAE,OAAO,CAAC;IAChB,gGAAgG;IAChG,WAAW,EAAE,OAAO,CAAC;IACrB,wFAAwF;IACxF,oBAAoB,EAAE,OAAO,CAAC;IAC9B,uDAAuD;IACvD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iEAAiE;IACjE,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,yEAAyE;AACzE,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAQD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,YAAY,GAAE,MAA8B,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAKtG;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CACxC,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACxC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAUzB;AAED,iEAAiE;AACjE,MAAM,WAAW,mBAAmB;IAClC,0EAA0E;IAC1E,OAAO,EAAE,OAAO,CAAC;IACjB,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAC;CACd;AAyBD;;;;;;;;;GASG;AACH,wBAAgB,0BAA0B,CACxC,YAAY,GAAE,MAA8B,GAC3C,mBAAmB,CAWrB;AAED;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CACxC,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,YAAY,GAAE,MAA8B,GAC3C,oBAAoB,CAuBtB;AAED;;;;GAIG;AACH,wBAAgB,kCAAkC,CAChD,YAAY,GAAE,MAA8B,GAC3C,MAAM,CAOR"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync, renameSync, unlinkSync } from 'fs';
|
|
2
|
+
import { homedir } from 'os';
|
|
3
|
+
import { randomBytes } from 'crypto';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
/** The env var Claude Code reads to decide when to auto-background a long-running MCP tool call. */
|
|
6
|
+
export const AUTO_BACKGROUND_ENV_KEY = 'CLAUDE_CODE_MCP_AUTO_BACKGROUND_MS';
|
|
7
|
+
/** The value that disables auto-backgrounding, so a blocking HITL tool call is never yanked away before the human answers. */
|
|
8
|
+
export const AUTO_BACKGROUND_TARGET_VALUE = '0';
|
|
9
|
+
/** Locate the host Claude Code settings file: ~/.claude/settings.json */
|
|
10
|
+
export function getHostSettingsPath() {
|
|
11
|
+
return path.join(homedir(), '.claude', 'settings.json');
|
|
12
|
+
}
|
|
13
|
+
function asRecord(value) {
|
|
14
|
+
return value && typeof value === 'object' && !Array.isArray(value)
|
|
15
|
+
? value
|
|
16
|
+
: {};
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Read a Claude Code settings.json file. Returns an empty object when the
|
|
20
|
+
* file is missing or blank, so callers can merge into the result unconditionally.
|
|
21
|
+
* Malformed JSON is not swallowed — it throws, so a caller can surface a clear
|
|
22
|
+
* error instead of silently discarding a user's existing settings.
|
|
23
|
+
*/
|
|
24
|
+
export function readHostSettings(settingsPath = getHostSettingsPath()) {
|
|
25
|
+
if (!existsSync(settingsPath))
|
|
26
|
+
return {};
|
|
27
|
+
const raw = readFileSync(settingsPath, 'utf-8');
|
|
28
|
+
if (!raw.trim())
|
|
29
|
+
return {};
|
|
30
|
+
return JSON.parse(raw);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Merge the auto-background remediation value into an existing settings
|
|
34
|
+
* object, preserving every other top-level key and every other `env` entry.
|
|
35
|
+
* Pure function — never mutates its input. Applying it to its own output is
|
|
36
|
+
* idempotent (produces an equal object).
|
|
37
|
+
*/
|
|
38
|
+
export function mergeAutoBackgroundSetting(existingSettings) {
|
|
39
|
+
const existingEnv = asRecord(existingSettings.env);
|
|
40
|
+
return {
|
|
41
|
+
...existingSettings,
|
|
42
|
+
env: {
|
|
43
|
+
...existingEnv,
|
|
44
|
+
[AUTO_BACKGROUND_ENV_KEY]: AUTO_BACKGROUND_TARGET_VALUE,
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Write via a temp file in the same directory, then rename over the target,
|
|
50
|
+
* so a crash mid-write can never leave a partially-written settings.json.
|
|
51
|
+
* `renameSync` maps to MoveFileEx with MOVEFILE_REPLACE_EXISTING on Windows,
|
|
52
|
+
* so replacing an existing destination is atomic there too. The temp file is
|
|
53
|
+
* removed on failure so a full disk (or a failed rename) cannot leave debris
|
|
54
|
+
* behind.
|
|
55
|
+
*/
|
|
56
|
+
function writeAtomic(file, contents) {
|
|
57
|
+
const tmp = `${file}.${process.pid}.${randomBytes(6).toString('hex')}.tmp`;
|
|
58
|
+
try {
|
|
59
|
+
writeFileSync(tmp, contents, 'utf-8');
|
|
60
|
+
renameSync(tmp, file);
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
try {
|
|
64
|
+
unlinkSync(tmp);
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
/* nothing to clean up */
|
|
68
|
+
}
|
|
69
|
+
throw err;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Apply the auto-background remediation to disk: read the existing
|
|
74
|
+
* settings.json (if any), merge in the target env value via
|
|
75
|
+
* {@link mergeAutoBackgroundSetting}, and write the result back only if it
|
|
76
|
+
* actually changed. Re-running this after a prior successful run is a no-op
|
|
77
|
+
* (`updated: false`) rather than rewriting an identical file.
|
|
78
|
+
*
|
|
79
|
+
* The parent directory (e.g. ~/.claude) is created if missing. Writes are
|
|
80
|
+
* atomic — see {@link writeAtomic}.
|
|
81
|
+
*/
|
|
82
|
+
export function applyAutoBackgroundSetting(settingsPath = getHostSettingsPath()) {
|
|
83
|
+
const existing = readHostSettings(settingsPath);
|
|
84
|
+
const merged = mergeAutoBackgroundSetting(existing);
|
|
85
|
+
if (JSON.stringify(merged) === JSON.stringify(existing)) {
|
|
86
|
+
return { updated: false, path: settingsPath };
|
|
87
|
+
}
|
|
88
|
+
mkdirSync(path.dirname(settingsPath), { recursive: true });
|
|
89
|
+
writeAtomic(settingsPath, JSON.stringify(merged, null, 2) + '\n');
|
|
90
|
+
return { updated: true, path: settingsPath };
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Detect whether the auto-background guard is already in effect:
|
|
94
|
+
* - `activeInEnv`: the currently running process inherited it — in effect now.
|
|
95
|
+
* - `configuredForRestart`: ~/.claude/settings.json has it queued — takes
|
|
96
|
+
* effect the next time Claude Code restarts, not for the current session.
|
|
97
|
+
*
|
|
98
|
+
* Never throws: a missing or malformed settings.json is treated the same as
|
|
99
|
+
* "not configured", since this is a read-only diagnostic.
|
|
100
|
+
*/
|
|
101
|
+
export function detectAutoBackgroundStatus(env = process.env, settingsPath = getHostSettingsPath()) {
|
|
102
|
+
const envValue = env[AUTO_BACKGROUND_ENV_KEY];
|
|
103
|
+
const activeInEnv = envValue === AUTO_BACKGROUND_TARGET_VALUE;
|
|
104
|
+
let settings;
|
|
105
|
+
try {
|
|
106
|
+
settings = readHostSettings(settingsPath);
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
settings = {};
|
|
110
|
+
}
|
|
111
|
+
const settingsEnv = asRecord(settings.env);
|
|
112
|
+
const rawSettingsValue = settingsEnv[AUTO_BACKGROUND_ENV_KEY];
|
|
113
|
+
const settingsValue = typeof rawSettingsValue === 'string' ? rawSettingsValue : undefined;
|
|
114
|
+
const configuredForRestart = settingsValue === AUTO_BACKGROUND_TARGET_VALUE;
|
|
115
|
+
return {
|
|
116
|
+
active: activeInEnv || configuredForRestart,
|
|
117
|
+
activeInEnv,
|
|
118
|
+
configuredForRestart,
|
|
119
|
+
envValue,
|
|
120
|
+
settingsValue,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Build reusable, human-readable remediation text for when the auto-background
|
|
125
|
+
* guard is not yet active. Shared by the setup diagnostic step, and any future
|
|
126
|
+
* CLI/UX surface that needs to explain the same fix.
|
|
127
|
+
*/
|
|
128
|
+
export function buildAutoBackgroundRemediationText(settingsPath = getHostSettingsPath()) {
|
|
129
|
+
return [
|
|
130
|
+
`${AUTO_BACKGROUND_ENV_KEY} is not set to "${AUTO_BACKGROUND_TARGET_VALUE}", so Claude Code may auto-background a long-running HITL tool call before you get a chance to respond.`,
|
|
131
|
+
`Fix: merge the following into ${settingsPath} (preserve every other key):`,
|
|
132
|
+
` { "env": { "${AUTO_BACKGROUND_ENV_KEY}": "${AUTO_BACKGROUND_TARGET_VALUE}" } }`,
|
|
133
|
+
`Restart Claude Code afterward for the change to take effect.`,
|
|
134
|
+
].join('\n');
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=host-settings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host-settings.js","sourceRoot":"","sources":["../src/host-settings.ts"],"names":[],"mappings":"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"}
|