@longtable/mcp 0.1.45 → 0.1.48
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 +1 -1
- package/dist/research-specification.d.ts +1 -0
- package/dist/research-specification.js +3 -0
- package/dist/server.js +257 -16
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -62,4 +62,5 @@ export interface ResearchSpecificationQuestionSpec {
|
|
|
62
62
|
export declare function renderResearchSpecificationPreview(specification: ResearchSpecification): string;
|
|
63
63
|
export declare function buildResearchSpecificationQuestion(specification: ResearchSpecification): ResearchSpecificationQuestionSpec;
|
|
64
64
|
export declare function researchSpecificationAnswerConfirms(answer: string): boolean;
|
|
65
|
+
export declare function researchSpecificationAnswerNeedsFollowUp(answer: string): boolean;
|
|
65
66
|
export declare function researchSpecificationAnswerStatus(answer: string): "confirmed" | "active" | "deferred";
|
|
@@ -116,6 +116,9 @@ export function buildResearchSpecificationQuestion(specification) {
|
|
|
116
116
|
export function researchSpecificationAnswerConfirms(answer) {
|
|
117
117
|
return answer === "confirm_specification";
|
|
118
118
|
}
|
|
119
|
+
export function researchSpecificationAnswerNeedsFollowUp(answer) {
|
|
120
|
+
return answer === "ask_one_more" || answer === "revise_section";
|
|
121
|
+
}
|
|
119
122
|
export function researchSpecificationAnswerStatus(answer) {
|
|
120
123
|
if (researchSpecificationAnswerConfirms(answer)) {
|
|
121
124
|
return "confirmed";
|
package/dist/server.js
CHANGED
|
@@ -11,9 +11,9 @@ import { classifyCheckpointTrigger } from "@longtable/checkpoints";
|
|
|
11
11
|
import { renderQuestionRecordInput } from "@longtable/provider-claude";
|
|
12
12
|
import { renderQuestionRecordPrompt } from "@longtable/provider-codex";
|
|
13
13
|
import { loadSetupOutput } from "@longtable/setup";
|
|
14
|
-
import { answerWorkspaceQuestion, clearWorkspaceQuestion, createOrUpdateProjectWorkspace, createWorkspaceQuestion, inspectProjectWorkspace, loadProjectContextFromDirectory, loadWorkspaceState, syncCurrentWorkspaceView } from "@longtable/cli";
|
|
14
|
+
import { answerWorkspaceQuestion, applyResearchSpecificationAuditUpdate, applyResearchSpecificationPatch, clearWorkspaceQuestion, createOrUpdateProjectWorkspace, createWorkspaceQuestion, diffResearchSpecifications, findUnincorporatedResearchEvidence, inspectProjectWorkspace, loadProjectContextFromDirectory, loadWorkspaceState, proposeResearchSpecificationPatch, readResearchSpecificationHistory, syncCurrentWorkspaceView } from "@longtable/cli";
|
|
15
15
|
import { buildFirstResearchShapeQuestion, firstResearchShapeAnswerConfirms, firstResearchShapeAnswerStatus } from "./first-research-shape.js";
|
|
16
|
-
import { buildResearchSpecificationQuestion, renderResearchSpecificationPreview, researchSpecificationAnswerConfirms, researchSpecificationAnswerStatus } from "./research-specification.js";
|
|
16
|
+
import { buildResearchSpecificationQuestion, renderResearchSpecificationPreview, researchSpecificationAnswerConfirms, researchSpecificationAnswerNeedsFollowUp, researchSpecificationAnswerStatus } from "./research-specification.js";
|
|
17
17
|
const SERVER_NAME = "longtable-state";
|
|
18
18
|
const require = createRequire(import.meta.url);
|
|
19
19
|
const SERVER_VERSION = String(require("../package.json").version ?? "0.0.0");
|
|
@@ -27,6 +27,11 @@ const TOOL_NAMES = [
|
|
|
27
27
|
"summarize_interview",
|
|
28
28
|
"summarize_research_specification",
|
|
29
29
|
"read_research_specification",
|
|
30
|
+
"propose_research_spec_patch",
|
|
31
|
+
"apply_research_spec_patch",
|
|
32
|
+
"diff_research_specification",
|
|
33
|
+
"read_research_spec_history",
|
|
34
|
+
"find_unincorporated_evidence",
|
|
30
35
|
"cancel_interview",
|
|
31
36
|
"confirm_first_research_shape",
|
|
32
37
|
"confirm_research_specification",
|
|
@@ -47,6 +52,22 @@ const questionOptionSchema = z.object({
|
|
|
47
52
|
description: z.string().optional(),
|
|
48
53
|
recommended: z.boolean().optional()
|
|
49
54
|
});
|
|
55
|
+
const commitmentFamilySchema = z.enum([
|
|
56
|
+
"scope",
|
|
57
|
+
"construct",
|
|
58
|
+
"coding",
|
|
59
|
+
"method",
|
|
60
|
+
"evidence",
|
|
61
|
+
"epistemic_authority",
|
|
62
|
+
"product_policy"
|
|
63
|
+
]);
|
|
64
|
+
const epistemicBasisSchema = z.enum([
|
|
65
|
+
"researcher_knowledge",
|
|
66
|
+
"project_state",
|
|
67
|
+
"external_evidence",
|
|
68
|
+
"ai_inference",
|
|
69
|
+
"mixed"
|
|
70
|
+
]);
|
|
50
71
|
const firstResearchShapeSchema = z.object({
|
|
51
72
|
handle: z.string().min(1),
|
|
52
73
|
currentGoal: z.string().min(1),
|
|
@@ -67,6 +88,9 @@ const researchSpecificationSchema = z.object({
|
|
|
67
88
|
createdAt: z.string().optional(),
|
|
68
89
|
updatedAt: z.string().optional(),
|
|
69
90
|
sourceHookId: z.string().optional(),
|
|
91
|
+
latestRevisionId: z.string().optional(),
|
|
92
|
+
sourceEvidenceIds: z.array(z.string()).optional(),
|
|
93
|
+
sectionEvidence: z.record(z.string(), z.array(z.string())).optional(),
|
|
70
94
|
researchDirection: z.object({
|
|
71
95
|
question: z.string().optional(),
|
|
72
96
|
purpose: z.string().min(1),
|
|
@@ -113,6 +137,15 @@ const researchSpecificationSchema = z.object({
|
|
|
113
137
|
confidence: z.enum(["low", "medium", "high"]).default("medium"),
|
|
114
138
|
confirmedAt: z.string().optional()
|
|
115
139
|
});
|
|
140
|
+
const researchSpecificationPatchSourceSchema = z.enum([
|
|
141
|
+
"interview",
|
|
142
|
+
"panel",
|
|
143
|
+
"critic",
|
|
144
|
+
"reviewer",
|
|
145
|
+
"decision",
|
|
146
|
+
"manual",
|
|
147
|
+
"system"
|
|
148
|
+
]);
|
|
116
149
|
function textResult(structuredContent) {
|
|
117
150
|
return {
|
|
118
151
|
content: [
|
|
@@ -228,6 +261,57 @@ function resolveFirstResearchShapeObligation(state, options) {
|
|
|
228
261
|
})
|
|
229
262
|
};
|
|
230
263
|
}
|
|
264
|
+
function researchSpecificationFollowUpReason(answer) {
|
|
265
|
+
if (answer === "ask_one_more") {
|
|
266
|
+
return "The researcher chose one more question before saving; after that answer, LongTable must update or read the Research Specification and return to confirmation.";
|
|
267
|
+
}
|
|
268
|
+
if (answer === "revise_section") {
|
|
269
|
+
return "The researcher chose section revision; after the section is revised, LongTable must return to the Research Specification Preview for confirmation.";
|
|
270
|
+
}
|
|
271
|
+
return "Research Specification confirmation remains open.";
|
|
272
|
+
}
|
|
273
|
+
function ensureResearchSpecificationConfirmationObligation(state, specification, options) {
|
|
274
|
+
const existing = (state.questionObligations ?? []).find((obligation) => obligation.kind === "research_specification_confirmation" &&
|
|
275
|
+
obligation.status === "pending" &&
|
|
276
|
+
((specification.sourceHookId && obligation.sourceHookId === specification.sourceHookId) ||
|
|
277
|
+
(!specification.sourceHookId && obligation.prompt.includes(specification.title))));
|
|
278
|
+
const timestamp = new Date().toISOString();
|
|
279
|
+
const next = {
|
|
280
|
+
...(existing ?? {
|
|
281
|
+
id: createId("question_obligation"),
|
|
282
|
+
kind: "research_specification_confirmation",
|
|
283
|
+
status: "pending",
|
|
284
|
+
createdAt: timestamp
|
|
285
|
+
}),
|
|
286
|
+
updatedAt: timestamp,
|
|
287
|
+
prompt: `Return to Research Specification Preview before ending the interview: ${specification.title}`,
|
|
288
|
+
reason: researchSpecificationFollowUpReason(options.answer),
|
|
289
|
+
...(specification.sourceHookId ? { sourceHookId: specification.sourceHookId } : {}),
|
|
290
|
+
...(options.questionId ? { questionId: options.questionId } : existing?.questionId ? { questionId: existing.questionId } : {}),
|
|
291
|
+
...(options.decisionId ? { decisionId: options.decisionId } : existing?.decisionId ? { decisionId: existing.decisionId } : {})
|
|
292
|
+
};
|
|
293
|
+
return upsertQuestionObligation(state, next);
|
|
294
|
+
}
|
|
295
|
+
function resolveResearchSpecificationConfirmationObligation(state, specification, options = {}) {
|
|
296
|
+
return {
|
|
297
|
+
...state,
|
|
298
|
+
questionObligations: (state.questionObligations ?? []).map((obligation) => {
|
|
299
|
+
const matches = obligation.kind === "research_specification_confirmation" && ((specification.sourceHookId && obligation.sourceHookId === specification.sourceHookId) ||
|
|
300
|
+
(options.questionId && obligation.questionId === options.questionId) ||
|
|
301
|
+
(!specification.sourceHookId && obligation.prompt.includes(specification.title)));
|
|
302
|
+
if (!matches || obligation.status !== "pending") {
|
|
303
|
+
return obligation;
|
|
304
|
+
}
|
|
305
|
+
return {
|
|
306
|
+
...obligation,
|
|
307
|
+
status: options.status ?? "satisfied",
|
|
308
|
+
updatedAt: new Date().toISOString(),
|
|
309
|
+
...(options.questionId ? { questionId: options.questionId } : obligation.questionId ? { questionId: obligation.questionId } : {}),
|
|
310
|
+
...(options.decisionId ? { decisionId: options.decisionId } : obligation.decisionId ? { decisionId: obligation.decisionId } : {})
|
|
311
|
+
};
|
|
312
|
+
})
|
|
313
|
+
};
|
|
314
|
+
}
|
|
231
315
|
function interviewDepth(turns) {
|
|
232
316
|
if (turns.some((turn) => turn.readyToSummarize === true && turn.quality !== "thin")) {
|
|
233
317
|
return "ready_to_summarize";
|
|
@@ -772,11 +856,6 @@ async function markResearchSpecificationConfirmation(context, specification, ans
|
|
|
772
856
|
status: researchSpecificationAnswerStatus(answer) === "deferred" ? "deferred" : "draft",
|
|
773
857
|
updatedAt: timestamp
|
|
774
858
|
};
|
|
775
|
-
state.researchSpecification = confirmedSpecification;
|
|
776
|
-
state.workingState = {
|
|
777
|
-
...state.workingState,
|
|
778
|
-
researchSpecification: confirmedSpecification
|
|
779
|
-
};
|
|
780
859
|
state.hooks = (state.hooks ?? []).map((hook) => {
|
|
781
860
|
if (hook.id !== specification.sourceHookId || !isInterviewHookRun(hook)) {
|
|
782
861
|
return hook;
|
|
@@ -794,6 +873,37 @@ async function markResearchSpecificationConfirmation(context, specification, ans
|
|
|
794
873
|
: hook.linkedDecisionRecordIds
|
|
795
874
|
};
|
|
796
875
|
});
|
|
876
|
+
const sourceEvidenceIds = (state.evidenceRecords ?? [])
|
|
877
|
+
.filter((record) => record.sourceHookId && record.sourceHookId === specification.sourceHookId)
|
|
878
|
+
.map((record) => record.id);
|
|
879
|
+
const audited = applyResearchSpecificationAuditUpdate(state, {
|
|
880
|
+
specification: confirmedSpecification,
|
|
881
|
+
timestamp,
|
|
882
|
+
source: "decision",
|
|
883
|
+
title: `Research Specification confirmation: ${confirmedSpecification.title}`,
|
|
884
|
+
rationale: `Research Specification confirmation answer: ${answer}`,
|
|
885
|
+
sourceEvidenceIds,
|
|
886
|
+
questionRecordId: questionId,
|
|
887
|
+
decisionRecordId: decisionId,
|
|
888
|
+
createDecisionRecord: false
|
|
889
|
+
});
|
|
890
|
+
const nextState = researchSpecificationAnswerConfirms(answer)
|
|
891
|
+
? resolveResearchSpecificationConfirmationObligation(audited.state, confirmedSpecification, {
|
|
892
|
+
questionId,
|
|
893
|
+
decisionId,
|
|
894
|
+
status: "satisfied"
|
|
895
|
+
})
|
|
896
|
+
: researchSpecificationAnswerNeedsFollowUp(answer)
|
|
897
|
+
? ensureResearchSpecificationConfirmationObligation(audited.state, confirmedSpecification, {
|
|
898
|
+
answer,
|
|
899
|
+
questionId,
|
|
900
|
+
decisionId
|
|
901
|
+
})
|
|
902
|
+
: resolveResearchSpecificationConfirmationObligation(audited.state, confirmedSpecification, {
|
|
903
|
+
questionId,
|
|
904
|
+
decisionId,
|
|
905
|
+
status: "cleared"
|
|
906
|
+
});
|
|
797
907
|
const session = {
|
|
798
908
|
...context.session,
|
|
799
909
|
researchSpecification: confirmedSpecification,
|
|
@@ -801,9 +911,9 @@ async function markResearchSpecificationConfirmation(context, specification, ans
|
|
|
801
911
|
};
|
|
802
912
|
context.session = session;
|
|
803
913
|
await writeFile(context.sessionFilePath, JSON.stringify(session, null, 2), "utf8");
|
|
804
|
-
await writeFile(context.stateFilePath, JSON.stringify(
|
|
914
|
+
await writeFile(context.stateFilePath, JSON.stringify(nextState, null, 2), "utf8");
|
|
805
915
|
await syncCurrentWorkspaceView(context);
|
|
806
|
-
return { state, session, specification: confirmedSpecification };
|
|
916
|
+
return { state: nextState, session, specification: confirmedSpecification };
|
|
807
917
|
}
|
|
808
918
|
async function markAlreadyConfirmedResearchSpecification(context, specification) {
|
|
809
919
|
const state = asInterviewState(await loadWorkspaceState(context));
|
|
@@ -832,6 +942,9 @@ async function markAlreadyConfirmedResearchSpecification(context, specification)
|
|
|
832
942
|
researchSpecification: confirmedSpecification
|
|
833
943
|
};
|
|
834
944
|
});
|
|
945
|
+
const nextState = resolveResearchSpecificationConfirmationObligation(state, confirmedSpecification, {
|
|
946
|
+
status: "satisfied"
|
|
947
|
+
});
|
|
835
948
|
const session = {
|
|
836
949
|
...context.session,
|
|
837
950
|
researchSpecification: confirmedSpecification,
|
|
@@ -839,9 +952,9 @@ async function markAlreadyConfirmedResearchSpecification(context, specification)
|
|
|
839
952
|
};
|
|
840
953
|
context.session = session;
|
|
841
954
|
await writeFile(context.sessionFilePath, JSON.stringify(session, null, 2), "utf8");
|
|
842
|
-
await writeFile(context.stateFilePath, JSON.stringify(
|
|
955
|
+
await writeFile(context.stateFilePath, JSON.stringify(nextState, null, 2), "utf8");
|
|
843
956
|
await syncCurrentWorkspaceView(context);
|
|
844
|
-
return { state, session, specification: confirmedSpecification };
|
|
957
|
+
return { state: nextState, session, specification: confirmedSpecification };
|
|
845
958
|
}
|
|
846
959
|
function statusForElicitationError(error) {
|
|
847
960
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -1132,6 +1245,126 @@ export function createLongTableMcpServer() {
|
|
|
1132
1245
|
return errorResult(error instanceof Error ? error.message : String(error));
|
|
1133
1246
|
}
|
|
1134
1247
|
});
|
|
1248
|
+
server.registerTool("propose_research_spec_patch", {
|
|
1249
|
+
title: "Propose Research Specification Patch",
|
|
1250
|
+
description: "Store a reviewable Research Specification patch without applying it.",
|
|
1251
|
+
inputSchema: cwdSchema.extend({
|
|
1252
|
+
specification: researchSpecificationSchema,
|
|
1253
|
+
source: researchSpecificationPatchSourceSchema.default("manual"),
|
|
1254
|
+
rationale: z.string().optional(),
|
|
1255
|
+
sourceEvidenceIds: z.array(z.string()).optional()
|
|
1256
|
+
})
|
|
1257
|
+
}, async ({ cwd: inputCwd, specification, source, rationale, sourceEvidenceIds }) => {
|
|
1258
|
+
try {
|
|
1259
|
+
const context = await requireContext(inputCwd);
|
|
1260
|
+
const result = await proposeResearchSpecificationPatch({
|
|
1261
|
+
context,
|
|
1262
|
+
specification: specification,
|
|
1263
|
+
source,
|
|
1264
|
+
rationale,
|
|
1265
|
+
sourceEvidenceIds
|
|
1266
|
+
});
|
|
1267
|
+
return textResult({
|
|
1268
|
+
patch: result.patch,
|
|
1269
|
+
changes: result.changes,
|
|
1270
|
+
nextAction: `apply_research_spec_patch patchId=${result.patch.id}`
|
|
1271
|
+
});
|
|
1272
|
+
}
|
|
1273
|
+
catch (error) {
|
|
1274
|
+
return errorResult(error instanceof Error ? error.message : String(error));
|
|
1275
|
+
}
|
|
1276
|
+
});
|
|
1277
|
+
server.registerTool("apply_research_spec_patch", {
|
|
1278
|
+
title: "Apply Research Specification Patch",
|
|
1279
|
+
description: "Automatically apply a proposed or inline Research Specification update and record a revision.",
|
|
1280
|
+
inputSchema: cwdSchema.extend({
|
|
1281
|
+
patchId: z.string().optional(),
|
|
1282
|
+
specification: researchSpecificationSchema.optional(),
|
|
1283
|
+
source: researchSpecificationPatchSourceSchema.default("manual"),
|
|
1284
|
+
rationale: z.string().optional(),
|
|
1285
|
+
sourceEvidenceIds: z.array(z.string()).optional(),
|
|
1286
|
+
questionRecordId: z.string().optional(),
|
|
1287
|
+
decisionRecordId: z.string().optional()
|
|
1288
|
+
})
|
|
1289
|
+
}, async ({ cwd: inputCwd, patchId, specification, source, rationale, sourceEvidenceIds, questionRecordId, decisionRecordId }) => {
|
|
1290
|
+
try {
|
|
1291
|
+
const context = await requireContext(inputCwd);
|
|
1292
|
+
const result = await applyResearchSpecificationPatch({
|
|
1293
|
+
context,
|
|
1294
|
+
patchId,
|
|
1295
|
+
specification: specification,
|
|
1296
|
+
source,
|
|
1297
|
+
rationale,
|
|
1298
|
+
sourceEvidenceIds,
|
|
1299
|
+
questionRecordId,
|
|
1300
|
+
decisionRecordId
|
|
1301
|
+
});
|
|
1302
|
+
return textResult({
|
|
1303
|
+
patch: result.patch,
|
|
1304
|
+
revision: result.revision,
|
|
1305
|
+
specification: result.specification,
|
|
1306
|
+
decision: result.decision,
|
|
1307
|
+
session: {
|
|
1308
|
+
currentGoal: result.session.currentGoal,
|
|
1309
|
+
researchSpecification: result.session.researchSpecification
|
|
1310
|
+
}
|
|
1311
|
+
});
|
|
1312
|
+
}
|
|
1313
|
+
catch (error) {
|
|
1314
|
+
return errorResult(error instanceof Error ? error.message : String(error));
|
|
1315
|
+
}
|
|
1316
|
+
});
|
|
1317
|
+
server.registerTool("diff_research_specification", {
|
|
1318
|
+
title: "Diff Research Specification",
|
|
1319
|
+
description: "Compare an inline Research Specification against the current workspace specification without writing state.",
|
|
1320
|
+
inputSchema: cwdSchema.extend({
|
|
1321
|
+
specification: researchSpecificationSchema
|
|
1322
|
+
}),
|
|
1323
|
+
annotations: { readOnlyHint: true }
|
|
1324
|
+
}, async ({ cwd: inputCwd, specification }) => {
|
|
1325
|
+
try {
|
|
1326
|
+
const context = await requireContext(inputCwd);
|
|
1327
|
+
const state = asInterviewState(await loadWorkspaceState(context));
|
|
1328
|
+
const current = state.researchSpecification ?? context.session.researchSpecification;
|
|
1329
|
+
return textResult({
|
|
1330
|
+
current,
|
|
1331
|
+
changes: diffResearchSpecifications(current, specification)
|
|
1332
|
+
});
|
|
1333
|
+
}
|
|
1334
|
+
catch (error) {
|
|
1335
|
+
return errorResult(error instanceof Error ? error.message : String(error));
|
|
1336
|
+
}
|
|
1337
|
+
});
|
|
1338
|
+
server.registerTool("read_research_spec_history", {
|
|
1339
|
+
title: "Read Research Specification History",
|
|
1340
|
+
description: "Read specification revisions, patches, and evidence records for audit or resume.",
|
|
1341
|
+
inputSchema: cwdSchema,
|
|
1342
|
+
annotations: { readOnlyHint: true }
|
|
1343
|
+
}, async ({ cwd: inputCwd }) => {
|
|
1344
|
+
try {
|
|
1345
|
+
const context = await requireContext(inputCwd);
|
|
1346
|
+
return textResult(await readResearchSpecificationHistory(context));
|
|
1347
|
+
}
|
|
1348
|
+
catch (error) {
|
|
1349
|
+
return errorResult(error instanceof Error ? error.message : String(error));
|
|
1350
|
+
}
|
|
1351
|
+
});
|
|
1352
|
+
server.registerTool("find_unincorporated_evidence", {
|
|
1353
|
+
title: "Find Unincorporated Research Evidence",
|
|
1354
|
+
description: "List interview, panel, critic, reviewer, or invocation evidence not yet incorporated into a Research Specification revision.",
|
|
1355
|
+
inputSchema: cwdSchema,
|
|
1356
|
+
annotations: { readOnlyHint: true }
|
|
1357
|
+
}, async ({ cwd: inputCwd }) => {
|
|
1358
|
+
try {
|
|
1359
|
+
const context = await requireContext(inputCwd);
|
|
1360
|
+
return textResult({
|
|
1361
|
+
evidenceRecords: await findUnincorporatedResearchEvidence(context)
|
|
1362
|
+
});
|
|
1363
|
+
}
|
|
1364
|
+
catch (error) {
|
|
1365
|
+
return errorResult(error instanceof Error ? error.message : String(error));
|
|
1366
|
+
}
|
|
1367
|
+
});
|
|
1135
1368
|
server.registerTool("cancel_interview", {
|
|
1136
1369
|
title: "Cancel LongTable Interview",
|
|
1137
1370
|
description: "Explicitly cancel the active $longtable-interview hook without confirming a First Research Shape.",
|
|
@@ -1428,9 +1661,11 @@ export function createLongTableMcpServer() {
|
|
|
1428
1661
|
options: z.array(questionOptionSchema).optional(),
|
|
1429
1662
|
displayReason: z.string().optional(),
|
|
1430
1663
|
provider: z.enum(["codex", "claude"]).optional(),
|
|
1431
|
-
required: z.boolean().optional()
|
|
1664
|
+
required: z.boolean().optional(),
|
|
1665
|
+
commitmentFamily: commitmentFamilySchema.optional(),
|
|
1666
|
+
epistemicBasis: epistemicBasisSchema.optional()
|
|
1432
1667
|
})
|
|
1433
|
-
}, async ({ cwd: inputCwd, prompt, title, question, checkpointKey, options, displayReason, provider, required }) => {
|
|
1668
|
+
}, async ({ cwd: inputCwd, prompt, title, question, checkpointKey, options, displayReason, provider, required, commitmentFamily, epistemicBasis }) => {
|
|
1434
1669
|
try {
|
|
1435
1670
|
const context = await requireContext(inputCwd);
|
|
1436
1671
|
const result = await createWorkspaceQuestion({
|
|
@@ -1442,7 +1677,9 @@ export function createLongTableMcpServer() {
|
|
|
1442
1677
|
questionOptions: options,
|
|
1443
1678
|
displayReason,
|
|
1444
1679
|
provider,
|
|
1445
|
-
required
|
|
1680
|
+
required,
|
|
1681
|
+
commitmentFamily: commitmentFamily,
|
|
1682
|
+
epistemicBasis: epistemicBasis
|
|
1446
1683
|
});
|
|
1447
1684
|
return textResult({
|
|
1448
1685
|
question: result.question,
|
|
@@ -1465,9 +1702,11 @@ export function createLongTableMcpServer() {
|
|
|
1465
1702
|
displayReason: z.string().optional(),
|
|
1466
1703
|
provider: z.enum(["codex", "claude"]).default("codex"),
|
|
1467
1704
|
required: z.boolean().optional(),
|
|
1705
|
+
commitmentFamily: commitmentFamilySchema.optional(),
|
|
1706
|
+
epistemicBasis: epistemicBasisSchema.optional(),
|
|
1468
1707
|
fallbackOnly: z.boolean().default(false).describe("Create and render the checkpoint without calling MCP elicitation.")
|
|
1469
1708
|
})
|
|
1470
|
-
}, async ({ cwd: inputCwd, prompt, title, question, checkpointKey, options, displayReason, provider, required, fallbackOnly }) => {
|
|
1709
|
+
}, async ({ cwd: inputCwd, prompt, title, question, checkpointKey, options, displayReason, provider, required, commitmentFamily, epistemicBasis, fallbackOnly }) => {
|
|
1471
1710
|
try {
|
|
1472
1711
|
const context = await requireContext(inputCwd);
|
|
1473
1712
|
const created = await createWorkspaceQuestion({
|
|
@@ -1479,7 +1718,9 @@ export function createLongTableMcpServer() {
|
|
|
1479
1718
|
questionOptions: options,
|
|
1480
1719
|
displayReason,
|
|
1481
1720
|
provider,
|
|
1482
|
-
required
|
|
1721
|
+
required,
|
|
1722
|
+
commitmentFamily: commitmentFamily,
|
|
1723
|
+
epistemicBasis: epistemicBasis
|
|
1483
1724
|
});
|
|
1484
1725
|
const fallback = renderQuestionFallback(created.question, provider);
|
|
1485
1726
|
if (fallbackOnly) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@longtable/mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.48",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "LongTable MCP transport for workspace state and Researcher Checkpoints",
|
|
6
6
|
"type": "module",
|
|
@@ -26,12 +26,12 @@
|
|
|
26
26
|
"self-test": "node ./dist/server.js --self-test"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@longtable/checkpoints": "0.1.
|
|
30
|
-
"@longtable/cli": "0.1.
|
|
31
|
-
"@longtable/core": "0.1.
|
|
32
|
-
"@longtable/provider-claude": "0.1.
|
|
33
|
-
"@longtable/provider-codex": "0.1.
|
|
34
|
-
"@longtable/setup": "0.1.
|
|
29
|
+
"@longtable/checkpoints": "0.1.48",
|
|
30
|
+
"@longtable/cli": "0.1.48",
|
|
31
|
+
"@longtable/core": "0.1.48",
|
|
32
|
+
"@longtable/provider-claude": "0.1.48",
|
|
33
|
+
"@longtable/provider-codex": "0.1.48",
|
|
34
|
+
"@longtable/setup": "0.1.48",
|
|
35
35
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
36
36
|
"zod": "^4.0.0"
|
|
37
37
|
},
|