@basegrid_tech/mcp 0.18.13 → 0.18.14

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 (2) hide show
  1. package/dist/index.js +189 -15
  2. package/package.json +12 -12
package/dist/index.js CHANGED
@@ -69,6 +69,8 @@ var DEFAULT_WORKSPACE = {
69
69
  iconColor: "#6b7280",
70
70
  order: 0
71
71
  };
72
+ var MCP_ASK_TIMEOUT_MS = 60 * 60 * 1e3;
73
+ var MCP_TOOL_TIMEOUT_MS = MCP_ASK_TIMEOUT_MS + 6e4;
72
74
  var QUICK_COMMAND_LIMITS = {
73
75
  maxCommands: 40,
74
76
  maxLabel: 80,
@@ -102,6 +104,29 @@ var DEFAULT_AGENT_COMMANDS = {
102
104
  }
103
105
  };
104
106
 
107
+ // ../shared/src/config-save-mutation.ts
108
+ function applyTaskConfigMutation(currentTasks, mutation) {
109
+ if (!mutation) return currentTasks;
110
+ if (mutation.kind === "create") {
111
+ if (currentTasks.some((task) => task.id === mutation.task.id)) return currentTasks;
112
+ return [...currentTasks, mutation.task];
113
+ }
114
+ if (mutation.kind === "delete") {
115
+ const doomed = new Set(mutation.ids);
116
+ return currentTasks.filter((task) => !doomed.has(task.id));
117
+ }
118
+ const patches = new Map(mutation.patches.map((patch) => [patch.id, patch]));
119
+ return currentTasks.map((task) => {
120
+ const patch = patches.get(task.id);
121
+ if (!patch) return task;
122
+ const next = { ...task, ...patch.updates };
123
+ for (const key of patch.clear ?? []) {
124
+ delete next[key];
125
+ }
126
+ return next;
127
+ });
128
+ }
129
+
105
130
  // ../server/src/database.ts
106
131
  import Database from "libsql";
107
132
  import path3 from "path";
