@achieveai/hitl-mcp-server 2.9.6 → 2.11.2

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.
Files changed (60) hide show
  1. package/dist/cli.d.ts +31 -1
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +133 -5
  4. package/dist/cli.js.map +1 -1
  5. package/dist/config.d.ts.map +1 -1
  6. package/dist/config.js +2 -0
  7. package/dist/config.js.map +1 -1
  8. package/dist/git-context.d.ts +53 -2
  9. package/dist/git-context.d.ts.map +1 -1
  10. package/dist/git-context.js +118 -18
  11. package/dist/git-context.js.map +1 -1
  12. package/dist/host-settings.d.ts +68 -0
  13. package/dist/host-settings.d.ts.map +1 -0
  14. package/dist/host-settings.js +136 -0
  15. package/dist/host-settings.js.map +1 -0
  16. package/dist/identity.d.ts +20 -0
  17. package/dist/identity.d.ts.map +1 -0
  18. package/dist/identity.js +35 -0
  19. package/dist/identity.js.map +1 -0
  20. package/dist/mcp-server.d.ts +65 -1
  21. package/dist/mcp-server.d.ts.map +1 -1
  22. package/dist/mcp-server.js +446 -65
  23. package/dist/mcp-server.js.map +1 -1
  24. package/dist/ntfy-transport.d.ts +293 -13
  25. package/dist/ntfy-transport.d.ts.map +1 -1
  26. package/dist/ntfy-transport.js +765 -88
  27. package/dist/ntfy-transport.js.map +1 -1
  28. package/dist/payload.d.ts +80 -0
  29. package/dist/payload.d.ts.map +1 -0
  30. package/dist/payload.js +135 -0
  31. package/dist/payload.js.map +1 -0
  32. package/dist/plan-diff.d.ts +29 -0
  33. package/dist/plan-diff.d.ts.map +1 -0
  34. package/dist/plan-diff.js +138 -0
  35. package/dist/plan-diff.js.map +1 -0
  36. package/dist/plan-file.d.ts +24 -0
  37. package/dist/plan-file.d.ts.map +1 -0
  38. package/dist/plan-file.js +98 -0
  39. package/dist/plan-file.js.map +1 -0
  40. package/dist/plan-review.d.ts +54 -0
  41. package/dist/plan-review.d.ts.map +1 -0
  42. package/dist/plan-review.js +110 -0
  43. package/dist/plan-review.js.map +1 -0
  44. package/dist/setup.d.ts +22 -5
  45. package/dist/setup.d.ts.map +1 -1
  46. package/dist/setup.js +52 -15
  47. package/dist/setup.js.map +1 -1
  48. package/dist/snapshot-store.d.ts +104 -0
  49. package/dist/snapshot-store.d.ts.map +1 -0
  50. package/dist/snapshot-store.js +209 -0
  51. package/dist/snapshot-store.js.map +1 -0
  52. package/dist/types.d.ts +144 -1
  53. package/dist/types.d.ts.map +1 -1
  54. package/dist/types.js +2 -0
  55. package/dist/types.js.map +1 -1
  56. package/dist/version.d.ts +13 -0
  57. package/dist/version.d.ts.map +1 -0
  58. package/dist/version.js +15 -0
  59. package/dist/version.js.map +1 -0
  60. package/package.json +64 -61
