@basegrid_tech/mcp 0.18.13 → 0.18.14-beta.1
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/index.js +189 -15
- 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
|
-
|
|
2311
|
-
|
|
2312
|
-
(r) => r.id
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
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
|
-
|
|
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:
|
|
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.
|
|
4935
|
+
const version = true ? "0.18.14-beta.1" : 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.
|
|
3
|
+
"version": "0.18.14-beta.1",
|
|
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": "
|
|
39
|
-
"libsql": "
|
|
40
|
-
"pino": "
|
|
41
|
-
"ws": "
|
|
42
|
-
"zod": "
|
|
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": "
|
|
46
|
-
"@basegrid/shared": "
|
|
47
|
-
"tsup": "
|
|
48
|
-
"tsx": "
|
|
49
|
-
"typescript": "
|
|
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
|
+
}
|