@@ -604,6 +629,7 @@ function createSchema() {
604
629
  agent_session_id TEXT,
605
630
  branch TEXT,
606
631
  use_worktree INTEGER DEFAULT 0,
632
+ worktree_path TEXT,
607
633
  created_at TEXT NOT NULL,
608
634
  updated_at TEXT NOT NULL,
609
635
  completed_at TEXT
@@ -789,12 +815,39 @@ function createSchema() {
789
815
  updated_at INTEGER NOT NULL
790
816
  );
791
817
 
818
+ -- \u0427\u0435\u0440\u043D\u043E\u0432\u0438\u043A \u0438\u043D\u043F\u0443\u0442\u0430 \u0441\u0435\u0441\u0441\u0438\u0438: \u043D\u0430\u0431\u0440\u0430\u043D\u043D\u044B\u0439, \u043D\u043E \u043D\u0435 \u043E\u0442\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u043D\u044B\u0439 \u0442\u0435\u043A\u0441\u0442 (HTML
819
+ -- \u0440\u0435\u0434\u0430\u043A\u0442\u043E\u0440\u0430 PromptInput) \u0438 \u043C\u0435\u0442\u0430\u0434\u0430\u043D\u043D\u044B\u0435 \u0435\u0433\u043E \u0447\u0438\u043F\u043E\u0432. \u041A\u043B\u044E\u0447 \u2014 terminal_id,
820
+ -- \u043F\u043E\u044D\u0442\u043E\u043C\u0443 \u0447\u0435\u0440\u043D\u043E\u0432\u0438\u043A \u043F\u0435\u0440\u0435\u0436\u0438\u0432\u0430\u0435\u0442 \u043F\u0435\u0440\u0435\u0437\u0430\u043F\u0443\u0441\u043A \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F (issue #921). \u0421\u0442\u0440\u043E\u043A\u0430
821
+ -- \u0436\u0438\u0432\u0451\u0442 \u0440\u043E\u0432\u043D\u043E \u0441\u0442\u043E\u043B\u044C\u043A\u043E \u0436\u0435, \u0441\u043A\u043E\u043B\u044C\u043A\u043E \u0441\u0442\u0440\u043E\u043A\u0430 \u0441\u0435\u0441\u0441\u0438\u0438: \u0435\u0451 \u0443\u0434\u0430\u043B\u044F\u044E\u0442 \u0432\u043C\u0435\u0441\u0442\u0435 \u0441
822
+ -- \u0441\u0435\u0441\u0441\u0438\u0435\u0439 (deleteSessionById \u0438 \u0441\u043E\u0441\u0435\u0434\u0438) \u0438 \u043F\u043E\u0434\u0447\u0438\u0449\u0430\u044E\u0442 \u043D\u0430 \u0441\u0442\u0430\u0440\u0442\u0435
823
+ -- (pruneOrphanInputDrafts).
824
+ CREATE TABLE IF NOT EXISTS session_input_drafts (
825
+ terminal_id TEXT PRIMARY KEY,
826
+ html TEXT NOT NULL,
827
+ attachments TEXT NOT NULL DEFAULT '[]',
828
+ updated_at INTEGER NOT NULL
829
+ );
830
+
792
831
  CREATE TABLE IF NOT EXISTS worktree_notes (
793
832
  worktree_path TEXT PRIMARY KEY,
794
833
  body TEXT NOT NULL,
795
834
  updated_at INTEGER NOT NULL
796
835
  );
797
836
 
837
+ -- \u0421\u043E\u0441\u0442\u043E\u044F\u043D\u0438\u0435 \u0440\u0430\u0431\u043E\u0442\u044B \u0432 \u0432\u043E\u0440\u043A\u0442\u0440\u0438: \u0433\u0434\u0435 \u043C\u044B \u0432 \u0446\u0435\u043F\u043E\u0447\u043A\u0435 \xAB\u043E\u0431\u0441\u0443\u0436\u0434\u0435\u043D\u0438\u0435 \u2192 \u0440\u0435\u0430\u043B\u0438\u0437\u0430\u0446\u0438\u044F \u2192
838
+ -- \u043F\u0440\u0438\u0451\u043C\u043A\u0430\xBB \u0438 \u0447\u0442\u043E \u043F\u0435\u0440\u0435\u0434\u0430\u0451\u0442\u0441\u044F \u0434\u0430\u043B\u044C\u0448\u0435. \u0416\u0438\u0432\u0451\u0442 \u043D\u0430 \u0432\u043E\u0440\u043A\u0442\u0440\u0438, \u0430 \u043D\u0435 \u043D\u0430 \u0441\u0435\u0441\u0441\u0438\u0438
839
+ -- (\u0438\u0445 \u0432 \u043E\u0434\u043D\u043E\u0439 \u0432\u043E\u0440\u043A\u0442\u0440\u0438 \u043D\u0435\u0441\u043A\u043E\u043B\u044C\u043A\u043E, \u0438 \u043E\u043D\u0438 \u0440\u0430\u0437\u043E\u0448\u043B\u0438\u0441\u044C \u0431\u044B) \u0438 \u043D\u0435 \u043D\u0430 \u0437\u0430\u0434\u0430\u0447\u0435
840
+ -- (\u0437\u0430\u0434\u0430\u0447 \u043C\u043E\u0436\u0435\u0442 \u0431\u044B\u0442\u044C \u043D\u0435\u0441\u043A\u043E\u043B\u044C\u043A\u043E \u0438\u043B\u0438 \u043D\u0438 \u043E\u0434\u043D\u043E\u0439). \u0423\u043C\u0438\u0440\u0430\u0435\u0442 \u0432\u043C\u0435\u0441\u0442\u0435 \u0441 \u0432\u043E\u0440\u043A\u0442\u0440\u0438 \u2014
841
+ -- \u0441\u043C. deleteWorktreeListEntry.
842
+ CREATE TABLE IF NOT EXISTS worktree_flow (
843
+ worktree_path TEXT PRIMARY KEY,
844
+ step TEXT NOT NULL,
845
+ criteria TEXT NOT NULL DEFAULT '[]',
846
+ work_session_id TEXT,
847
+ accept_session_id TEXT,
848
+ updated_at INTEGER NOT NULL
849
+ );
850
+
798
851
  CREATE TABLE IF NOT EXISTS worktree_view_modes (
799
852
  worktree_path TEXT PRIMARY KEY,
800
853
  view_mode TEXT NOT NULL,
@@ -885,6 +938,17 @@ function createSchema() {
885
938
  function migrateSchema(d) {
886
939
  const row = d.prepare("SELECT value FROM schema_meta WHERE key = 'schema_version'").get();
887
940
  const version = row ? parseInt(row.value, 10) : 0;
941
+ {
942
+ const flowCols = d.prepare("PRAGMA table_info(worktree_flow)").all();
943
+ if (flowCols.length > 0) {
944
+ if (!flowCols.some((c) => c.name === "work_session_id")) {
945
+ d.exec("ALTER TABLE worktree_flow ADD COLUMN work_session_id TEXT");
946
+ }
947
+ if (!flowCols.some((c) => c.name === "accept_session_id")) {
948
+ d.exec("ALTER TABLE worktree_flow ADD COLUMN accept_session_id TEXT");
949
+ }
950
+ }
951
+ }
888
952
  if (version < 1) {
889
953
  d.transaction(() => {
890
954
  const projectCols = d.prepare("PRAGMA table_info(projects)").all();
@@ -1915,6 +1979,10 @@ function verifySchema(d) {
1915
1979
  {
1916
1980
  column: "source_external_id",
1917
1981
  ddl: "ALTER TABLE tasks ADD COLUMN source_external_id TEXT"
1982
+ },
1983
+ {
1984
+ column: "worktree_path",
1985
+ ddl: "ALTER TABLE tasks ADD COLUMN worktree_path TEXT"
1918
1986
  }
1919
1987
  ],
1920
1988
  task_source_links: [
@@ -2042,6 +2110,7 @@ var DEFAULTS_KEYS_MAP = {
2042
2110
  claudeDefaultEffort: true,
2043
2111
  codexDefaultModel: true,
2044
2112
  codexDefaultEffort: true,
2113
+ geminiDefaultModel: true,
2045
2114
  language: true,
2046
2115
  hasSeededDefaultTaskWorkflow: true,
2047
2116
  defaultSpinnerVariant: true,
@@ -2058,6 +2127,7 @@ var DEFAULTS_KEYS_MAP = {
2058
2127
  reviewClaudeModel: true,
2059
2128
  reviewCodexModel: true,
2060
2129
  reviewCodexEffort: true,
2130
+ reviewGeminiModel: true,
2061
2131
  aiCommitModel: true,
2062
2132
  aiCommitThinkingLevel: true,
2063
2133
  aiCommitCustomPrompt: true,
@@ -2307,17 +2377,17 @@ function saveConfig(config) {
2307
2377
  h.sshOptions ?? null
2308
2378
  );
2309
2379
  }
2310
- const nextTaskIds = new Set((config.tasks ?? []).map((t) => t.id));
2311
- const existingTaskIds = d.prepare("SELECT id FROM tasks").all().map(
2312
- (r) => r.id
2313
- );
2314
- const deleteTask = d.prepare("DELETE FROM tasks WHERE id = ?");
2315
- for (const id of existingTaskIds) {
2316
- if (!nextTaskIds.has(id)) deleteTask.run(id);
2380
+ if (config.tasks) {
2381
+ const nextTaskIds = new Set(config.tasks.map((t) => t.id));
2382
+ const existingTaskIds = d.prepare("SELECT id FROM tasks").all().map((r) => r.id);
2383
+ const deleteTask = d.prepare("DELETE FROM tasks WHERE id = ?");
2384
+ for (const id of existingTaskIds) {
2385
+ if (!nextTaskIds.has(id)) deleteTask.run(id);
2386
+ }
2317
2387
  }
2318
2388
  const insertTask = d.prepare(
2319
- `INSERT INTO tasks (id, project_name, title, description, status, "order", assigned_session_id, assigned_agent, agent_session_id, branch, use_worktree, created_at, updated_at, completed_at, source_connector_id, source_external_url, source_external_id)
2320
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
2389
+ `INSERT INTO tasks (id, project_name, title, description, status, "order", assigned_session_id, assigned_agent, agent_session_id, branch, use_worktree, worktree_path, created_at, updated_at, completed_at, source_connector_id, source_external_url, source_external_id)
2390
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
2321
2391
  ON CONFLICT(id) DO UPDATE SET
2322
2392
  project_name = excluded.project_name,
2323
2393
  title = excluded.title,
@@ -2329,6 +2399,7 @@ function saveConfig(config) {
2329
2399
  agent_session_id = excluded.agent_session_id,
2330
2400
  branch = excluded.branch,
2331
2401
  use_worktree = excluded.use_worktree,
2402
+ worktree_path = excluded.worktree_path,
2332
2403
  created_at = excluded.created_at,
2333
2404
  updated_at = excluded.updated_at,
2334
2405
  completed_at = excluded.completed_at,
@@ -2349,6 +2420,7 @@ function saveConfig(config) {
2349
2420
  t.agentSessionId ?? null,
2350
2421
  t.branch ?? null,
2351
2422
  t.useWorktree ? 1 : 0,
2423
+ t.worktreePath ?? null,
2352
2424
  t.createdAt,
2353
2425
  t.updatedAt,
2354
2426
  t.completedAt ?? null,
@@ -2391,8 +2463,8 @@ function dbGetTask(id) {
2391
2463
  }
2392
2464
  function dbInsertTask(task) {
2393
2465
  getDb().prepare(
2394
- `INSERT INTO tasks (id, project_name, title, description, status, "order", assigned_session_id, assigned_agent, agent_session_id, branch, use_worktree, created_at, updated_at, completed_at, source_connector_id, source_external_url, source_external_id)
2395
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
2466
+ `INSERT INTO tasks (id, project_name, title, description, status, "order", assigned_session_id, assigned_agent, agent_session_id, branch, use_worktree, worktree_path, created_at, updated_at, completed_at, source_connector_id, source_external_url, source_external_id)
2467
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
2396
2468
  ).run(
2397
2469
  task.id,
2398
2470
  task.projectName,
@@ -2405,6 +2477,7 @@ function dbInsertTask(task) {
2405
2477
  task.agentSessionId ?? null,
2406
2478
  task.branch ?? null,
2407
2479
  task.useWorktree ? 1 : 0,
2480
+ task.worktreePath ?? null,
2408
2481
  task.createdAt,
2409
2482
  task.updatedAt,
2410
2483
  task.completedAt ?? null,
@@ -2427,6 +2500,7 @@ function dbUpdateTask(id, updates) {
2427
2500
  addSet(sets, params, "status", updates.status);
2428
2501
  addSet(sets, params, '"order"', updates.order);
2429
2502
  addSet(sets, params, "branch", updates.branch);
2503
+ addSet(sets, params, "worktree_path", updates.worktreePath);
2430
2504
  if (updates.useWorktree !== void 0) {
2431
2505
  sets.push("use_worktree = ?");
2432
2506
  params.push(updates.useWorktree ? 1 : 0);
@@ -2641,6 +2715,7 @@ function rowToTask(r) {
2641
2715
  ...r.agent_session_id != null && { agentSessionId: r.agent_session_id },
2642
2716
  ...r.branch != null && { branch: r.branch },
2643
2717
  ...r.use_worktree != null && r.use_worktree !== 0 && { useWorktree: true },
2718
+ ...r.worktree_path != null && { worktreePath: r.worktree_path },
2644
2719
  createdAt: r.created_at,
2645
2720
  updatedAt: r.updated_at,
2646
2721
  ...r.completed_at != null && { completedAt: r.completed_at },
@@ -2917,9 +2992,40 @@ var ConfigManager = class {
2917
2992
  }
2918
2993
  return seeded;
2919
2994
  }
2995
+ /** Авторитетный список задач читаем прямо из БД, минуя `cachedConfig`:
2996
+ * задачи пишутся и мимо ConfigManager (backfill коннектора, MCP
2997
+ * stdio-процесс), а кэш инвалидируется только собственными
2998
+ * saveConfig/notifyChanged. Сохранение поверх тёплого кэша означало бы
2999
+ * «удалить всё, что появилось после последней записи».
3000
+ *
3001
+ * Возвращает null, если чтение упало: подставлять сюда fallback из
3002
+ * loadConfig() нельзя — он отдаёт `tasks: []`, что для dbSaveConfig
3003
+ * равносильно «удалить все задачи». */
3004
+ readPersistedTasks() {
3005
+ try {
3006
+ return loadConfig().tasks ?? [];
3007
+ } catch (err) {
3008
+ logger_default.error({ err }, "[config-manager] failed to read tasks before save");
3009
+ return null;
3010
+ }
3011
+ }
2920
3012
  saveConfig(config) {
2921
3013
  try {
2922
- saveConfig(config);
3014
+ const mutation = config.__taskMutation;
3015
+ const persisted = { ...config };
3016
+ delete persisted.__taskMutation;
3017
+ delete config.__taskMutation;
3018
+ const currentTasks = this.readPersistedTasks();
3019
+ if (currentTasks === null) {
3020
+ delete persisted.tasks;
3021
+ } else {
3022
+ const tasks = applyTaskConfigMutation(currentTasks, mutation);
3023
+ if (config.tasks !== void 0 || currentTasks.length || mutation) {
3024
+ persisted.tasks = tasks;
3025
+ config.tasks = tasks;
3026
+ }
3027
+ }
3028
+ saveConfig(persisted);
2923
3029
  this.cachedConfig = null;
2924
3030
  } catch (err) {
2925
3031
  logger_default.error({ err }, "[config-manager] saveConfig failed");
@@ -4249,7 +4355,6 @@ function registerWorkspaceTools(server) {
4249
4355
 
4250
4356
  // src/tools/ask-user-question.ts
4251
4357
  import { z as z7 } from "zod";
4252
- var ASK_TIMEOUT_MS = 60 * 60 * 1e3;
4253
4358
  var questionSchema = z7.object({
4254
4359
  question: z7.string().min(1).max(1e3).describe("The question to ask the user."),
4255
4360
  // 12 символов — потолок «чипа» в карточке (как у встроенного
@@ -4302,7 +4407,7 @@ function registerAskUserQuestionTool(server) {
4302
4407
  const res = await rpcCall(
4303
4408
  "mcp:askUserQuestion",
4304
4409
  { terminalId, questions: normalized },
4305
- { timeoutMs: ASK_TIMEOUT_MS }
4410
+ { timeoutMs: MCP_ASK_TIMEOUT_MS }
4306
4411
  );
4307
4412
  if (res.skipped || !res.answers) {
4308
4413
  return {
@@ -4735,6 +4840,74 @@ function registerEmulatorTools(server) {
4735
4840
  );
4736
4841
  }
4737
4842
 
4843
+ // src/tools/flow.ts
4844
+ import { z as z9 } from "zod";
4845
+ function registerFlowTools(server) {
4846
+ server.tool(
4847
+ "set_acceptance_criteria",
4848
+ "Record the acceptance criteria for the work in this worktree: what a person will do and what they should see. Call this at the end of a discussion, before any code is written \u2014 the criteria are handed to the session that implements the work and to the one that accepts it. Replaces the list you recorded before, but never the criteria the human added by hand. Requires the BaseGrid app to be running.",
4849
+ {
4850
+ worktree_path: V.absolutePath.describe(
4851
+ "Absolute path of the worktree you are working in (your cwd)"
4852
+ ),
4853
+ criteria: z9.array(
4854
+ z9.object({
4855
+ text: V.title.describe("One checkable criterion, phrased as a user would"),
4856
+ task_id: V.id.optional().describe("Task this criterion comes from, if any")
4857
+ })
4858
+ ).min(1).max(30).describe("The full list \u2014 it replaces whatever was recorded before")
4859
+ },
4860
+ async (args) => {
4861
+ const flow = await rpcCall("worktree:flow:setCriteria", {
4862
+ cwd: args.worktree_path,
4863
+ // Пункты, дописанные человеком в полосе, вызов не трогает.
4864
+ fromAgent: true,
4865
+ criteria: args.criteria.map((c) => ({
4866
+ text: c.text,
4867
+ ...c.task_id ? { taskId: c.task_id } : {}
4868
+ }))
4869
+ });
4870
+ return { content: [{ type: "text", text: JSON.stringify(flow, null, 2) }] };
4871
+ }
4872
+ );
4873
+ server.tool(
4874
+ "set_criterion_status",
4875
+ "Record the verdict for ONE acceptance criterion during an acceptance pass, by its 1-based number as shown in the list. Only the acceptance tab may record verdicts \u2014 from the work tab the call is rejected. Call it as soon as you close a criterion, not in a batch at the end: the bar above the tabs is the scoreboard the human watches while you work. A verdict left only in your reply dies with the session \u2014 this one survives it. Requires the BaseGrid app to be running.",
4876
+ {
4877
+ worktree_path: V.absolutePath.describe(
4878
+ "Absolute path of the worktree you are working in (your cwd)"
4879
+ ),
4880
+ index: z9.number().int().min(1).max(30).describe("1-based position of the criterion in the recorded list"),
4881
+ status: z9.enum(["passed", "failed"]).describe("passed only when you actually ran it \u2014 never for something you only read"),
4882
+ evidence: V.title.optional().describe("What closed it: the command you ran, the file, the behaviour you saw")
4883
+ },
4884
+ async (args) => {
4885
+ const terminalId = process.env.BASEGRID_TERMINAL_ID;
4886
+ const flow = await rpcCall("worktree:flow:setCriterionStatus", {
4887
+ cwd: args.worktree_path,
4888
+ index: args.index,
4889
+ status: args.status,
4890
+ ...args.evidence ? { evidence: args.evidence } : {},
4891
+ ...terminalId ? { terminalId } : {}
4892
+ });
4893
+ return { content: [{ type: "text", text: JSON.stringify(flow, null, 2) }] };
4894
+ }
4895
+ );
4896
+ server.tool(
4897
+ "get_acceptance_criteria",
4898
+ "Read the acceptance criteria and current step recorded for a worktree. Returns null when nothing has been recorded yet.",
4899
+ {
4900
+ worktree_path: V.absolutePath.describe("Absolute path of the worktree (your cwd)")
4901
+ },
4902
+ async (args) => {
4903
+ const flow = await rpcCall("worktree:flow:get", {
4904
+ cwd: args.worktree_path
4905
+ });
4906
+ return { content: [{ type: "text", text: JSON.stringify(flow, null, 2) }] };
4907
+ }
4908
+ );
4909
+ }
4910
+
4738
4911
  // src/server.ts
4739
4912
  function createMcpServer(version) {
4740
4913
  const server = new McpServer({ name: "basegrid", version }, { capabilities: { tools: {} } });
@@ -4746,6 +4919,7 @@ function createMcpServer(version) {
4746
4919
  registerWorkspaceTools(server);
4747
4920
  registerAskUserQuestionTool(server);
4748
4921
  registerEmulatorTools(server);
4922
+ registerFlowTools(server);
4749
4923
  return server;
4750
4924
  }
4751
4925
 
@@ -4758,7 +4932,7 @@ console.warn = (...args) => _origError("[mcp:warn]", ...args);
4758
4932
  console.error = (...args) => _origError("[mcp:error]", ...args);
4759
4933
  async function main() {
4760
4934
  configManager.init();
4761
- const version = true ? "0.18.13" : createRequire(import.meta.url)("../package.json").version;
4935
+ const version = true ? "0.18.14" : createRequire(import.meta.url)("../package.json").version;
4762
4936
  const server = createMcpServer(version);
4763
4937
  const transport = new StdioServerTransport();
4764
4938
  await server.connect(transport);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@basegrid_tech/mcp",
3
- "version": "0.18.13",
3
+ "version": "0.18.14",
4
4
  "description": "BaseGrid MCP server — task management, git, and workflow tools for AI coding agents",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -35,17 +35,17 @@
35
35
  "dev": "tsx src/index.ts"
36
36
  },
37
37
  "dependencies": {
38
- "@modelcontextprotocol/sdk": "^1.29.0",
39
- "libsql": "^0.5.29",
40
- "pino": "^10.3.1",
41
- "ws": "^8.20.0",
42
- "zod": "^4.3.6"
38
+ "@modelcontextprotocol/sdk": "1.29.0",
39
+ "libsql": "0.5.29",
40
+ "pino": "10.3.1",
41
+ "ws": "8.21.0",
42
+ "zod": "4.3.6"
43
43
  },
44
44
  "devDependencies": {
45
- "@basegrid/server": "0.18.13",
46
- "@basegrid/shared": "0.18.13",
47
- "tsup": "^8.5.1",
48
- "tsx": "^4.21.0",
49
- "typescript": "^6.0.3"
45
+ "@basegrid/server": "workspace:*",
46
+ "@basegrid/shared": "workspace:*",
47
+ "tsup": "8.5.1",
48
+ "tsx": "4.21.0",
49
+ "typescript": "6.0.3"
50
50
  }
51
- }
51
+ }