holistic 0.2.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.
Files changed (66) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/CONTRIBUTING.md +121 -0
  3. package/LICENSE +21 -0
  4. package/README.md +329 -0
  5. package/bin/holistic +17 -0
  6. package/bin/holistic.cmd +23 -0
  7. package/bin/holistic.js +59 -0
  8. package/dist/__tests__/mcp-notification.test.d.ts +5 -0
  9. package/dist/__tests__/mcp-notification.test.d.ts.map +1 -0
  10. package/dist/__tests__/mcp-notification.test.js +255 -0
  11. package/dist/__tests__/mcp-notification.test.js.map +1 -0
  12. package/dist/cli.d.ts +6 -0
  13. package/dist/cli.d.ts.map +1 -0
  14. package/dist/cli.js +637 -0
  15. package/dist/cli.js.map +1 -0
  16. package/dist/core/docs.d.ts +3 -0
  17. package/dist/core/docs.d.ts.map +1 -0
  18. package/dist/core/docs.js +602 -0
  19. package/dist/core/docs.js.map +1 -0
  20. package/dist/core/git-hooks.d.ts +17 -0
  21. package/dist/core/git-hooks.d.ts.map +1 -0
  22. package/dist/core/git-hooks.js +144 -0
  23. package/dist/core/git-hooks.js.map +1 -0
  24. package/dist/core/git.d.ts +12 -0
  25. package/dist/core/git.d.ts.map +1 -0
  26. package/dist/core/git.js +121 -0
  27. package/dist/core/git.js.map +1 -0
  28. package/dist/core/lock.d.ts +2 -0
  29. package/dist/core/lock.d.ts.map +1 -0
  30. package/dist/core/lock.js +40 -0
  31. package/dist/core/lock.js.map +1 -0
  32. package/dist/core/redact.d.ts +3 -0
  33. package/dist/core/redact.d.ts.map +1 -0
  34. package/dist/core/redact.js +13 -0
  35. package/dist/core/redact.js.map +1 -0
  36. package/dist/core/setup.d.ts +35 -0
  37. package/dist/core/setup.d.ts.map +1 -0
  38. package/dist/core/setup.js +654 -0
  39. package/dist/core/setup.js.map +1 -0
  40. package/dist/core/splash.d.ts +9 -0
  41. package/dist/core/splash.d.ts.map +1 -0
  42. package/dist/core/splash.js +35 -0
  43. package/dist/core/splash.js.map +1 -0
  44. package/dist/core/state.d.ts +42 -0
  45. package/dist/core/state.d.ts.map +1 -0
  46. package/dist/core/state.js +744 -0
  47. package/dist/core/state.js.map +1 -0
  48. package/dist/core/sync.d.ts +12 -0
  49. package/dist/core/sync.d.ts.map +1 -0
  50. package/dist/core/sync.js +106 -0
  51. package/dist/core/sync.js.map +1 -0
  52. package/dist/core/types.d.ts +210 -0
  53. package/dist/core/types.d.ts.map +1 -0
  54. package/dist/core/types.js +2 -0
  55. package/dist/core/types.js.map +1 -0
  56. package/dist/daemon.d.ts +7 -0
  57. package/dist/daemon.d.ts.map +1 -0
  58. package/dist/daemon.js +242 -0
  59. package/dist/daemon.js.map +1 -0
  60. package/dist/mcp-server.d.ts +11 -0
  61. package/dist/mcp-server.d.ts.map +1 -0
  62. package/dist/mcp-server.js +266 -0
  63. package/dist/mcp-server.js.map +1 -0
  64. package/docs/handoff-walkthrough.md +119 -0
  65. package/docs/structured-metadata.md +341 -0
  66. package/package.json +67 -0