@@ -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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"}
@@ -0,0 +1,20 @@
1
+ import type { SenderIdentity } from './types.js';
2
+ /** Resolves a human-readable session name, or null when none is available. */
3
+ export type SessionNameResolver = () => string | null;
4
+ /**
5
+ * No documented Claude Code env var exposes a human-readable session name
6
+ * today — only a UUID. This seam lets a real resolver replace this default
7
+ * without touching call sites.
8
+ */
9
+ export declare const defaultSessionNameResolver: SessionNameResolver;
10
+ /**
11
+ * Resolve a display-ready sender identity for an outgoing message, in
12
+ * precedence order: session name override > linked-worktree branch > path
13
+ * fallback.
14
+ *
15
+ * Purely a function of its arguments — never reads `process.cwd()` or
16
+ * `os.hostname()` itself, so callers control (and tests can mock) both `cwd`
17
+ * and `deviceName`; per-tool cwd rules live at each call site.
18
+ */
19
+ export declare function resolveSenderIdentity(cwd: string, deviceName: string, sessionResolver?: SessionNameResolver): SenderIdentity;
20
+ //# sourceMappingURL=identity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../src/identity.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,8EAA8E;AAC9E,MAAM,MAAM,mBAAmB,GAAG,MAAM,MAAM,GAAG,IAAI,CAAC;AAEtD;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,EAAE,mBAAgC,CAAC;AAQ1E;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,MAAM,EAClB,eAAe,GAAE,mBAAgD,GAChE,cAAc,CAYhB"}
@@ -0,0 +1,35 @@
1
+ import { detectRepoContext, isLinkedWorktree } from './git-context.js';
2
+ /**
3
+ * No documented Claude Code env var exposes a human-readable session name
4
+ * today — only a UUID. This seam lets a real resolver replace this default
5
+ * without touching call sites.
6
+ */
7
+ export const defaultSessionNameResolver = () => null;
8
+ /** Last two `/`-joined path segments of `cwd`, tolerating either path separator. Never absolute (F-9). */
9
+ function lastTwoSegments(cwd) {
10
+ const segments = cwd.split(/[\\/]/).filter(Boolean);
11
+ return segments.slice(-2).join('/');
12
+ }
13
+ /**
14
+ * Resolve a display-ready sender identity for an outgoing message, in
15
+ * precedence order: session name override > linked-worktree branch > path
16
+ * fallback.
17
+ *
18
+ * Purely a function of its arguments — never reads `process.cwd()` or
19
+ * `os.hostname()` itself, so callers control (and tests can mock) both `cwd`
20
+ * and `deviceName`; per-tool cwd rules live at each call site.
21
+ */
22
+ export function resolveSenderIdentity(cwd, deviceName, sessionResolver = defaultSessionNameResolver) {
23
+ const sessionName = sessionResolver();
24
+ if (sessionName !== null)
25
+ return { label: sessionName, source: 'session' };
26
+ if (isLinkedWorktree(cwd)) {
27
+ const branch = detectRepoContext(cwd)?.branch;
28
+ if (branch)
29
+ return { label: `${deviceName} - ${branch}`, source: 'worktree' };
30
+ // isLinkedWorktree true but no branch (race/edge case) — fall through rather
31
+ // than emit a malformed label.
32
+ }
33
+ return { label: `${deviceName} ${lastTwoSegments(cwd)}`, source: 'path' };
34
+ }
35
+ //# sourceMappingURL=identity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity.js","sourceRoot":"","sources":["../src/identity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAMvE;;;;GAIG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAwB,GAAG,EAAE,CAAC,IAAI,CAAC;AAE1E,0GAA0G;AAC1G,SAAS,eAAe,CAAC,GAAW;IAClC,MAAM,QAAQ,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACpD,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACtC,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,qBAAqB,CACnC,GAAW,EACX,UAAkB,EAClB,kBAAuC,0BAA0B;IAEjE,MAAM,WAAW,GAAG,eAAe,EAAE,CAAC;IACtC,IAAI,WAAW,KAAK,IAAI;QAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IAE3E,IAAI,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1B,MAAM,MAAM,GAAG,iBAAiB,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAC9C,IAAI,MAAM;YAAE,OAAO,EAAE,KAAK,EAAE,GAAG,UAAU,MAAM,MAAM,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;QAC9E,6EAA6E;QAC7E,+BAA+B;IACjC,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,GAAG,UAAU,IAAI,eAAe,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAC5E,CAAC"}
@@ -1,3 +1,67 @@
1
1
  #!/usr/bin/env node