package/dist/daemon.js ADDED
@@ -0,0 +1,242 @@
1
+ import { pathToFileURL } from "node:url";
2
+ import { captureRepoSnapshot, getGitSnapshot, isPortableHolisticPath } from './core/git.js';
3
+ import { writeDerivedDocs } from './core/docs.js';
4
+ import { requestAutoSync } from './core/sync.js';
5
+ import { buildAutoDraftHandoff, checkpointState, getRuntimePaths, loadState, readDraftHandoff, saveState, shouldAutoDraftHandoff, startNewSession, withStateLock, writeDraftHandoff, } from './core/state.js';
6
+ function parseArgs(argv) {
7
+ const flags = {};
8
+ for (let index = 0; index < argv.length; index += 1) {
9
+ const token = argv[index];
10
+ if (!token.startsWith("--")) {
11
+ continue;
12
+ }
13
+ const flag = token.slice(2);
14
+ const next = argv[index + 1];
15
+ if (!next || next.startsWith("--")) {
16
+ flags[flag] = ["true"];
17
+ continue;
18
+ }
19
+ flags[flag] ??= [];
20
+ flags[flag].push(next);
21
+ index += 1;
22
+ }
23
+ return { flags };
24
+ }
25
+ function firstFlag(flags, name, fallback = "") {
26
+ return flags[name]?.[0] ?? fallback;
27
+ }
28
+ function asAgent(value) {
29
+ if (value === "codex" || value === "claude" || value === "antigravity" || value === "gemini" || value === "copilot" || value === "cursor" || value === "goose" || value === "gsd") {
30
+ return value;
31
+ }
32
+ return "unknown";
33
+ }
34
+ const QUIET_TICKS_BEFORE_CHECKPOINT = 1;
35
+ function now() {
36
+ return new Date().toISOString();
37
+ }
38
+ function defaultPassiveCapture() {
39
+ return {
40
+ lastObservedBranch: null,
41
+ pendingFiles: [],
42
+ activityTicks: 0,
43
+ quietTicks: 0,
44
+ lastCheckpointAt: null,
45
+ };
46
+ }
47
+ function uniqueFiles(files) {
48
+ return [...new Set(files)].sort();
49
+ }
50
+ function summarizeFiles(files) {
51
+ return files.slice(0, 3).join(", ");
52
+ }
53
+ function isSameDraft(left, right) {
54
+ if (!left || !right) {
55
+ return false;
56
+ }
57
+ return left.sourceSessionId === right.sourceSessionId
58
+ && left.sourceSessionUpdatedAt === right.sourceSessionUpdatedAt
59
+ && left.reason === right.reason;
60
+ }
61
+ function persistLocked(rootDir, state, paths) {
62
+ writeDerivedDocs(paths, state);
63
+ state.repoSnapshot = captureRepoSnapshot(rootDir);
64
+ saveState(paths, state, { locked: true });
65
+ return state;
66
+ }
67
+ function persistObservedState(state, paths, snapshot) {
68
+ state.repoSnapshot = snapshot;
69
+ saveState(paths, state, { locked: true });
70
+ return state;
71
+ }
72
+ function ensurePassiveSession(rootDir, state, agent) {
73
+ if (state.activeSession) {
74
+ return state;
75
+ }
76
+ return startNewSession(rootDir, state, agent, "Passively capture repo activity for the next agent handoff", [
77
+ "Read HOLISTIC.md",
78
+ "Review the detected repo activity",
79
+ "Confirm whether to continue planned work or start something new",
80
+ ], "Passive session capture");
81
+ }
82
+ export function runDaemonTick(rootDir, agent = "unknown") {
83
+ const paths = getRuntimePaths(rootDir);
84
+ const result = withStateLock(paths, () => {
85
+ const { state, paths: lockedPaths } = loadState(rootDir);
86
+ const snapshot = getGitSnapshot(rootDir, state.repoSnapshot ?? {});
87
+ const tracker = {
88
+ ...defaultPassiveCapture(),
89
+ ...(state.passiveCapture ?? {}),
90
+ pendingFiles: state.passiveCapture?.pendingFiles ?? [],
91
+ };
92
+ const meaningfulFiles = snapshot.changedFiles.filter((file) => !isPortableHolisticPath(file));
93
+ const previousBranch = tracker.lastObservedBranch;
94
+ const branchChanged = Boolean(previousBranch && previousBranch !== snapshot.branch);
95
+ if (branchChanged) {
96
+ let nextState = ensurePassiveSession(rootDir, state, agent);
97
+ nextState = checkpointState(rootDir, nextState, {
98
+ agent,
99
+ reason: "branch-switch",
100
+ status: `Detected a branch switch from ${previousBranch} to ${snapshot.branch}; Holistic captured a continuity checkpoint automatically.`,
101
+ next: nextState.activeSession?.nextSteps.length
102
+ ? nextState.activeSession.nextSteps
103
+ : ["Review the new branch and confirm the intended task."],
104
+ impacts: ["Holistic now records branch switches as explicit continuity checkpoints."],
105
+ regressions: ["Branch changes should create a single checkpoint instead of repeated polling noise."],
106
+ });
107
+ nextState.passiveCapture = {
108
+ ...defaultPassiveCapture(),
109
+ lastObservedBranch: snapshot.branch,
110
+ lastCheckpointAt: now(),
111
+ };
112
+ persistLocked(rootDir, nextState, lockedPaths);
113
+ return {
114
+ changed: true,
115
+ summary: `Captured branch switch from ${previousBranch} to ${snapshot.branch}.`,
116
+ syncTrigger: "checkpoint",
117
+ };
118
+ }
119
+ if (meaningfulFiles.length > 0) {
120
+ const nextState = {
121
+ ...state,
122
+ passiveCapture: {
123
+ ...tracker,
124
+ lastObservedBranch: snapshot.branch,
125
+ pendingFiles: uniqueFiles([...tracker.pendingFiles, ...meaningfulFiles]),
126
+ activityTicks: tracker.activityTicks + 1,
127
+ quietTicks: 0,
128
+ },
129
+ };
130
+ persistObservedState(nextState, lockedPaths, snapshot.snapshot);
131
+ return {
132
+ changed: false,
133
+ summary: `Buffered ${nextState.passiveCapture?.pendingFiles.length ?? 0} changed file(s) for a quieter passive checkpoint.`,
134
+ };
135
+ }
136
+ if (tracker.pendingFiles.length > 0) {
137
+ const quietTicks = tracker.quietTicks + 1;
138
+ if (quietTicks >= QUIET_TICKS_BEFORE_CHECKPOINT) {
139
+ let nextState = ensurePassiveSession(rootDir, state, agent);
140
+ const fileSummary = summarizeFiles(tracker.pendingFiles);
141
+ nextState = checkpointState(rootDir, nextState, {
142
+ agent,
143
+ reason: tracker.activityTicks > 1 || tracker.pendingFiles.length > 1 ? "daemon-auto-cluster" : "daemon-auto",
144
+ status: `Detected a quiet point after repo activity on ${snapshot.branch}; Holistic captured ${tracker.pendingFiles.length} file(s) automatically.`,
145
+ next: nextState.activeSession?.nextSteps.length
146
+ ? nextState.activeSession.nextSteps
147
+ : [`Review recent changes in ${fileSummary || "the repo"} and confirm the intended task.`],
148
+ impacts: ["Passive capture now clusters nearby repo changes before checkpointing, which reduces noise while preserving continuity."],
149
+ regressions: ["Passive checkpoints should cluster nearby edits instead of firing on every poll tick."],
150
+ });
151
+ nextState.passiveCapture = {
152
+ ...defaultPassiveCapture(),
153
+ lastObservedBranch: snapshot.branch,
154
+ lastCheckpointAt: now(),
155
+ };
156
+ persistLocked(rootDir, nextState, lockedPaths);
157
+ return {
158
+ changed: true,
159
+ summary: `Captured a passive checkpoint for ${tracker.pendingFiles.length} file(s) on ${snapshot.branch}.`,
160
+ syncTrigger: "checkpoint",
161
+ };
162
+ }
163
+ const nextState = {
164
+ ...state,
165
+ passiveCapture: {
166
+ ...tracker,
167
+ lastObservedBranch: snapshot.branch,
168
+ quietTicks,
169
+ },
170
+ };
171
+ persistObservedState(nextState, lockedPaths, snapshot.snapshot);
172
+ return { changed: false, summary: "Waiting for repo activity to settle before checkpointing." };
173
+ }
174
+ if (tracker.lastObservedBranch !== snapshot.branch || Object.keys(state.repoSnapshot ?? {}).length === 0) {
175
+ const nextState = {
176
+ ...state,
177
+ passiveCapture: {
178
+ ...tracker,
179
+ lastObservedBranch: snapshot.branch,
180
+ },
181
+ };
182
+ persistObservedState(nextState, lockedPaths, snapshot.snapshot);
183
+ }
184
+ if (state.activeSession) {
185
+ const decision = shouldAutoDraftHandoff(state.activeSession);
186
+ if (decision.should) {
187
+ const nextDraft = buildAutoDraftHandoff(state, decision.reason);
188
+ const existingDraft = readDraftHandoff(lockedPaths);
189
+ if (nextDraft && !isSameDraft(existingDraft, nextDraft)) {
190
+ writeDraftHandoff(lockedPaths, nextDraft);
191
+ return {
192
+ changed: true,
193
+ summary: `Saved an auto-drafted handoff for ${decision.reason}.`,
194
+ };
195
+ }
196
+ }
197
+ }
198
+ return { changed: false, summary: "No repo changes detected." };
199
+ });
200
+ if (result.syncTrigger) {
201
+ requestAutoSync(rootDir, result.syncTrigger);
202
+ }
203
+ return result;
204
+ }
205
+ async function main() {
206
+ const parsed = parseArgs(process.argv.slice(2));
207
+ const rootDir = process.cwd();
208
+ const intervalSeconds = Number.parseInt(firstFlag(parsed.flags, "interval", "30"), 10);
209
+ const runOnce = firstFlag(parsed.flags, "once") === "true";
210
+ const agent = asAgent(firstFlag(parsed.flags, "agent", "unknown"));
211
+ const tick = () => {
212
+ const result = runDaemonTick(rootDir, agent);
213
+ if (result.changed) {
214
+ process.stdout.write(`${new Date().toISOString()} ${result.summary}\n`);
215
+ }
216
+ };
217
+ tick();
218
+ if (runOnce) {
219
+ return 0;
220
+ }
221
+ process.stdout.write(`Holistic daemon watching ${rootDir} every ${intervalSeconds}s.\n`);
222
+ const timer = setInterval(tick, intervalSeconds * 1000);
223
+ const stop = () => {
224
+ clearInterval(timer);
225
+ process.stdout.write("Holistic daemon stopped.\n");
226
+ process.exit(0);
227
+ };
228
+ process.on("SIGINT", stop);
229
+ process.on("SIGTERM", stop);
230
+ return await new Promise(() => undefined);
231
+ }
232
+ const isEntrypoint = process.argv[1] ? pathToFileURL(process.argv[1]).href === import.meta.url : false;
233
+ if (isEntrypoint) {
234
+ main().then((code) => {
235
+ process.exit(code);
236
+ }).catch((error) => {
237
+ const message = error instanceof Error ? error.stack || error.message : String(error);
238
+ process.stderr.write(`${message}\n`);
239
+ process.exit(1);
240
+ });
241
+ }
242
+ //# sourceMappingURL=daemon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon.js","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
2
+ import { type CallToolResult, type ListToolsResult } from "@modelcontextprotocol/sdk/types.js";
3
+ import type { AgentName, HolisticState } from './core/types.js';
4
+ export declare function buildResumeNotificationText(state: HolisticState, agent?: AgentName): string | null;
5
+ export declare function sendResumeNotification(server: Server, rootDir: string, agent?: AgentName): Promise<boolean>;
6
+ export declare function listHolisticTools(): ListToolsResult;
7
+ export declare function callHolisticTool(rootDir: string, name: string, args?: Record<string, unknown>): CallToolResult;
8
+ export declare function createHolisticMcpServer(rootDir: string): Server;
9
+ export declare function waitForStdioShutdown(stdin?: Pick<NodeJS.ReadStream, "once" | "resume">): Promise<void>;
10
+ export declare function runMcpServer(rootDir: string): Promise<void>;
11
+ //# sourceMappingURL=mcp-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-server.d.ts","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAEnE,OAAO,EAAiD,KAAK,cAAc,EAAE,KAAK,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAkB9I,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAgB,MAAM,iBAAiB,CAAC;AAiE9E,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,aAAa,EAAE,KAAK,GAAE,SAA6B,GAAG,MAAM,GAAG,IAAI,CAQrH;AAED,wBAAsB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,GAAE,SAA6B,GAAG,OAAO,CAAC,OAAO,CAAC,CAgBpI;AAED,wBAAgB,iBAAiB,IAAI,eAAe,CAmEnD;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,cAAc,CA8E9G;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CA8B/D;AAED,wBAAsB,oBAAoB,CAAC,KAAK,GAAE,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,QAAQ,CAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAO3H;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAUjE"}
@@ -0,0 +1,266 @@
1
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
2
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
4
+ import { pathToFileURL } from "node:url";
5
+ import { captureRepoSnapshot } from './core/git.js';
6
+ import { writeDerivedDocs } from './core/docs.js';
7
+ import { refreshHolisticHooks } from './core/setup.js';
8
+ import { requestAutoSync } from './core/sync.js';
9
+ import { applyHandoff, buildStartupGreeting, canInferSessionStart, checkpointState, continueFromLatest, getRuntimePaths, loadState, saveState, withStateLock, } from './core/state.js';
10
+ const DEFAULT_MCP_AGENT = "claude";
11
+ function asAgent(value, fallback = "unknown") {
12
+ const validAgents = [
13
+ "codex",
14
+ "claude",
15
+ "antigravity",
16
+ "gemini",
17
+ "copilot",
18
+ "cursor",
19
+ "goose",
20
+ "gsd",
21
+ ];
22
+ if (typeof value === "string" && validAgents.includes(value)) {
23
+ return value;
24
+ }
25
+ return fallback;
26
+ }
27
+ function textResult(text, isError = false) {
28
+ return {
29
+ content: [
30
+ {
31
+ type: "text",
32
+ text,
33
+ },
34
+ ],
35
+ isError,
36
+ };
37
+ }
38
+ function persistLocked(rootDir, state, paths) {
39
+ writeDerivedDocs(paths, state);
40
+ state.repoSnapshot = captureRepoSnapshot(rootDir);
41
+ saveState(paths, state, { locked: true });
42
+ return state;
43
+ }
44
+ function mutateState(rootDir, mutator) {
45
+ const paths = getRuntimePaths(rootDir);
46
+ return withStateLock(paths, () => {
47
+ const { state, paths: lockedPaths } = loadState(rootDir);
48
+ const nextState = mutator(state, lockedPaths);
49
+ return persistLocked(rootDir, nextState, lockedPaths);
50
+ });
51
+ }
52
+ function ensureMcpResumeState(rootDir, agent = DEFAULT_MCP_AGENT) {
53
+ const { state } = loadState(rootDir);
54
+ if (state.activeSession) {
55
+ return state;
56
+ }
57
+ if (!canInferSessionStart(rootDir, state)) {
58
+ return state;
59
+ }
60
+ return mutateState(rootDir, (currentState) => continueFromLatest(rootDir, currentState, agent));
61
+ }
62
+ export function buildResumeNotificationText(state, agent = DEFAULT_MCP_AGENT) {
63
+ const greeting = buildStartupGreeting(state, agent);
64
+ if (!greeting) {
65
+ return null;
66
+ }
67
+ return `${greeting}\n\nUse holistic_resume tool for an explicit refresh.`;
68
+ }
69
+ export async function sendResumeNotification(server, rootDir, agent = DEFAULT_MCP_AGENT) {
70
+ const state = ensureMcpResumeState(rootDir, agent);
71
+ const text = buildResumeNotificationText(state, agent);
72
+ if (!text) {
73
+ return false;
74
+ }
75
+ await server.sendLoggingMessage({
76
+ level: "info",
77
+ logger: "holistic",
78
+ data: text,
79
+ });
80
+ return true;
81
+ }
82
+ export function listHolisticTools() {
83
+ return {
84
+ tools: [
85
+ {
86
+ name: "holistic_resume",
87
+ description: "🎯 Resume Holistic session and get full project context. Call this FIRST at conversation start to load: current objective, recent work, regression watch, and next steps. Essential for maintaining continuity across sessions.",
88
+ inputSchema: {
89
+ type: "object",
90
+ properties: {
91
+ agent: {
92
+ type: "string",
93
+ enum: ["codex", "claude", "antigravity", "gemini", "copilot", "cursor", "goose", "gsd"],
94
+ description: "Agent name for context retrieval (optional, defaults to claude)",
95
+ },
96
+ continue: {
97
+ type: "boolean",
98
+ description: "Auto-infer and start a session from recent work if none exists (optional)",
99
+ },
100
+ },
101
+ },
102
+ },
103
+ {
104
+ name: "holistic_slash",
105
+ description: "Lightweight startup command: load Holistic context and get project recap. Equivalent to typing '/holistic' - use this at conversation start for quick context refresh.",
106
+ inputSchema: {
107
+ type: "object",
108
+ properties: {
109
+ agent: {
110
+ type: "string",
111
+ enum: ["codex", "claude", "antigravity", "gemini", "copilot", "cursor", "goose", "gsd"],
112
+ description: "Agent name (optional, defaults to claude)",
113
+ },
114
+ },
115
+ },
116
+ },
117
+ {
118
+ name: "holistic_checkpoint",
119
+ description: "Create a Holistic checkpoint for the current work.",
120
+ inputSchema: {
121
+ type: "object",
122
+ properties: {
123
+ reason: { type: "string" },
124
+ status: { type: "string" },
125
+ done: { type: "array", items: { type: "string" } },
126
+ next: { type: "array", items: { type: "string" } },
127
+ impacts: { type: "array", items: { type: "string" } },
128
+ regressions: { type: "array", items: { type: "string" } },
129
+ },
130
+ required: ["reason"],
131
+ },
132
+ },
133
+ {
134
+ name: "holistic_handoff",
135
+ description: "Finalize the current Holistic session and prepare a handoff.",
136
+ inputSchema: {
137
+ type: "object",
138
+ properties: {
139
+ summary: { type: "string" },
140
+ done: { type: "array", items: { type: "string" } },
141
+ next: { type: "array", items: { type: "string" } },
142
+ impacts: { type: "array", items: { type: "string" } },
143
+ regressions: { type: "array", items: { type: "string" } },
144
+ },
145
+ },
146
+ },
147
+ ],
148
+ };
149
+ }
150
+ export function callHolisticTool(rootDir, name, args) {
151
+ switch (name) {
152
+ case "holistic_resume": {
153
+ const agent = asAgent(args?.agent, DEFAULT_MCP_AGENT);
154
+ const shouldContinue = args?.continue === true;
155
+ const state = shouldContinue
156
+ ? mutateState(rootDir, (currentState) => continueFromLatest(rootDir, currentState, agent))
157
+ : loadState(rootDir).state;
158
+ const greeting = buildStartupGreeting(state, agent);
159
+ if (!greeting) {
160
+ return textResult("No active Holistic session or pending work found. Use holistic_resume with continue:true to infer a session from recent work.");
161
+ }
162
+ return textResult(greeting);
163
+ }
164
+ case "holistic_slash": {
165
+ const agent = asAgent(args?.agent, DEFAULT_MCP_AGENT);
166
+ const state = mutateState(rootDir, (currentState) => {
167
+ if (!currentState.activeSession && canInferSessionStart(rootDir, currentState)) {
168
+ return continueFromLatest(rootDir, currentState, agent);
169
+ }
170
+ return currentState;
171
+ });
172
+ const greeting = buildStartupGreeting(state, agent);
173
+ if (!greeting) {
174
+ return textResult("No active Holistic session or pending work found in this repo yet.");
175
+ }
176
+ return textResult(greeting);
177
+ }
178
+ case "holistic_checkpoint": {
179
+ const reason = typeof args?.reason === "string" ? args.reason : "";
180
+ if (!reason) {
181
+ return textResult("Checkpoint failed: reason is required.", true);
182
+ }
183
+ const state = mutateState(rootDir, (currentState) => checkpointState(rootDir, currentState, {
184
+ agent: asAgent(args?.agent, DEFAULT_MCP_AGENT),
185
+ reason,
186
+ status: typeof args?.status === "string" ? args.status : undefined,
187
+ done: Array.isArray(args?.done) ? args.done.filter((item) => typeof item === "string") : undefined,
188
+ next: Array.isArray(args?.next) ? args.next.filter((item) => typeof item === "string") : undefined,
189
+ impacts: Array.isArray(args?.impacts) ? args.impacts.filter((item) => typeof item === "string") : undefined,
190
+ regressions: Array.isArray(args?.regressions) ? args.regressions.filter((item) => typeof item === "string") : undefined,
191
+ }));
192
+ requestAutoSync(rootDir, "checkpoint");
193
+ return textResult(`Checkpoint created: ${state.activeSession?.checkpointCount ?? 0} total checkpoints.`);
194
+ }
195
+ case "holistic_handoff": {
196
+ const { state } = loadState(rootDir);
197
+ if (!state.activeSession) {
198
+ return textResult("Handoff failed: no active session to hand off.", true);
199
+ }
200
+ const nextState = mutateState(rootDir, (currentState) => applyHandoff(rootDir, currentState, {
201
+ summary: typeof args?.summary === "string" ? args.summary : undefined,
202
+ done: Array.isArray(args?.done) ? args.done.filter((item) => typeof item === "string") : undefined,
203
+ next: Array.isArray(args?.next) ? args.next.filter((item) => typeof item === "string") : undefined,
204
+ impacts: Array.isArray(args?.impacts) ? args.impacts.filter((item) => typeof item === "string") : undefined,
205
+ regressions: Array.isArray(args?.regressions) ? args.regressions.filter((item) => typeof item === "string") : undefined,
206
+ }));
207
+ requestAutoSync(rootDir, "handoff");
208
+ return textResult(`Handoff complete. Summary: ${nextState.lastHandoff?.summary ?? "n/a"}`);
209
+ }
210
+ default:
211
+ return textResult(`Unknown Holistic MCP tool: ${name}`, true);
212
+ }
213
+ }
214
+ export function createHolisticMcpServer(rootDir) {
215
+ const server = new Server({
216
+ name: "holistic",
217
+ version: "0.1.0",
218
+ }, {
219
+ capabilities: {
220
+ tools: {},
221
+ },
222
+ });
223
+ server.oninitialized = () => {
224
+ void sendResumeNotification(server, rootDir, DEFAULT_MCP_AGENT).catch((error) => {
225
+ const message = error instanceof Error ? error.message : String(error);
226
+ console.error(`Failed to send Holistic resume notification: ${message}`);
227
+ });
228
+ };
229
+ server.setRequestHandler(ListToolsRequestSchema, async () => listHolisticTools());
230
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
231
+ return callHolisticTool(rootDir, request.params.name, (request.params.arguments ?? {}));
232
+ });
233
+ return server;
234
+ }
235
+ export async function waitForStdioShutdown(stdin = process.stdin) {
236
+ stdin.resume();
237
+ await new Promise((resolve) => {
238
+ const finish = () => resolve();
239
+ stdin.once("close", finish);
240
+ stdin.once("end", finish);
241
+ });
242
+ }
243
+ export async function runMcpServer(rootDir) {
244
+ const hookResult = refreshHolisticHooks(rootDir);
245
+ for (const warning of hookResult.warnings) {
246
+ console.error(warning);
247
+ }
248
+ const transport = new StdioServerTransport();
249
+ const server = createHolisticMcpServer(rootDir);
250
+ await server.connect(transport);
251
+ console.error("Holistic MCP server running on stdio");
252
+ await waitForStdioShutdown();
253
+ }
254
+ async function main() {
255
+ const rootDir = process.env.HOLISTIC_REPO || process.cwd();
256
+ await runMcpServer(rootDir);
257
+ }
258
+ const isEntrypoint = process.argv[1] ? pathToFileURL(process.argv[1]).href === import.meta.url : false;
259
+ if (isEntrypoint) {
260
+ main().catch((error) => {
261
+ const message = error instanceof Error ? error.stack || error.message : String(error);
262
+ process.stderr.write(`${message}\n`);
263
+ process.exit(1);
264
+ });
265
+ }
266
+ //# sourceMappingURL=mcp-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"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"}