2
- export {};
2
+ import type { HitlConfig } from './types.js';
3
+ export declare class HumanInTheLoopServer {
4
+ private server;
5
+ private transport;
6
+ private config;
7
+ /** reviewIds still waiting on a human, so a graceful exit can release them (D-3). */
8
+ private outstandingReviews;
9
+ /** `config` is injectable so a test can construct a server without a real ~/.hitl. */
10
+ constructor(config?: HitlConfig);
11
+ private setupHandlers;
12
+ /**
13
+ * ReviewPlan: snapshot a markdown plan, publish it for line-anchored review,
14
+ * and block until a human submits a verdict.
15
+ */
16
+ private handleReviewPlan;
17
+ /**
18
+ * Drop a subscription hold after the late-response window.
19
+ *
20
+ * The timer is unref'd so it can never be the reason the process stays alive.
21
+ */
22
+ private releaseLater;
23
+ /**
24
+ * Download, decode and validate a submitted review, then acknowledge it.
25
+ *
26
+ * The ack is what lets the client distinguish "the server read this" from "I
27
+ * clicked submit": the response attachment expires after 3 h while the
28
+ * message itself survives 12 h, so a submit can be accepted at click time and
29
+ * still never arrive (C-12).
30
+ */
31
+ private consumeReviewResponse;
32
+ private downloadResponseBody;
33
+ /**
34
+ * Publish the sender's own identity as a companion to a question or
35
+ * notification just published, unless the operator opted out.
36
+ *
37
+ * Shared by AskUserQuestion and Notify — both resolve identity from
38
+ * `process.cwd()` (ReviewPlan resolves from the plan's own directory
39
+ * instead, so it is not part of this shared path). Decoration only: never
40
+ * lets a publish failure escape past the tool call it decorates, matching
41
+ * `publishAck`'s log-and-continue pattern below.
42
+ */
43
+ private publishSenderIdentityFor;
44
+ /** Tell the client whether its submission actually landed. */
45
+ private publishAck;
46
+ /**
47
+ * Fail before publishing when no client can be found or launched.
48
+ *
49
+ * Without a timeout to bound it, publishing to a topic nobody is subscribed
50
+ * to is a permanent silent hang — the agent blocks and the human never sees a
51
+ * window to explain why (A-10).
52
+ */
53
+ private requireClient;
54
+ /**
55
+ * Start emitting progress notifications, returning the stop function.
56
+ *
57
+ * Whether these actually keep the call alive is the calling host's decision:
58
+ * the MCP SDK's DEFAULT_REQUEST_TIMEOUT_MSEC is 60 s and
59
+ * `resetTimeoutOnProgress` defaults to false, so a host that does not opt in
60
+ * will time the call out regardless of what we send (D-2).
61
+ */
62
+ private startHeartbeat;
63
+ run(): Promise<void>;
64
+ /** Publish cancel_review for every review still waiting on a human. */
65
+ private cancelOutstandingReviews;
66
+ }
3
67
  //# sourceMappingURL=mcp-server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-server.d.ts","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"mcp-server.d.ts","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":";AAcA,OAAO,KAAK,EAaV,UAAU,EAGX,MAAM,YAAY,CAAC;AAuDpB,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAAgB;IACjC,OAAO,CAAC,MAAM,CAAa;IAC3B,qFAAqF;IACrF,OAAO,CAAC,kBAAkB,CAAqB;IAE/C,sFAAsF;gBAC1E,MAAM,GAAE,UAAyB;IAY7C,OAAO,CAAC,aAAa;IA+brB;;;OAGG;YACW,gBAAgB;IAmK9B;;;;OAIG;IACH,OAAO,CAAC,YAAY;IAIpB;;;;;;;OAOG;YACW,qBAAqB;YAiErB,oBAAoB;IAUlC;;;;;;;;;OASG;YACW,wBAAwB;IAmBtC,8DAA8D;YAChD,UAAU;IAuBxB;;;;;;OAMG;IACH,OAAO,CAAC,aAAa;IAUrB;;;;;;;OAOG;IACH,OAAO,CAAC,cAAc;IAyBhB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IA0B1B,uEAAuE;YACzD,wBAAwB;CAkBvC"}