@contextstream/mcp-server 0.3.20 → 0.3.22
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 +79 -334
- package/dist/index.js +738 -524
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4611,7 +4611,9 @@ var CacheTTL = {
|
|
|
4611
4611
|
// Search results - cache for 60 seconds
|
|
4612
4612
|
SEARCH: 60 * 1e3,
|
|
4613
4613
|
// User preferences - cache for 5 minutes
|
|
4614
|
-
USER_PREFS: 5 * 60 * 1e3
|
|
4614
|
+
USER_PREFS: 5 * 60 * 1e3,
|
|
4615
|
+
// Credits/plan - cache briefly to reflect upgrades quickly
|
|
4616
|
+
CREDIT_BALANCE: 60 * 1e3
|
|
4615
4617
|
};
|
|
4616
4618
|
var CacheKeys = {
|
|
4617
4619
|
workspace: (id) => `workspace:${id}`,
|
|
@@ -4620,7 +4622,8 @@ var CacheKeys = {
|
|
|
4620
4622
|
projectList: (workspaceId) => `projects:${workspaceId}`,
|
|
4621
4623
|
sessionInit: (workspaceId, projectId) => `session_init:${workspaceId || ""}:${projectId || ""}`,
|
|
4622
4624
|
memoryEvents: (workspaceId) => `memory:${workspaceId}`,
|
|
4623
|
-
search: (query, workspaceId) => `search:${workspaceId || ""}:${query}
|
|
4625
|
+
search: (query, workspaceId) => `search:${workspaceId || ""}:${query}`,
|
|
4626
|
+
creditBalance: () => "credits:balance"
|
|
4624
4627
|
};
|
|
4625
4628
|
var globalCache = new MemoryCache();
|
|
4626
4629
|
|
|
@@ -4666,6 +4669,25 @@ var ContextStreamClient = class {
|
|
|
4666
4669
|
me() {
|
|
4667
4670
|
return request(this.config, "/auth/me");
|
|
4668
4671
|
}
|
|
4672
|
+
// Credits / Billing (used for plan gating)
|
|
4673
|
+
async getCreditBalance() {
|
|
4674
|
+
const cacheKey = CacheKeys.creditBalance();
|
|
4675
|
+
const cached = globalCache.get(cacheKey);
|
|
4676
|
+
if (cached) return cached;
|
|
4677
|
+
const result = await request(this.config, "/credits/balance", { method: "GET" });
|
|
4678
|
+
const data = result && typeof result === "object" && "data" in result && result.data ? result.data : result;
|
|
4679
|
+
globalCache.set(cacheKey, data, CacheTTL.CREDIT_BALANCE);
|
|
4680
|
+
return data;
|
|
4681
|
+
}
|
|
4682
|
+
async getPlanName() {
|
|
4683
|
+
try {
|
|
4684
|
+
const balance = await this.getCreditBalance();
|
|
4685
|
+
const planName = balance?.plan?.name;
|
|
4686
|
+
return typeof planName === "string" ? planName.toLowerCase() : null;
|
|
4687
|
+
} catch {
|
|
4688
|
+
return null;
|
|
4689
|
+
}
|
|
4690
|
+
}
|
|
4669
4691
|
// Workspaces & Projects
|
|
4670
4692
|
listWorkspaces(params) {
|
|
4671
4693
|
const query = new URLSearchParams();
|
|
@@ -5053,22 +5075,15 @@ var ContextStreamClient = class {
|
|
|
5053
5075
|
return context;
|
|
5054
5076
|
}
|
|
5055
5077
|
} else {
|
|
5056
|
-
const
|
|
5057
|
-
|
|
5058
|
-
|
|
5059
|
-
|
|
5060
|
-
|
|
5061
|
-
|
|
5062
|
-
|
|
5063
|
-
|
|
5064
|
-
|
|
5065
|
-
context.workspace_created = true;
|
|
5066
|
-
writeLocalConfig(rootPath, {
|
|
5067
|
-
workspace_id: newWorkspace.id,
|
|
5068
|
-
workspace_name: newWorkspace.name,
|
|
5069
|
-
associated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
5070
|
-
});
|
|
5071
|
-
}
|
|
5078
|
+
const folderDisplayName = rootPath?.split("/").pop() || "this folder";
|
|
5079
|
+
context.status = "requires_workspace_name";
|
|
5080
|
+
context.workspace_source = "none_found";
|
|
5081
|
+
context.ide_roots = ideRoots;
|
|
5082
|
+
context.folder_name = folderDisplayName;
|
|
5083
|
+
context.folder_path = rootPath;
|
|
5084
|
+
context.suggested_project_name = folderDisplayName;
|
|
5085
|
+
context.message = `No workspaces found for this account. Ask the user for a name for a new workspace, then create a project for "${folderDisplayName}".`;
|
|
5086
|
+
return context;
|
|
5072
5087
|
}
|
|
5073
5088
|
} catch (e) {
|
|
5074
5089
|
context.workspace_error = String(e);
|
|
@@ -6455,6 +6470,39 @@ function toStructured(data) {
|
|
|
6455
6470
|
return void 0;
|
|
6456
6471
|
}
|
|
6457
6472
|
function registerTools(server, client, sessionManager) {
|
|
6473
|
+
const upgradeUrl2 = process.env.CONTEXTSTREAM_UPGRADE_URL || "https://contextstream.io/pricing";
|
|
6474
|
+
const defaultProTools = /* @__PURE__ */ new Set([
|
|
6475
|
+
// AI endpoints (typically paid/credit-metered)
|
|
6476
|
+
"ai_context",
|
|
6477
|
+
"ai_enhanced_context",
|
|
6478
|
+
"ai_context_budget",
|
|
6479
|
+
"ai_embeddings",
|
|
6480
|
+
"ai_plan",
|
|
6481
|
+
"ai_tasks"
|
|
6482
|
+
]);
|
|
6483
|
+
const proTools = (() => {
|
|
6484
|
+
const raw = process.env.CONTEXTSTREAM_PRO_TOOLS;
|
|
6485
|
+
if (!raw) return defaultProTools;
|
|
6486
|
+
const parsed = raw.split(",").map((t) => t.trim()).filter(Boolean);
|
|
6487
|
+
return parsed.length > 0 ? new Set(parsed) : defaultProTools;
|
|
6488
|
+
})();
|
|
6489
|
+
function getToolAccessTier(toolName) {
|
|
6490
|
+
return proTools.has(toolName) ? "pro" : "free";
|
|
6491
|
+
}
|
|
6492
|
+
function getToolAccessLabel(toolName) {
|
|
6493
|
+
return getToolAccessTier(toolName) === "pro" ? "PRO" : "Free";
|
|
6494
|
+
}
|
|
6495
|
+
async function gateIfProTool(toolName) {
|
|
6496
|
+
if (getToolAccessTier(toolName) !== "pro") return null;
|
|
6497
|
+
const planName = await client.getPlanName();
|
|
6498
|
+
if (planName !== "free") return null;
|
|
6499
|
+
return errorResult(
|
|
6500
|
+
[
|
|
6501
|
+
`Access denied: \`${toolName}\` requires ContextStream PRO.`,
|
|
6502
|
+
`Upgrade: ${upgradeUrl2}`
|
|
6503
|
+
].join("\n")
|
|
6504
|
+
);
|
|
6505
|
+
}
|
|
6458
6506
|
function wrapWithAutoContext(toolName, handler) {
|
|
6459
6507
|
if (!sessionManager) {
|
|
6460
6508
|
return handler;
|
|
@@ -6483,8 +6531,18 @@ function registerTools(server, client, sessionManager) {
|
|
|
6483
6531
|
};
|
|
6484
6532
|
}
|
|
6485
6533
|
function registerTool(name, config, handler) {
|
|
6534
|
+
const accessLabel = getToolAccessLabel(name);
|
|
6535
|
+
const labeledConfig = {
|
|
6536
|
+
...config,
|
|
6537
|
+
title: `${config.title} (${accessLabel})`,
|
|
6538
|
+
description: `${config.description}
|
|
6539
|
+
|
|
6540
|
+
Access: ${accessLabel}${accessLabel === "PRO" ? ` (upgrade: ${upgradeUrl2})` : ""}`
|
|
6541
|
+
};
|
|
6486
6542
|
const safeHandler = async (input) => {
|
|
6487
6543
|
try {
|
|
6544
|
+
const gated = await gateIfProTool(name);
|
|
6545
|
+
if (gated) return gated;
|
|
6488
6546
|
return await handler(input);
|
|
6489
6547
|
} catch (error) {
|
|
6490
6548
|
const errorMessage = error?.message || String(error);
|
|
@@ -6498,10 +6556,26 @@ function registerTools(server, client, sessionManager) {
|
|
|
6498
6556
|
};
|
|
6499
6557
|
server.registerTool(
|
|
6500
6558
|
name,
|
|
6501
|
-
|
|
6559
|
+
labeledConfig,
|
|
6502
6560
|
wrapWithAutoContext(name, safeHandler)
|
|
6503
6561
|
);
|
|
6504
6562
|
}
|
|
6563
|
+
function errorResult(text) {
|
|
6564
|
+
return {
|
|
6565
|
+
content: [{ type: "text", text }],
|
|
6566
|
+
isError: true
|
|
6567
|
+
};
|
|
6568
|
+
}
|
|
6569
|
+
function resolveWorkspaceId(explicitWorkspaceId) {
|
|
6570
|
+
if (explicitWorkspaceId) return explicitWorkspaceId;
|
|
6571
|
+
const ctx = sessionManager?.getContext();
|
|
6572
|
+
return typeof ctx?.workspace_id === "string" ? ctx.workspace_id : void 0;
|
|
6573
|
+
}
|
|
6574
|
+
function resolveProjectId(explicitProjectId) {
|
|
6575
|
+
if (explicitProjectId) return explicitProjectId;
|
|
6576
|
+
const ctx = sessionManager?.getContext();
|
|
6577
|
+
return typeof ctx?.project_id === "string" ? ctx.project_id : void 0;
|
|
6578
|
+
}
|
|
6505
6579
|
registerTool(
|
|
6506
6580
|
"auth_me",
|
|
6507
6581
|
{
|
|
@@ -6638,10 +6712,14 @@ function registerTools(server, client, sessionManager) {
|
|
|
6638
6712
|
{
|
|
6639
6713
|
title: "Index project",
|
|
6640
6714
|
description: "Trigger indexing for a project",
|
|
6641
|
-
inputSchema: external_exports.object({ project_id: external_exports.string().uuid() })
|
|
6715
|
+
inputSchema: external_exports.object({ project_id: external_exports.string().uuid().optional() })
|
|
6642
6716
|
},
|
|
6643
6717
|
async (input) => {
|
|
6644
|
-
const
|
|
6718
|
+
const projectId = resolveProjectId(input.project_id);
|
|
6719
|
+
if (!projectId) {
|
|
6720
|
+
return errorResult("Error: project_id is required. Please call session_init first or provide project_id explicitly.");
|
|
6721
|
+
}
|
|
6722
|
+
const result = await client.indexProject(projectId);
|
|
6645
6723
|
return { content: [{ type: "text", text: formatContent(result) }], structuredContent: toStructured(result) };
|
|
6646
6724
|
}
|
|
6647
6725
|
);
|
|
@@ -6991,10 +7069,14 @@ function registerTools(server, client, sessionManager) {
|
|
|
6991
7069
|
{
|
|
6992
7070
|
title: "Get project",
|
|
6993
7071
|
description: "Get project details by ID",
|
|
6994
|
-
inputSchema: external_exports.object({ project_id: external_exports.string().uuid() })
|
|
7072
|
+
inputSchema: external_exports.object({ project_id: external_exports.string().uuid().optional() })
|
|
6995
7073
|
},
|
|
6996
7074
|
async (input) => {
|
|
6997
|
-
const
|
|
7075
|
+
const projectId = resolveProjectId(input.project_id);
|
|
7076
|
+
if (!projectId) {
|
|
7077
|
+
return errorResult("Error: project_id is required. Please call session_init first or provide project_id explicitly.");
|
|
7078
|
+
}
|
|
7079
|
+
const result = await client.getProject(projectId);
|
|
6998
7080
|
return { content: [{ type: "text", text: formatContent(result) }], structuredContent: toStructured(result) };
|
|
6999
7081
|
}
|
|
7000
7082
|
);
|
|
@@ -7003,10 +7085,14 @@ function registerTools(server, client, sessionManager) {
|
|
|
7003
7085
|
{
|
|
7004
7086
|
title: "Project overview",
|
|
7005
7087
|
description: "Get project overview with summary information",
|
|
7006
|
-
inputSchema: external_exports.object({ project_id: external_exports.string().uuid() })
|
|
7088
|
+
inputSchema: external_exports.object({ project_id: external_exports.string().uuid().optional() })
|
|
7007
7089
|
},
|
|
7008
7090
|
async (input) => {
|
|
7009
|
-
const
|
|
7091
|
+
const projectId = resolveProjectId(input.project_id);
|
|
7092
|
+
if (!projectId) {
|
|
7093
|
+
return errorResult("Error: project_id is required. Please call session_init first or provide project_id explicitly.");
|
|
7094
|
+
}
|
|
7095
|
+
const result = await client.projectOverview(projectId);
|
|
7010
7096
|
return { content: [{ type: "text", text: formatContent(result) }], structuredContent: toStructured(result) };
|
|
7011
7097
|
}
|
|
7012
7098
|
);
|
|
@@ -7015,10 +7101,14 @@ function registerTools(server, client, sessionManager) {
|
|
|
7015
7101
|
{
|
|
7016
7102
|
title: "Project statistics",
|
|
7017
7103
|
description: "Get project statistics (files, lines, complexity)",
|
|
7018
|
-
inputSchema: external_exports.object({ project_id: external_exports.string().uuid() })
|
|
7104
|
+
inputSchema: external_exports.object({ project_id: external_exports.string().uuid().optional() })
|
|
7019
7105
|
},
|
|
7020
7106
|
async (input) => {
|
|
7021
|
-
const
|
|
7107
|
+
const projectId = resolveProjectId(input.project_id);
|
|
7108
|
+
if (!projectId) {
|
|
7109
|
+
return errorResult("Error: project_id is required. Please call session_init first or provide project_id explicitly.");
|
|
7110
|
+
}
|
|
7111
|
+
const result = await client.projectStatistics(projectId);
|
|
7022
7112
|
return { content: [{ type: "text", text: formatContent(result) }], structuredContent: toStructured(result) };
|
|
7023
7113
|
}
|
|
7024
7114
|
);
|
|
@@ -7027,10 +7117,14 @@ function registerTools(server, client, sessionManager) {
|
|
|
7027
7117
|
{
|
|
7028
7118
|
title: "List project files",
|
|
7029
7119
|
description: "List all indexed files in a project",
|
|
7030
|
-
inputSchema: external_exports.object({ project_id: external_exports.string().uuid() })
|
|
7120
|
+
inputSchema: external_exports.object({ project_id: external_exports.string().uuid().optional() })
|
|
7031
7121
|
},
|
|
7032
7122
|
async (input) => {
|
|
7033
|
-
const
|
|
7123
|
+
const projectId = resolveProjectId(input.project_id);
|
|
7124
|
+
if (!projectId) {
|
|
7125
|
+
return errorResult("Error: project_id is required. Please call session_init first or provide project_id explicitly.");
|
|
7126
|
+
}
|
|
7127
|
+
const result = await client.projectFiles(projectId);
|
|
7034
7128
|
return { content: [{ type: "text", text: formatContent(result) }], structuredContent: toStructured(result) };
|
|
7035
7129
|
}
|
|
7036
7130
|
);
|
|
@@ -7039,10 +7133,14 @@ function registerTools(server, client, sessionManager) {
|
|
|
7039
7133
|
{
|
|
7040
7134
|
title: "Index status",
|
|
7041
7135
|
description: "Get project indexing status",
|
|
7042
|
-
inputSchema: external_exports.object({ project_id: external_exports.string().uuid() })
|
|
7136
|
+
inputSchema: external_exports.object({ project_id: external_exports.string().uuid().optional() })
|
|
7043
7137
|
},
|
|
7044
7138
|
async (input) => {
|
|
7045
|
-
const
|
|
7139
|
+
const projectId = resolveProjectId(input.project_id);
|
|
7140
|
+
if (!projectId) {
|
|
7141
|
+
return errorResult("Error: project_id is required. Please call session_init first or provide project_id explicitly.");
|
|
7142
|
+
}
|
|
7143
|
+
const result = await client.projectIndexStatus(projectId);
|
|
7046
7144
|
return { content: [{ type: "text", text: formatContent(result) }], structuredContent: toStructured(result) };
|
|
7047
7145
|
}
|
|
7048
7146
|
);
|
|
@@ -7054,18 +7152,22 @@ function registerTools(server, client, sessionManager) {
|
|
|
7054
7152
|
This indexes your entire project by reading files in batches.
|
|
7055
7153
|
Automatically detects code files and skips ignored directories like node_modules, target, dist, etc.`,
|
|
7056
7154
|
inputSchema: external_exports.object({
|
|
7057
|
-
project_id: external_exports.string().uuid().describe("Project to ingest files into"),
|
|
7155
|
+
project_id: external_exports.string().uuid().optional().describe("Project to ingest files into (defaults to current session project)"),
|
|
7058
7156
|
path: external_exports.string().describe("Local directory path to read files from")
|
|
7059
7157
|
})
|
|
7060
7158
|
},
|
|
7061
7159
|
async (input) => {
|
|
7160
|
+
const projectId = resolveProjectId(input.project_id);
|
|
7161
|
+
if (!projectId) {
|
|
7162
|
+
return errorResult("Error: project_id is required. Please call session_init first or provide project_id explicitly.");
|
|
7163
|
+
}
|
|
7062
7164
|
(async () => {
|
|
7063
7165
|
try {
|
|
7064
7166
|
let totalIndexed = 0;
|
|
7065
7167
|
let batchCount = 0;
|
|
7066
|
-
console.error(`[ContextStream] Starting background ingestion for project ${
|
|
7168
|
+
console.error(`[ContextStream] Starting background ingestion for project ${projectId} from ${input.path}`);
|
|
7067
7169
|
for await (const batch of readAllFilesInBatches(input.path, { batchSize: 50 })) {
|
|
7068
|
-
const result = await client.ingestFiles(
|
|
7170
|
+
const result = await client.ingestFiles(projectId, batch);
|
|
7069
7171
|
totalIndexed += result.data?.files_indexed ?? batch.length;
|
|
7070
7172
|
batchCount++;
|
|
7071
7173
|
}
|
|
@@ -7077,7 +7179,7 @@ Automatically detects code files and skips ignored directories like node_modules
|
|
|
7077
7179
|
const summary = {
|
|
7078
7180
|
status: "started",
|
|
7079
7181
|
message: "Ingestion running in background",
|
|
7080
|
-
project_id:
|
|
7182
|
+
project_id: projectId,
|
|
7081
7183
|
path: input.path,
|
|
7082
7184
|
note: "Use 'projects_index_status' to monitor progress."
|
|
7083
7185
|
};
|
|
@@ -7095,10 +7197,14 @@ Automatically detects code files and skips ignored directories like node_modules
|
|
|
7095
7197
|
{
|
|
7096
7198
|
title: "Get workspace",
|
|
7097
7199
|
description: "Get workspace details by ID",
|
|
7098
|
-
inputSchema: external_exports.object({ workspace_id: external_exports.string().uuid() })
|
|
7200
|
+
inputSchema: external_exports.object({ workspace_id: external_exports.string().uuid().optional() })
|
|
7099
7201
|
},
|
|
7100
7202
|
async (input) => {
|
|
7101
|
-
const
|
|
7203
|
+
const workspaceId = resolveWorkspaceId(input.workspace_id);
|
|
7204
|
+
if (!workspaceId) {
|
|
7205
|
+
return errorResult("Error: workspace_id is required. Please call session_init first or provide workspace_id explicitly.");
|
|
7206
|
+
}
|
|
7207
|
+
const result = await client.getWorkspace(workspaceId);
|
|
7102
7208
|
return { content: [{ type: "text", text: formatContent(result) }], structuredContent: toStructured(result) };
|
|
7103
7209
|
}
|
|
7104
7210
|
);
|
|
@@ -7107,10 +7213,14 @@ Automatically detects code files and skips ignored directories like node_modules
|
|
|
7107
7213
|
{
|
|
7108
7214
|
title: "Workspace overview",
|
|
7109
7215
|
description: "Get workspace overview with summary information",
|
|
7110
|
-
inputSchema: external_exports.object({ workspace_id: external_exports.string().uuid() })
|
|
7216
|
+
inputSchema: external_exports.object({ workspace_id: external_exports.string().uuid().optional() })
|
|
7111
7217
|
},
|
|
7112
7218
|
async (input) => {
|
|
7113
|
-
const
|
|
7219
|
+
const workspaceId = resolveWorkspaceId(input.workspace_id);
|
|
7220
|
+
if (!workspaceId) {
|
|
7221
|
+
return errorResult("Error: workspace_id is required. Please call session_init first or provide workspace_id explicitly.");
|
|
7222
|
+
}
|
|
7223
|
+
const result = await client.workspaceOverview(workspaceId);
|
|
7114
7224
|
return { content: [{ type: "text", text: formatContent(result) }], structuredContent: toStructured(result) };
|
|
7115
7225
|
}
|
|
7116
7226
|
);
|
|
@@ -7119,10 +7229,14 @@ Automatically detects code files and skips ignored directories like node_modules
|
|
|
7119
7229
|
{
|
|
7120
7230
|
title: "Workspace analytics",
|
|
7121
7231
|
description: "Get workspace usage analytics",
|
|
7122
|
-
inputSchema: external_exports.object({ workspace_id: external_exports.string().uuid() })
|
|
7232
|
+
inputSchema: external_exports.object({ workspace_id: external_exports.string().uuid().optional() })
|
|
7123
7233
|
},
|
|
7124
7234
|
async (input) => {
|
|
7125
|
-
const
|
|
7235
|
+
const workspaceId = resolveWorkspaceId(input.workspace_id);
|
|
7236
|
+
if (!workspaceId) {
|
|
7237
|
+
return errorResult("Error: workspace_id is required. Please call session_init first or provide workspace_id explicitly.");
|
|
7238
|
+
}
|
|
7239
|
+
const result = await client.workspaceAnalytics(workspaceId);
|
|
7126
7240
|
return { content: [{ type: "text", text: formatContent(result) }], structuredContent: toStructured(result) };
|
|
7127
7241
|
}
|
|
7128
7242
|
);
|
|
@@ -7131,10 +7245,14 @@ Automatically detects code files and skips ignored directories like node_modules
|
|
|
7131
7245
|
{
|
|
7132
7246
|
title: "Workspace content",
|
|
7133
7247
|
description: "List content in a workspace",
|
|
7134
|
-
inputSchema: external_exports.object({ workspace_id: external_exports.string().uuid() })
|
|
7248
|
+
inputSchema: external_exports.object({ workspace_id: external_exports.string().uuid().optional() })
|
|
7135
7249
|
},
|
|
7136
7250
|
async (input) => {
|
|
7137
|
-
const
|
|
7251
|
+
const workspaceId = resolveWorkspaceId(input.workspace_id);
|
|
7252
|
+
if (!workspaceId) {
|
|
7253
|
+
return errorResult("Error: workspace_id is required. Please call session_init first or provide workspace_id explicitly.");
|
|
7254
|
+
}
|
|
7255
|
+
const result = await client.workspaceContent(workspaceId);
|
|
7138
7256
|
return { content: [{ type: "text", text: formatContent(result) }], structuredContent: toStructured(result) };
|
|
7139
7257
|
}
|
|
7140
7258
|
);
|
|
@@ -7256,10 +7374,14 @@ Automatically detects code files and skips ignored directories like node_modules
|
|
|
7256
7374
|
{
|
|
7257
7375
|
title: "Memory timeline",
|
|
7258
7376
|
description: "Get chronological timeline of memory events for a workspace",
|
|
7259
|
-
inputSchema: external_exports.object({ workspace_id: external_exports.string().uuid() })
|
|
7377
|
+
inputSchema: external_exports.object({ workspace_id: external_exports.string().uuid().optional() })
|
|
7260
7378
|
},
|
|
7261
7379
|
async (input) => {
|
|
7262
|
-
const
|
|
7380
|
+
const workspaceId = resolveWorkspaceId(input.workspace_id);
|
|
7381
|
+
if (!workspaceId) {
|
|
7382
|
+
return errorResult("Error: workspace_id is required. Please call session_init first or provide workspace_id explicitly.");
|
|
7383
|
+
}
|
|
7384
|
+
const result = await client.memoryTimeline(workspaceId);
|
|
7263
7385
|
return { content: [{ type: "text", text: formatContent(result) }], structuredContent: toStructured(result) };
|
|
7264
7386
|
}
|
|
7265
7387
|
);
|
|
@@ -7268,10 +7390,14 @@ Automatically detects code files and skips ignored directories like node_modules
|
|
|
7268
7390
|
{
|
|
7269
7391
|
title: "Memory summary",
|
|
7270
7392
|
description: "Get condensed summary of workspace memory",
|
|
7271
|
-
inputSchema: external_exports.object({ workspace_id: external_exports.string().uuid() })
|
|
7393
|
+
inputSchema: external_exports.object({ workspace_id: external_exports.string().uuid().optional() })
|
|
7272
7394
|
},
|
|
7273
7395
|
async (input) => {
|
|
7274
|
-
const
|
|
7396
|
+
const workspaceId = resolveWorkspaceId(input.workspace_id);
|
|
7397
|
+
if (!workspaceId) {
|
|
7398
|
+
return errorResult("Error: workspace_id is required. Please call session_init first or provide workspace_id explicitly.");
|
|
7399
|
+
}
|
|
7400
|
+
const result = await client.memorySummary(workspaceId);
|
|
7275
7401
|
return { content: [{ type: "text", text: formatContent(result) }], structuredContent: toStructured(result) };
|
|
7276
7402
|
}
|
|
7277
7403
|
);
|
|
@@ -7280,10 +7406,14 @@ Automatically detects code files and skips ignored directories like node_modules
|
|
|
7280
7406
|
{
|
|
7281
7407
|
title: "Find circular dependencies",
|
|
7282
7408
|
description: "Detect circular dependencies in project code",
|
|
7283
|
-
inputSchema: external_exports.object({ project_id: external_exports.string().uuid() })
|
|
7409
|
+
inputSchema: external_exports.object({ project_id: external_exports.string().uuid().optional() })
|
|
7284
7410
|
},
|
|
7285
7411
|
async (input) => {
|
|
7286
|
-
const
|
|
7412
|
+
const projectId = resolveProjectId(input.project_id);
|
|
7413
|
+
if (!projectId) {
|
|
7414
|
+
return errorResult("Error: project_id is required. Please call session_init first or provide project_id explicitly.");
|
|
7415
|
+
}
|
|
7416
|
+
const result = await client.findCircularDependencies(projectId);
|
|
7287
7417
|
return { content: [{ type: "text", text: formatContent(result) }], structuredContent: toStructured(result) };
|
|
7288
7418
|
}
|
|
7289
7419
|
);
|
|
@@ -7292,10 +7422,14 @@ Automatically detects code files and skips ignored directories like node_modules
|
|
|
7292
7422
|
{
|
|
7293
7423
|
title: "Find unused code",
|
|
7294
7424
|
description: "Detect unused code in project",
|
|
7295
|
-
inputSchema: external_exports.object({ project_id: external_exports.string().uuid() })
|
|
7425
|
+
inputSchema: external_exports.object({ project_id: external_exports.string().uuid().optional() })
|
|
7296
7426
|
},
|
|
7297
7427
|
async (input) => {
|
|
7298
|
-
const
|
|
7428
|
+
const projectId = resolveProjectId(input.project_id);
|
|
7429
|
+
if (!projectId) {
|
|
7430
|
+
return errorResult("Error: project_id is required. Please call session_init first or provide project_id explicitly.");
|
|
7431
|
+
}
|
|
7432
|
+
const result = await client.findUnusedCode(projectId);
|
|
7299
7433
|
return { content: [{ type: "text", text: formatContent(result) }], structuredContent: toStructured(result) };
|
|
7300
7434
|
}
|
|
7301
7435
|
);
|
|
@@ -7440,6 +7574,132 @@ Optionally generates AI editor rules for automatic ContextStream usage.`,
|
|
|
7440
7574
|
return { content: [{ type: "text", text: formatContent(response) }], structuredContent: toStructured(response) };
|
|
7441
7575
|
}
|
|
7442
7576
|
);
|
|
7577
|
+
registerTool(
|
|
7578
|
+
"workspace_bootstrap",
|
|
7579
|
+
{
|
|
7580
|
+
title: "Create workspace + project from folder",
|
|
7581
|
+
description: `Create a new workspace (user-provided name) and onboard the current folder as a project.
|
|
7582
|
+
This is useful when session_init returns status='requires_workspace_name' (no workspaces exist yet) or when you want to create a new workspace for a repo.
|
|
7583
|
+
|
|
7584
|
+
Behavior:
|
|
7585
|
+
- Creates a workspace with the given name
|
|
7586
|
+
- Associates the folder to that workspace (writes .contextstream/config.json)
|
|
7587
|
+
- Initializes a session for the folder, which creates the project (folder name) and starts indexing (if enabled)`,
|
|
7588
|
+
inputSchema: external_exports.object({
|
|
7589
|
+
workspace_name: external_exports.string().min(1).describe("Name for the new workspace (ask the user)"),
|
|
7590
|
+
folder_path: external_exports.string().optional().describe("Absolute folder path (defaults to IDE root/cwd)"),
|
|
7591
|
+
description: external_exports.string().optional().describe("Optional workspace description"),
|
|
7592
|
+
visibility: external_exports.enum(["private", "public"]).optional().describe("Workspace visibility (default: private)"),
|
|
7593
|
+
create_parent_mapping: external_exports.boolean().optional().describe("Also create a parent folder mapping (e.g., /dev/company/* -> workspace)"),
|
|
7594
|
+
generate_editor_rules: external_exports.boolean().optional().describe("Generate AI editor rules in the folder for automatic ContextStream usage"),
|
|
7595
|
+
context_hint: external_exports.string().optional().describe("Optional context hint for session initialization"),
|
|
7596
|
+
auto_index: external_exports.boolean().optional().describe("Automatically create and index project from folder (default: true)")
|
|
7597
|
+
})
|
|
7598
|
+
},
|
|
7599
|
+
async (input) => {
|
|
7600
|
+
let folderPath = input.folder_path;
|
|
7601
|
+
if (!folderPath) {
|
|
7602
|
+
try {
|
|
7603
|
+
const rootsResponse = await server.server.listRoots();
|
|
7604
|
+
if (rootsResponse?.roots && rootsResponse.roots.length > 0) {
|
|
7605
|
+
folderPath = rootsResponse.roots[0].uri.replace("file://", "");
|
|
7606
|
+
}
|
|
7607
|
+
} catch {
|
|
7608
|
+
}
|
|
7609
|
+
}
|
|
7610
|
+
if (!folderPath) {
|
|
7611
|
+
folderPath = process.cwd();
|
|
7612
|
+
}
|
|
7613
|
+
if (!folderPath) {
|
|
7614
|
+
return errorResult("Error: folder_path is required. Provide folder_path or run from a project directory.");
|
|
7615
|
+
}
|
|
7616
|
+
const folderName = folderPath.split("/").pop() || "My Project";
|
|
7617
|
+
let newWorkspace;
|
|
7618
|
+
try {
|
|
7619
|
+
newWorkspace = await client.createWorkspace({
|
|
7620
|
+
name: input.workspace_name,
|
|
7621
|
+
description: input.description || `Workspace created for ${folderPath}`,
|
|
7622
|
+
visibility: input.visibility || "private"
|
|
7623
|
+
});
|
|
7624
|
+
} catch (err) {
|
|
7625
|
+
const message = err?.message || String(err);
|
|
7626
|
+
if (typeof message === "string" && message.includes("workspaces_slug_key")) {
|
|
7627
|
+
return errorResult(
|
|
7628
|
+
[
|
|
7629
|
+
"Failed to create workspace: the workspace slug is already taken (or reserved by a deleted workspace).",
|
|
7630
|
+
"",
|
|
7631
|
+
"Try a slightly different workspace name (e.g., add a suffix) and re-run `workspace_bootstrap`."
|
|
7632
|
+
].join("\n")
|
|
7633
|
+
);
|
|
7634
|
+
}
|
|
7635
|
+
throw err;
|
|
7636
|
+
}
|
|
7637
|
+
if (!newWorkspace?.id) {
|
|
7638
|
+
return errorResult("Error: failed to create workspace.");
|
|
7639
|
+
}
|
|
7640
|
+
const associateResult = await client.associateWorkspace({
|
|
7641
|
+
folder_path: folderPath,
|
|
7642
|
+
workspace_id: newWorkspace.id,
|
|
7643
|
+
workspace_name: newWorkspace.name || input.workspace_name,
|
|
7644
|
+
create_parent_mapping: input.create_parent_mapping
|
|
7645
|
+
});
|
|
7646
|
+
let rulesGenerated = [];
|
|
7647
|
+
if (input.generate_editor_rules) {
|
|
7648
|
+
const fs3 = await import("fs");
|
|
7649
|
+
const path3 = await import("path");
|
|
7650
|
+
for (const editor of getAvailableEditors()) {
|
|
7651
|
+
const rule = generateRuleContent(editor, {
|
|
7652
|
+
workspaceName: newWorkspace.name || input.workspace_name,
|
|
7653
|
+
workspaceId: newWorkspace.id
|
|
7654
|
+
});
|
|
7655
|
+
if (!rule) continue;
|
|
7656
|
+
const filePath = path3.join(folderPath, rule.filename);
|
|
7657
|
+
try {
|
|
7658
|
+
let existingContent = "";
|
|
7659
|
+
try {
|
|
7660
|
+
existingContent = fs3.readFileSync(filePath, "utf-8");
|
|
7661
|
+
} catch {
|
|
7662
|
+
}
|
|
7663
|
+
if (!existingContent) {
|
|
7664
|
+
fs3.writeFileSync(filePath, rule.content);
|
|
7665
|
+
rulesGenerated.push(rule.filename);
|
|
7666
|
+
} else if (!existingContent.includes("ContextStream Integration")) {
|
|
7667
|
+
fs3.writeFileSync(filePath, existingContent + "\n\n" + rule.content);
|
|
7668
|
+
rulesGenerated.push(rule.filename + " (appended)");
|
|
7669
|
+
}
|
|
7670
|
+
} catch {
|
|
7671
|
+
}
|
|
7672
|
+
}
|
|
7673
|
+
}
|
|
7674
|
+
const session = await client.initSession(
|
|
7675
|
+
{
|
|
7676
|
+
workspace_id: newWorkspace.id,
|
|
7677
|
+
context_hint: input.context_hint,
|
|
7678
|
+
include_recent_memory: true,
|
|
7679
|
+
include_decisions: true,
|
|
7680
|
+
auto_index: input.auto_index
|
|
7681
|
+
},
|
|
7682
|
+
[folderPath]
|
|
7683
|
+
);
|
|
7684
|
+
if (sessionManager) {
|
|
7685
|
+
sessionManager.markInitialized(session);
|
|
7686
|
+
}
|
|
7687
|
+
const response = {
|
|
7688
|
+
...session,
|
|
7689
|
+
bootstrap: {
|
|
7690
|
+
folder_path: folderPath,
|
|
7691
|
+
project_name: folderName,
|
|
7692
|
+
workspace: {
|
|
7693
|
+
id: newWorkspace.id,
|
|
7694
|
+
name: newWorkspace.name || input.workspace_name
|
|
7695
|
+
},
|
|
7696
|
+
association: associateResult,
|
|
7697
|
+
editor_rules_generated: rulesGenerated.length > 0 ? rulesGenerated : void 0
|
|
7698
|
+
}
|
|
7699
|
+
};
|
|
7700
|
+
return { content: [{ type: "text", text: formatContent(response) }], structuredContent: toStructured(response) };
|
|
7701
|
+
}
|
|
7702
|
+
);
|
|
7443
7703
|
registerTool(
|
|
7444
7704
|
"session_capture",
|
|
7445
7705
|
{
|
|
@@ -7626,7 +7886,7 @@ Returns lessons filtered by:
|
|
|
7626
7886
|
limit: input.limit * 2
|
|
7627
7887
|
// Fetch more to filter
|
|
7628
7888
|
});
|
|
7629
|
-
let lessons = (searchResult
|
|
7889
|
+
let lessons = (searchResult.results || []).filter((item) => {
|
|
7630
7890
|
const tags = item.metadata?.tags || [];
|
|
7631
7891
|
const isLesson = tags.includes("lesson");
|
|
7632
7892
|
if (!isLesson) return false;
|
|
@@ -8171,34 +8431,47 @@ function registerResources(server, client, apiUrl) {
|
|
|
8171
8431
|
}
|
|
8172
8432
|
|
|
8173
8433
|
// src/prompts.ts
|
|
8434
|
+
var ID_NOTES = [
|
|
8435
|
+
"Notes:",
|
|
8436
|
+
"- If ContextStream is not initialized in this conversation, call `session_init` first (omit ids).",
|
|
8437
|
+
"- Do not ask me for `workspace_id`/`project_id` \u2014 use session defaults or IDs returned by `session_init`.",
|
|
8438
|
+
"- Prefer omitting IDs in tool calls when the tool supports defaults."
|
|
8439
|
+
];
|
|
8440
|
+
var upgradeUrl = process.env.CONTEXTSTREAM_UPGRADE_URL || "https://contextstream.io/pricing";
|
|
8441
|
+
var proPrompts = /* @__PURE__ */ new Set([
|
|
8442
|
+
"build-context",
|
|
8443
|
+
"generate-plan",
|
|
8444
|
+
"generate-tasks",
|
|
8445
|
+
"token-budget-context"
|
|
8446
|
+
]);
|
|
8447
|
+
function promptAccessLabel(promptName) {
|
|
8448
|
+
return proPrompts.has(promptName) ? "PRO" : "Free";
|
|
8449
|
+
}
|
|
8174
8450
|
function registerPrompts(server) {
|
|
8175
8451
|
server.registerPrompt(
|
|
8176
8452
|
"explore-codebase",
|
|
8177
8453
|
{
|
|
8178
|
-
title:
|
|
8179
|
-
description: "Get an overview of a project codebase structure and key components"
|
|
8180
|
-
argsSchema: {
|
|
8181
|
-
project_id: external_exports.string().uuid().optional().describe("Project ID to explore (optional if session_init has set defaults)"),
|
|
8182
|
-
focus_area: external_exports.string().optional().describe('Optional area to focus on (e.g., "authentication", "api routes")')
|
|
8183
|
-
}
|
|
8454
|
+
title: `Explore Codebase (${promptAccessLabel("explore-codebase")})`,
|
|
8455
|
+
description: "Get an overview of a project codebase structure and key components"
|
|
8184
8456
|
},
|
|
8185
|
-
async (
|
|
8457
|
+
async () => ({
|
|
8186
8458
|
messages: [
|
|
8187
8459
|
{
|
|
8188
8460
|
role: "user",
|
|
8189
8461
|
content: {
|
|
8190
8462
|
type: "text",
|
|
8191
|
-
text:
|
|
8192
|
-
|
|
8193
|
-
|
|
8194
|
-
|
|
8195
|
-
|
|
8196
|
-
|
|
8197
|
-
|
|
8198
|
-
|
|
8199
|
-
|
|
8200
|
-
|
|
8201
|
-
|
|
8463
|
+
text: [
|
|
8464
|
+
"I want to understand the current codebase.",
|
|
8465
|
+
"",
|
|
8466
|
+
...ID_NOTES,
|
|
8467
|
+
"",
|
|
8468
|
+
"Please help me by:",
|
|
8469
|
+
"1. Use `projects_overview` to get a project summary (use session defaults; only pass `project_id` if required).",
|
|
8470
|
+
"2. Use `projects_files` to identify key entry points.",
|
|
8471
|
+
"3. If a focus area is clear from our conversation, prioritize it; otherwise ask me what to focus on.",
|
|
8472
|
+
"4. Use `search_semantic` (and optionally `search_hybrid`) to find the most relevant files.",
|
|
8473
|
+
"5. Summarize the architecture, major modules, and where to start editing."
|
|
8474
|
+
].join("\n")
|
|
8202
8475
|
}
|
|
8203
8476
|
}
|
|
8204
8477
|
]
|
|
@@ -8207,40 +8480,32 @@ Provide a clear, structured overview that helps me navigate this codebase effect
|
|
|
8207
8480
|
server.registerPrompt(
|
|
8208
8481
|
"capture-decision",
|
|
8209
8482
|
{
|
|
8210
|
-
title:
|
|
8211
|
-
description: "Document an architectural or technical decision in workspace memory"
|
|
8212
|
-
argsSchema: {
|
|
8213
|
-
workspace_id: external_exports.string().uuid().optional().describe("Workspace ID (optional if session_init has set defaults)"),
|
|
8214
|
-
decision_title: external_exports.string().describe("Brief title of the decision"),
|
|
8215
|
-
context: external_exports.string().describe("What prompted this decision"),
|
|
8216
|
-
decision: external_exports.string().describe("The decision made"),
|
|
8217
|
-
consequences: external_exports.string().optional().describe("Expected consequences or tradeoffs")
|
|
8218
|
-
}
|
|
8483
|
+
title: `Capture Decision (${promptAccessLabel("capture-decision")})`,
|
|
8484
|
+
description: "Document an architectural or technical decision in workspace memory"
|
|
8219
8485
|
},
|
|
8220
|
-
async (
|
|
8486
|
+
async () => ({
|
|
8221
8487
|
messages: [
|
|
8222
8488
|
{
|
|
8223
8489
|
role: "user",
|
|
8224
8490
|
content: {
|
|
8225
8491
|
type: "text",
|
|
8226
|
-
text:
|
|
8227
|
-
|
|
8228
|
-
|
|
8229
|
-
|
|
8230
|
-
|
|
8231
|
-
|
|
8232
|
-
|
|
8233
|
-
If
|
|
8234
|
-
|
|
8235
|
-
|
|
8236
|
-
-
|
|
8237
|
-
|
|
8238
|
-
-
|
|
8239
|
-
-
|
|
8240
|
-
|
|
8241
|
-
|
|
8242
|
-
|
|
8243
|
-
After creating, confirm the decision was recorded and summarize it.`
|
|
8492
|
+
text: [
|
|
8493
|
+
"Please capture an architectural/technical decision in ContextStream memory.",
|
|
8494
|
+
"",
|
|
8495
|
+
...ID_NOTES,
|
|
8496
|
+
"",
|
|
8497
|
+
"Instructions:",
|
|
8498
|
+
"- If the decision is already described in this conversation, extract: title, context, decision, consequences/tradeoffs.",
|
|
8499
|
+
"- If anything is missing, ask me 1\u20133 quick questions to fill the gaps.",
|
|
8500
|
+
"- Then call `session_capture` with:",
|
|
8501
|
+
' - event_type: "decision"',
|
|
8502
|
+
" - title: (short ADR title)",
|
|
8503
|
+
" - content: a well-formatted ADR (Context, Decision, Consequences)",
|
|
8504
|
+
' - tags: include relevant tags (e.g., "adr", "architecture")',
|
|
8505
|
+
' - importance: "high"',
|
|
8506
|
+
"",
|
|
8507
|
+
"After capturing, confirm what was saved."
|
|
8508
|
+
].join("\n")
|
|
8244
8509
|
}
|
|
8245
8510
|
}
|
|
8246
8511
|
]
|
|
@@ -8249,35 +8514,35 @@ After creating, confirm the decision was recorded and summarize it.`
|
|
|
8249
8514
|
server.registerPrompt(
|
|
8250
8515
|
"review-context",
|
|
8251
8516
|
{
|
|
8252
|
-
title:
|
|
8253
|
-
description: "Build context for reviewing code changes"
|
|
8254
|
-
argsSchema: {
|
|
8255
|
-
project_id: external_exports.string().uuid().optional().describe("Project ID (optional if session_init has set defaults)"),
|
|
8256
|
-
file_paths: external_exports.string().describe("Comma-separated file paths being changed"),
|
|
8257
|
-
change_description: external_exports.string().describe("Brief description of the changes")
|
|
8258
|
-
}
|
|
8517
|
+
title: `Code Review Context (${promptAccessLabel("review-context")})`,
|
|
8518
|
+
description: "Build context for reviewing code changes"
|
|
8259
8519
|
},
|
|
8260
|
-
async (
|
|
8520
|
+
async () => ({
|
|
8261
8521
|
messages: [
|
|
8262
8522
|
{
|
|
8263
8523
|
role: "user",
|
|
8264
8524
|
content: {
|
|
8265
8525
|
type: "text",
|
|
8266
|
-
text:
|
|
8267
|
-
|
|
8268
|
-
|
|
8269
|
-
|
|
8270
|
-
|
|
8271
|
-
|
|
8272
|
-
|
|
8273
|
-
|
|
8274
|
-
|
|
8275
|
-
|
|
8276
|
-
|
|
8277
|
-
|
|
8278
|
-
|
|
8279
|
-
|
|
8280
|
-
|
|
8526
|
+
text: [
|
|
8527
|
+
"I need context to review a set of code changes.",
|
|
8528
|
+
"",
|
|
8529
|
+
...ID_NOTES,
|
|
8530
|
+
"",
|
|
8531
|
+
"First:",
|
|
8532
|
+
"- If file paths and a short change description are not already in this conversation, ask me for them.",
|
|
8533
|
+
"",
|
|
8534
|
+
"Then build review context by:",
|
|
8535
|
+
"1. Using `graph_dependencies` to find what depends on the changed areas.",
|
|
8536
|
+
"2. Using `graph_impact` to assess potential blast radius.",
|
|
8537
|
+
"3. Using `memory_search` to find related decisions/notes.",
|
|
8538
|
+
"4. Using `search_semantic` to find related code patterns.",
|
|
8539
|
+
"",
|
|
8540
|
+
"Provide:",
|
|
8541
|
+
"- What the files/components do",
|
|
8542
|
+
"- What might be affected",
|
|
8543
|
+
"- Relevant prior decisions/lessons",
|
|
8544
|
+
"- Review checklist + risks to focus on"
|
|
8545
|
+
].join("\n")
|
|
8281
8546
|
}
|
|
8282
8547
|
}
|
|
8283
8548
|
]
|
|
@@ -8286,36 +8551,36 @@ Provide:
|
|
|
8286
8551
|
server.registerPrompt(
|
|
8287
8552
|
"investigate-bug",
|
|
8288
8553
|
{
|
|
8289
|
-
title:
|
|
8290
|
-
description: "Build context for debugging an issue"
|
|
8291
|
-
argsSchema: {
|
|
8292
|
-
project_id: external_exports.string().uuid().optional().describe("Project ID (optional if session_init has set defaults)"),
|
|
8293
|
-
error_message: external_exports.string().describe("Error message or symptom"),
|
|
8294
|
-
affected_area: external_exports.string().optional().describe("Known affected area or component")
|
|
8295
|
-
}
|
|
8554
|
+
title: `Investigate Bug (${promptAccessLabel("investigate-bug")})`,
|
|
8555
|
+
description: "Build context for debugging an issue"
|
|
8296
8556
|
},
|
|
8297
|
-
async (
|
|
8557
|
+
async () => ({
|
|
8298
8558
|
messages: [
|
|
8299
8559
|
{
|
|
8300
8560
|
role: "user",
|
|
8301
8561
|
content: {
|
|
8302
8562
|
type: "text",
|
|
8303
|
-
text:
|
|
8304
|
-
|
|
8305
|
-
|
|
8306
|
-
|
|
8307
|
-
|
|
8308
|
-
|
|
8309
|
-
|
|
8310
|
-
|
|
8311
|
-
|
|
8312
|
-
|
|
8313
|
-
|
|
8314
|
-
|
|
8315
|
-
|
|
8316
|
-
|
|
8317
|
-
|
|
8318
|
-
|
|
8563
|
+
text: [
|
|
8564
|
+
"I want help investigating a bug.",
|
|
8565
|
+
"",
|
|
8566
|
+
...ID_NOTES,
|
|
8567
|
+
"",
|
|
8568
|
+
"First:",
|
|
8569
|
+
"- If the error/symptom is not already stated, ask me for the exact error message and what I expected vs what happened.",
|
|
8570
|
+
"- If an affected area/component is not known, ask me where I noticed it.",
|
|
8571
|
+
"",
|
|
8572
|
+
"Then:",
|
|
8573
|
+
"1. Use `search_semantic` to find code related to the error/symptom.",
|
|
8574
|
+
"2. Use `search_pattern` to locate where similar errors are thrown or logged.",
|
|
8575
|
+
"3. If you identify key functions, use `graph_call_path` to trace call flows.",
|
|
8576
|
+
"4. Use `memory_search` to check if we have prior notes/bugs about this area.",
|
|
8577
|
+
"",
|
|
8578
|
+
"Return:",
|
|
8579
|
+
"- Likely origin locations",
|
|
8580
|
+
"- Call flow (if found)",
|
|
8581
|
+
"- Related past context",
|
|
8582
|
+
"- Suggested debugging steps"
|
|
8583
|
+
].join("\n")
|
|
8319
8584
|
}
|
|
8320
8585
|
}
|
|
8321
8586
|
]
|
|
@@ -8324,34 +8589,32 @@ Provide:
|
|
|
8324
8589
|
server.registerPrompt(
|
|
8325
8590
|
"explore-knowledge",
|
|
8326
8591
|
{
|
|
8327
|
-
title:
|
|
8328
|
-
description: "Navigate and understand the knowledge graph for a workspace"
|
|
8329
|
-
argsSchema: {
|
|
8330
|
-
workspace_id: external_exports.string().uuid().optional().describe("Workspace ID (optional if session_init has set defaults)"),
|
|
8331
|
-
starting_topic: external_exports.string().optional().describe("Topic to start exploration from")
|
|
8332
|
-
}
|
|
8592
|
+
title: `Explore Knowledge Graph (${promptAccessLabel("explore-knowledge")})`,
|
|
8593
|
+
description: "Navigate and understand the knowledge graph for a workspace"
|
|
8333
8594
|
},
|
|
8334
|
-
async (
|
|
8595
|
+
async () => ({
|
|
8335
8596
|
messages: [
|
|
8336
8597
|
{
|
|
8337
8598
|
role: "user",
|
|
8338
8599
|
content: {
|
|
8339
8600
|
type: "text",
|
|
8340
|
-
text:
|
|
8341
|
-
|
|
8342
|
-
|
|
8343
|
-
|
|
8344
|
-
|
|
8345
|
-
|
|
8346
|
-
|
|
8347
|
-
|
|
8348
|
-
|
|
8349
|
-
|
|
8350
|
-
|
|
8351
|
-
|
|
8352
|
-
|
|
8353
|
-
-
|
|
8354
|
-
-
|
|
8601
|
+
text: [
|
|
8602
|
+
"Help me explore the knowledge captured in this workspace.",
|
|
8603
|
+
"",
|
|
8604
|
+
...ID_NOTES,
|
|
8605
|
+
"",
|
|
8606
|
+
"Approach:",
|
|
8607
|
+
"1. Use `memory_summary` for a high-level overview.",
|
|
8608
|
+
"2. Use `memory_decisions` to see decision history (titles + a few key details).",
|
|
8609
|
+
"3. Use `memory_list_nodes` to see available knowledge nodes.",
|
|
8610
|
+
"4. If a starting topic is clear from the conversation, use `memory_search` for it.",
|
|
8611
|
+
"5. Use `graph_related` on the most relevant nodes to expand connections.",
|
|
8612
|
+
"",
|
|
8613
|
+
"Provide:",
|
|
8614
|
+
"- Key themes and topics",
|
|
8615
|
+
"- Important decisions + rationale",
|
|
8616
|
+
"- Suggested \u201Cnext nodes\u201D to explore"
|
|
8617
|
+
].join("\n")
|
|
8355
8618
|
}
|
|
8356
8619
|
}
|
|
8357
8620
|
]
|
|
@@ -8360,37 +8623,37 @@ Provide:
|
|
|
8360
8623
|
server.registerPrompt(
|
|
8361
8624
|
"onboard-to-project",
|
|
8362
8625
|
{
|
|
8363
|
-
title:
|
|
8364
|
-
description: "Generate onboarding context for a new team member"
|
|
8365
|
-
argsSchema: {
|
|
8366
|
-
project_id: external_exports.string().uuid().optional().describe("Project ID (optional if session_init has set defaults)"),
|
|
8367
|
-
workspace_id: external_exports.string().uuid().optional().describe("Workspace ID (optional if session_init has set defaults)"),
|
|
8368
|
-
role: external_exports.string().optional().describe('Role of the person being onboarded (e.g., "backend developer", "frontend developer")')
|
|
8369
|
-
}
|
|
8626
|
+
title: `Project Onboarding (${promptAccessLabel("onboard-to-project")})`,
|
|
8627
|
+
description: "Generate onboarding context for a new team member"
|
|
8370
8628
|
},
|
|
8371
|
-
async (
|
|
8629
|
+
async () => ({
|
|
8372
8630
|
messages: [
|
|
8373
8631
|
{
|
|
8374
8632
|
role: "user",
|
|
8375
8633
|
content: {
|
|
8376
8634
|
type: "text",
|
|
8377
|
-
text:
|
|
8378
|
-
|
|
8379
|
-
|
|
8380
|
-
|
|
8381
|
-
|
|
8382
|
-
|
|
8383
|
-
|
|
8384
|
-
|
|
8385
|
-
|
|
8386
|
-
|
|
8387
|
-
|
|
8388
|
-
|
|
8389
|
-
|
|
8390
|
-
|
|
8391
|
-
|
|
8392
|
-
-
|
|
8393
|
-
-
|
|
8635
|
+
text: [
|
|
8636
|
+
"Create an onboarding guide for a new team member joining this project.",
|
|
8637
|
+
"",
|
|
8638
|
+
...ID_NOTES,
|
|
8639
|
+
"",
|
|
8640
|
+
"First:",
|
|
8641
|
+
"- If the role is not specified, ask me what role they are onboarding into (backend, frontend, fullstack, etc.).",
|
|
8642
|
+
"",
|
|
8643
|
+
"Gather context:",
|
|
8644
|
+
"1. Use `projects_overview` and `projects_statistics` for project summary.",
|
|
8645
|
+
"2. Use `projects_files` to identify key entry points.",
|
|
8646
|
+
"3. Use `memory_timeline` and `memory_decisions` to understand recent changes and architectural choices.",
|
|
8647
|
+
"4. Use `search_semantic` to find READMEs/docs/setup instructions.",
|
|
8648
|
+
"",
|
|
8649
|
+
"Output:",
|
|
8650
|
+
"- Project overview and purpose",
|
|
8651
|
+
"- Tech stack + architecture map",
|
|
8652
|
+
"- Key files/entry points relevant to the role",
|
|
8653
|
+
"- Important decisions + rationale",
|
|
8654
|
+
"- Recent changes/current focus",
|
|
8655
|
+
"- Step-by-step getting started"
|
|
8656
|
+
].join("\n")
|
|
8394
8657
|
}
|
|
8395
8658
|
}
|
|
8396
8659
|
]
|
|
@@ -8399,33 +8662,30 @@ Provide an onboarding guide that includes:
|
|
|
8399
8662
|
server.registerPrompt(
|
|
8400
8663
|
"analyze-refactoring",
|
|
8401
8664
|
{
|
|
8402
|
-
title:
|
|
8403
|
-
description: "Analyze a codebase for refactoring opportunities"
|
|
8404
|
-
argsSchema: {
|
|
8405
|
-
project_id: external_exports.string().uuid().optional().describe("Project ID (optional if session_init has set defaults)"),
|
|
8406
|
-
target_area: external_exports.string().optional().describe("Specific area to analyze")
|
|
8407
|
-
}
|
|
8665
|
+
title: `Refactoring Analysis (${promptAccessLabel("analyze-refactoring")})`,
|
|
8666
|
+
description: "Analyze a codebase for refactoring opportunities"
|
|
8408
8667
|
},
|
|
8409
|
-
async (
|
|
8668
|
+
async () => ({
|
|
8410
8669
|
messages: [
|
|
8411
8670
|
{
|
|
8412
8671
|
role: "user",
|
|
8413
8672
|
content: {
|
|
8414
8673
|
type: "text",
|
|
8415
|
-
text:
|
|
8416
|
-
|
|
8417
|
-
|
|
8418
|
-
|
|
8419
|
-
|
|
8420
|
-
|
|
8421
|
-
|
|
8422
|
-
|
|
8423
|
-
|
|
8424
|
-
|
|
8425
|
-
|
|
8426
|
-
|
|
8427
|
-
|
|
8428
|
-
|
|
8674
|
+
text: [
|
|
8675
|
+
"Analyze the codebase for refactoring opportunities.",
|
|
8676
|
+
"",
|
|
8677
|
+
...ID_NOTES,
|
|
8678
|
+
"",
|
|
8679
|
+
"If a target area is obvious from our conversation, focus there; otherwise ask me what area to analyze.",
|
|
8680
|
+
"",
|
|
8681
|
+
"Please investigate:",
|
|
8682
|
+
"1. `graph_circular_dependencies` (circular deps to break)",
|
|
8683
|
+
"2. `graph_unused_code` (dead code to remove)",
|
|
8684
|
+
"3. `search_pattern` (duplication patterns)",
|
|
8685
|
+
"4. `projects_statistics` (high complexity hotspots)",
|
|
8686
|
+
"",
|
|
8687
|
+
"Provide a prioritized list with quick wins vs deeper refactors."
|
|
8688
|
+
].join("\n")
|
|
8429
8689
|
}
|
|
8430
8690
|
}
|
|
8431
8691
|
]
|
|
@@ -8434,34 +8694,30 @@ Provide:
|
|
|
8434
8694
|
server.registerPrompt(
|
|
8435
8695
|
"build-context",
|
|
8436
8696
|
{
|
|
8437
|
-
title:
|
|
8438
|
-
description: "Build comprehensive context for an LLM task"
|
|
8439
|
-
argsSchema: {
|
|
8440
|
-
query: external_exports.string().describe("What you need context for"),
|
|
8441
|
-
workspace_id: external_exports.string().uuid().optional().describe("Workspace ID"),
|
|
8442
|
-
project_id: external_exports.string().uuid().optional().describe("Project ID"),
|
|
8443
|
-
include_memory: external_exports.string().optional().describe('Include memory/decisions ("true" or "false")')
|
|
8444
|
-
}
|
|
8697
|
+
title: `Build LLM Context (${promptAccessLabel("build-context")})`,
|
|
8698
|
+
description: "Build comprehensive context for an LLM task"
|
|
8445
8699
|
},
|
|
8446
|
-
async (
|
|
8700
|
+
async () => ({
|
|
8447
8701
|
messages: [
|
|
8448
8702
|
{
|
|
8449
8703
|
role: "user",
|
|
8450
8704
|
content: {
|
|
8451
8705
|
type: "text",
|
|
8452
|
-
text:
|
|
8453
|
-
|
|
8454
|
-
|
|
8455
|
-
|
|
8456
|
-
|
|
8457
|
-
|
|
8458
|
-
|
|
8459
|
-
|
|
8460
|
-
-
|
|
8461
|
-
-
|
|
8462
|
-
|
|
8463
|
-
|
|
8464
|
-
|
|
8706
|
+
text: [
|
|
8707
|
+
"Build comprehensive context for the task we are working on.",
|
|
8708
|
+
"",
|
|
8709
|
+
`Access: ${promptAccessLabel("build-context")}${promptAccessLabel("build-context") === "PRO" ? ` (upgrade: ${upgradeUrl})` : ""}`,
|
|
8710
|
+
"",
|
|
8711
|
+
...ID_NOTES,
|
|
8712
|
+
"",
|
|
8713
|
+
"First:",
|
|
8714
|
+
"- If the \u201Cquery\u201D is clear from the latest user request, use that.",
|
|
8715
|
+
"- Otherwise ask me: \u201CWhat do you need context for?\u201D",
|
|
8716
|
+
"",
|
|
8717
|
+
"Then:",
|
|
8718
|
+
"- Call `ai_enhanced_context` with include_code=true, include_docs=true, include_memory=true (omit IDs unless required).",
|
|
8719
|
+
"- Synthesize the returned context into a short briefing with links/file paths and key decisions/risks."
|
|
8720
|
+
].join("\n")
|
|
8465
8721
|
}
|
|
8466
8722
|
}
|
|
8467
8723
|
]
|
|
@@ -8470,28 +8726,29 @@ Then synthesize the retrieved context into a coherent briefing that will help wi
|
|
|
8470
8726
|
server.registerPrompt(
|
|
8471
8727
|
"smart-search",
|
|
8472
8728
|
{
|
|
8473
|
-
title:
|
|
8474
|
-
description: "Search across memory, decisions, and code for a query"
|
|
8475
|
-
argsSchema: {
|
|
8476
|
-
query: external_exports.string().describe("What you want to find"),
|
|
8477
|
-
workspace_id: external_exports.string().uuid().optional().describe("Workspace ID (optional)"),
|
|
8478
|
-
project_id: external_exports.string().uuid().optional().describe("Project ID (optional)")
|
|
8479
|
-
}
|
|
8729
|
+
title: `Smart Search (${promptAccessLabel("smart-search")})`,
|
|
8730
|
+
description: "Search across memory, decisions, and code for a query"
|
|
8480
8731
|
},
|
|
8481
|
-
async (
|
|
8732
|
+
async () => ({
|
|
8482
8733
|
messages: [
|
|
8483
8734
|
{
|
|
8484
8735
|
role: "user",
|
|
8485
8736
|
content: {
|
|
8486
8737
|
type: "text",
|
|
8487
|
-
text:
|
|
8488
|
-
|
|
8489
|
-
|
|
8490
|
-
|
|
8491
|
-
|
|
8492
|
-
|
|
8493
|
-
|
|
8494
|
-
|
|
8738
|
+
text: [
|
|
8739
|
+
"Find the most relevant context for what I am asking about.",
|
|
8740
|
+
"",
|
|
8741
|
+
...ID_NOTES,
|
|
8742
|
+
"",
|
|
8743
|
+
"First:",
|
|
8744
|
+
"- If a query is clear from the conversation, use it.",
|
|
8745
|
+
"- Otherwise ask me what I want to find.",
|
|
8746
|
+
"",
|
|
8747
|
+
"Then:",
|
|
8748
|
+
"1. Use `session_smart_search` for the query.",
|
|
8749
|
+
"2. If results are thin, follow up with `search_hybrid` and `memory_search`.",
|
|
8750
|
+
"3. Return the top results with file paths/links and a short synthesis."
|
|
8751
|
+
].join("\n")
|
|
8495
8752
|
}
|
|
8496
8753
|
}
|
|
8497
8754
|
]
|
|
@@ -8500,26 +8757,28 @@ Please:
|
|
|
8500
8757
|
server.registerPrompt(
|
|
8501
8758
|
"recall-context",
|
|
8502
8759
|
{
|
|
8503
|
-
title:
|
|
8504
|
-
description: "Retrieve relevant past decisions and memory for a query"
|
|
8505
|
-
argsSchema: {
|
|
8506
|
-
query: external_exports.string().describe("What to recall (natural language)"),
|
|
8507
|
-
workspace_id: external_exports.string().uuid().optional().describe("Workspace ID (optional)"),
|
|
8508
|
-
project_id: external_exports.string().uuid().optional().describe("Project ID (optional)")
|
|
8509
|
-
}
|
|
8760
|
+
title: `Recall Context (${promptAccessLabel("recall-context")})`,
|
|
8761
|
+
description: "Retrieve relevant past decisions and memory for a query"
|
|
8510
8762
|
},
|
|
8511
|
-
async (
|
|
8763
|
+
async () => ({
|
|
8512
8764
|
messages: [
|
|
8513
8765
|
{
|
|
8514
8766
|
role: "user",
|
|
8515
8767
|
content: {
|
|
8516
8768
|
type: "text",
|
|
8517
|
-
text:
|
|
8518
|
-
|
|
8519
|
-
|
|
8520
|
-
|
|
8521
|
-
|
|
8522
|
-
|
|
8769
|
+
text: [
|
|
8770
|
+
"Recall relevant past context (decisions, notes, lessons) for what I am asking about.",
|
|
8771
|
+
"",
|
|
8772
|
+
...ID_NOTES,
|
|
8773
|
+
"",
|
|
8774
|
+
"First:",
|
|
8775
|
+
"- If a recall query is clear from the conversation, use it.",
|
|
8776
|
+
"- Otherwise ask me what topic I want to recall.",
|
|
8777
|
+
"",
|
|
8778
|
+
"Then:",
|
|
8779
|
+
"- Use `session_recall` with the query (omit IDs unless required).",
|
|
8780
|
+
"- Summarize the key points and any relevant decisions/lessons."
|
|
8781
|
+
].join("\n")
|
|
8523
8782
|
}
|
|
8524
8783
|
}
|
|
8525
8784
|
]
|
|
@@ -8528,26 +8787,25 @@ Then summarize the key points and any relevant decisions/lessons.`
|
|
|
8528
8787
|
server.registerPrompt(
|
|
8529
8788
|
"session-summary",
|
|
8530
8789
|
{
|
|
8531
|
-
title:
|
|
8532
|
-
description: "Get a compact summary of workspace/project context"
|
|
8533
|
-
argsSchema: {
|
|
8534
|
-
workspace_id: external_exports.string().uuid().optional().describe("Workspace ID (optional)"),
|
|
8535
|
-
project_id: external_exports.string().uuid().optional().describe("Project ID (optional)"),
|
|
8536
|
-
max_tokens: external_exports.string().optional().describe("Max tokens for summary (default: 500)")
|
|
8537
|
-
}
|
|
8790
|
+
title: `Session Summary (${promptAccessLabel("session-summary")})`,
|
|
8791
|
+
description: "Get a compact summary of workspace/project context"
|
|
8538
8792
|
},
|
|
8539
|
-
async (
|
|
8793
|
+
async () => ({
|
|
8540
8794
|
messages: [
|
|
8541
8795
|
{
|
|
8542
8796
|
role: "user",
|
|
8543
8797
|
content: {
|
|
8544
8798
|
type: "text",
|
|
8545
|
-
text:
|
|
8546
|
-
|
|
8547
|
-
|
|
8548
|
-
|
|
8549
|
-
|
|
8550
|
-
|
|
8799
|
+
text: [
|
|
8800
|
+
"Generate a compact, token-efficient summary of the current workspace/project context.",
|
|
8801
|
+
"",
|
|
8802
|
+
...ID_NOTES,
|
|
8803
|
+
"",
|
|
8804
|
+
"Use `session_summary` (default max_tokens=500 unless I specify otherwise).",
|
|
8805
|
+
"Then list:",
|
|
8806
|
+
"- Top decisions (titles only)",
|
|
8807
|
+
"- Any high-priority lessons to watch for"
|
|
8808
|
+
].join("\n")
|
|
8551
8809
|
}
|
|
8552
8810
|
}
|
|
8553
8811
|
]
|
|
@@ -8556,39 +8814,31 @@ Then list the top decisions (titles only) and any high-priority lessons to watch
|
|
|
8556
8814
|
server.registerPrompt(
|
|
8557
8815
|
"capture-lesson",
|
|
8558
8816
|
{
|
|
8559
|
-
title:
|
|
8560
|
-
description: "Record a lesson learned from an error or correction"
|
|
8561
|
-
argsSchema: {
|
|
8562
|
-
workspace_id: external_exports.string().uuid().optional().describe("Workspace ID (optional)"),
|
|
8563
|
-
project_id: external_exports.string().uuid().optional().describe("Project ID (optional)"),
|
|
8564
|
-
title: external_exports.string().describe("Lesson title (what to remember)"),
|
|
8565
|
-
severity: external_exports.string().optional().describe("low|medium|high|critical (default: medium)"),
|
|
8566
|
-
category: external_exports.string().describe("workflow|code_quality|verification|communication|project_specific"),
|
|
8567
|
-
trigger: external_exports.string().describe("What action caused the problem"),
|
|
8568
|
-
impact: external_exports.string().describe("What went wrong"),
|
|
8569
|
-
prevention: external_exports.string().describe("How to prevent in future"),
|
|
8570
|
-
keywords: external_exports.string().optional().describe("Comma-separated keywords (optional)")
|
|
8571
|
-
}
|
|
8817
|
+
title: `Capture Lesson (${promptAccessLabel("capture-lesson")})`,
|
|
8818
|
+
description: "Record a lesson learned from an error or correction"
|
|
8572
8819
|
},
|
|
8573
|
-
async (
|
|
8820
|
+
async () => ({
|
|
8574
8821
|
messages: [
|
|
8575
8822
|
{
|
|
8576
8823
|
role: "user",
|
|
8577
8824
|
content: {
|
|
8578
8825
|
type: "text",
|
|
8579
|
-
text:
|
|
8580
|
-
|
|
8581
|
-
|
|
8582
|
-
|
|
8583
|
-
|
|
8584
|
-
|
|
8585
|
-
|
|
8586
|
-
|
|
8587
|
-
|
|
8588
|
-
|
|
8589
|
-
|
|
8590
|
-
|
|
8591
|
-
|
|
8826
|
+
text: [
|
|
8827
|
+
"Capture a lesson learned so it is surfaced in future sessions.",
|
|
8828
|
+
"",
|
|
8829
|
+
...ID_NOTES,
|
|
8830
|
+
"",
|
|
8831
|
+
"If the lesson details are not fully present in the conversation, ask me for:",
|
|
8832
|
+
"- title (what to remember)",
|
|
8833
|
+
"- severity (low|medium|high|critical, default medium)",
|
|
8834
|
+
"- category (workflow|code_quality|verification|communication|project_specific)",
|
|
8835
|
+
"- trigger (what caused it)",
|
|
8836
|
+
"- impact (what went wrong)",
|
|
8837
|
+
"- prevention (how to prevent it)",
|
|
8838
|
+
"- keywords (optional)",
|
|
8839
|
+
"",
|
|
8840
|
+
"Then call `session_capture_lesson` with those fields and confirm it was saved."
|
|
8841
|
+
].join("\n")
|
|
8592
8842
|
}
|
|
8593
8843
|
}
|
|
8594
8844
|
]
|
|
@@ -8597,33 +8847,28 @@ Use \`session_capture_lesson\` with the fields above. If keywords were provided,
|
|
|
8597
8847
|
server.registerPrompt(
|
|
8598
8848
|
"capture-preference",
|
|
8599
8849
|
{
|
|
8600
|
-
title:
|
|
8601
|
-
description: "Save a user preference to memory"
|
|
8602
|
-
argsSchema: {
|
|
8603
|
-
workspace_id: external_exports.string().uuid().optional().describe("Workspace ID (optional)"),
|
|
8604
|
-
project_id: external_exports.string().uuid().optional().describe("Project ID (optional)"),
|
|
8605
|
-
title: external_exports.string().optional().describe("Preference title (optional)"),
|
|
8606
|
-
preference: external_exports.string().describe("Preference details to remember")
|
|
8607
|
-
}
|
|
8850
|
+
title: `Capture Preference (${promptAccessLabel("capture-preference")})`,
|
|
8851
|
+
description: "Save a user preference to memory"
|
|
8608
8852
|
},
|
|
8609
|
-
async (
|
|
8853
|
+
async () => ({
|
|
8610
8854
|
messages: [
|
|
8611
8855
|
{
|
|
8612
8856
|
role: "user",
|
|
8613
8857
|
content: {
|
|
8614
8858
|
type: "text",
|
|
8615
|
-
text:
|
|
8616
|
-
|
|
8617
|
-
|
|
8618
|
-
|
|
8619
|
-
|
|
8620
|
-
If
|
|
8621
|
-
|
|
8622
|
-
|
|
8623
|
-
- event_type: "preference"
|
|
8624
|
-
- title:
|
|
8625
|
-
- content:
|
|
8626
|
-
- importance: "medium"
|
|
8859
|
+
text: [
|
|
8860
|
+
"Save a user preference to ContextStream memory.",
|
|
8861
|
+
"",
|
|
8862
|
+
...ID_NOTES,
|
|
8863
|
+
"",
|
|
8864
|
+
"If the preference is not explicit in the conversation, ask me what to remember.",
|
|
8865
|
+
"",
|
|
8866
|
+
"Then call `session_capture` with:",
|
|
8867
|
+
'- event_type: "preference"',
|
|
8868
|
+
"- title: (short title)",
|
|
8869
|
+
"- content: (preference text)",
|
|
8870
|
+
'- importance: "medium"'
|
|
8871
|
+
].join("\n")
|
|
8627
8872
|
}
|
|
8628
8873
|
}
|
|
8629
8874
|
]
|
|
@@ -8632,33 +8877,28 @@ Use \`session_capture\` with:
|
|
|
8632
8877
|
server.registerPrompt(
|
|
8633
8878
|
"capture-task",
|
|
8634
8879
|
{
|
|
8635
|
-
title:
|
|
8636
|
-
description: "Capture an action item into memory"
|
|
8637
|
-
argsSchema: {
|
|
8638
|
-
workspace_id: external_exports.string().uuid().optional().describe("Workspace ID (optional)"),
|
|
8639
|
-
project_id: external_exports.string().uuid().optional().describe("Project ID (optional)"),
|
|
8640
|
-
title: external_exports.string().optional().describe("Task title (optional)"),
|
|
8641
|
-
task: external_exports.string().describe("Task details")
|
|
8642
|
-
}
|
|
8880
|
+
title: `Capture Task (${promptAccessLabel("capture-task")})`,
|
|
8881
|
+
description: "Capture an action item into memory"
|
|
8643
8882
|
},
|
|
8644
|
-
async (
|
|
8883
|
+
async () => ({
|
|
8645
8884
|
messages: [
|
|
8646
8885
|
{
|
|
8647
8886
|
role: "user",
|
|
8648
8887
|
content: {
|
|
8649
8888
|
type: "text",
|
|
8650
|
-
text:
|
|
8651
|
-
|
|
8652
|
-
|
|
8653
|
-
|
|
8654
|
-
|
|
8655
|
-
If
|
|
8656
|
-
|
|
8657
|
-
|
|
8658
|
-
- event_type: "task"
|
|
8659
|
-
- title:
|
|
8660
|
-
- content:
|
|
8661
|
-
- importance: "medium"
|
|
8889
|
+
text: [
|
|
8890
|
+
"Capture an action item into ContextStream memory.",
|
|
8891
|
+
"",
|
|
8892
|
+
...ID_NOTES,
|
|
8893
|
+
"",
|
|
8894
|
+
"If the task is not explicit in the conversation, ask me what to capture.",
|
|
8895
|
+
"",
|
|
8896
|
+
"Then call `session_capture` with:",
|
|
8897
|
+
'- event_type: "task"',
|
|
8898
|
+
"- title: (short title)",
|
|
8899
|
+
"- content: (task details)",
|
|
8900
|
+
'- importance: "medium"'
|
|
8901
|
+
].join("\n")
|
|
8662
8902
|
}
|
|
8663
8903
|
}
|
|
8664
8904
|
]
|
|
@@ -8667,44 +8907,34 @@ Use \`session_capture\` with:
|
|
|
8667
8907
|
server.registerPrompt(
|
|
8668
8908
|
"capture-bug",
|
|
8669
8909
|
{
|
|
8670
|
-
title:
|
|
8671
|
-
description: "Capture a bug report into workspace memory"
|
|
8672
|
-
argsSchema: {
|
|
8673
|
-
workspace_id: external_exports.string().uuid().optional().describe("Workspace ID (optional)"),
|
|
8674
|
-
project_id: external_exports.string().uuid().optional().describe("Project ID (optional)"),
|
|
8675
|
-
title: external_exports.string().describe("Bug title"),
|
|
8676
|
-
description: external_exports.string().describe("Bug description"),
|
|
8677
|
-
reproduction_steps: external_exports.string().optional().describe("Steps to reproduce (optional)"),
|
|
8678
|
-
expected: external_exports.string().optional().describe("Expected behavior (optional)"),
|
|
8679
|
-
actual: external_exports.string().optional().describe("Actual behavior (optional)")
|
|
8680
|
-
}
|
|
8910
|
+
title: `Capture Bug (${promptAccessLabel("capture-bug")})`,
|
|
8911
|
+
description: "Capture a bug report into workspace memory"
|
|
8681
8912
|
},
|
|
8682
|
-
async (
|
|
8913
|
+
async () => ({
|
|
8683
8914
|
messages: [
|
|
8684
8915
|
{
|
|
8685
8916
|
role: "user",
|
|
8686
8917
|
content: {
|
|
8687
8918
|
type: "text",
|
|
8688
|
-
text:
|
|
8689
|
-
|
|
8690
|
-
|
|
8691
|
-
|
|
8692
|
-
|
|
8693
|
-
|
|
8694
|
-
|
|
8695
|
-
|
|
8696
|
-
|
|
8697
|
-
|
|
8698
|
-
|
|
8699
|
-
|
|
8700
|
-
|
|
8701
|
-
|
|
8702
|
-
|
|
8703
|
-
-
|
|
8704
|
-
-
|
|
8705
|
-
-
|
|
8706
|
-
|
|
8707
|
-
- importance: "high"`
|
|
8919
|
+
text: [
|
|
8920
|
+
"Capture a bug report in ContextStream memory.",
|
|
8921
|
+
"",
|
|
8922
|
+
...ID_NOTES,
|
|
8923
|
+
"",
|
|
8924
|
+
"If details are missing, ask me for:",
|
|
8925
|
+
"- title",
|
|
8926
|
+
"- description",
|
|
8927
|
+
"- steps to reproduce (optional)",
|
|
8928
|
+
"- expected behavior (optional)",
|
|
8929
|
+
"- actual behavior (optional)",
|
|
8930
|
+
"",
|
|
8931
|
+
"Then call `session_capture` with:",
|
|
8932
|
+
'- event_type: "bug"',
|
|
8933
|
+
"- title: (bug title)",
|
|
8934
|
+
"- content: a well-formatted bug report (include all provided details)",
|
|
8935
|
+
"- tags: component/area tags",
|
|
8936
|
+
'- importance: "high"'
|
|
8937
|
+
].join("\n")
|
|
8708
8938
|
}
|
|
8709
8939
|
}
|
|
8710
8940
|
]
|
|
@@ -8713,41 +8943,33 @@ Use \`session_capture\` with:
|
|
|
8713
8943
|
server.registerPrompt(
|
|
8714
8944
|
"capture-feature",
|
|
8715
8945
|
{
|
|
8716
|
-
title:
|
|
8717
|
-
description: "Capture a feature request into workspace memory"
|
|
8718
|
-
argsSchema: {
|
|
8719
|
-
workspace_id: external_exports.string().uuid().optional().describe("Workspace ID (optional)"),
|
|
8720
|
-
project_id: external_exports.string().uuid().optional().describe("Project ID (optional)"),
|
|
8721
|
-
title: external_exports.string().describe("Feature title"),
|
|
8722
|
-
description: external_exports.string().describe("Feature description"),
|
|
8723
|
-
rationale: external_exports.string().optional().describe("Why this matters (optional)"),
|
|
8724
|
-
acceptance_criteria: external_exports.string().optional().describe("Acceptance criteria (optional)")
|
|
8725
|
-
}
|
|
8946
|
+
title: `Capture Feature (${promptAccessLabel("capture-feature")})`,
|
|
8947
|
+
description: "Capture a feature request into workspace memory"
|
|
8726
8948
|
},
|
|
8727
|
-
async (
|
|
8949
|
+
async () => ({
|
|
8728
8950
|
messages: [
|
|
8729
8951
|
{
|
|
8730
8952
|
role: "user",
|
|
8731
8953
|
content: {
|
|
8732
8954
|
type: "text",
|
|
8733
|
-
text:
|
|
8734
|
-
|
|
8735
|
-
|
|
8736
|
-
|
|
8737
|
-
|
|
8738
|
-
|
|
8739
|
-
|
|
8740
|
-
|
|
8741
|
-
|
|
8742
|
-
|
|
8743
|
-
|
|
8744
|
-
|
|
8745
|
-
|
|
8746
|
-
-
|
|
8747
|
-
-
|
|
8748
|
-
-
|
|
8749
|
-
-
|
|
8750
|
-
|
|
8955
|
+
text: [
|
|
8956
|
+
"Capture a feature request in ContextStream memory.",
|
|
8957
|
+
"",
|
|
8958
|
+
...ID_NOTES,
|
|
8959
|
+
"",
|
|
8960
|
+
"If details are missing, ask me for:",
|
|
8961
|
+
"- title",
|
|
8962
|
+
"- description",
|
|
8963
|
+
"- rationale (optional)",
|
|
8964
|
+
"- acceptance criteria (optional)",
|
|
8965
|
+
"",
|
|
8966
|
+
"Then call `session_capture` with:",
|
|
8967
|
+
'- event_type: "feature"',
|
|
8968
|
+
"- title: (feature title)",
|
|
8969
|
+
"- content: a well-formatted feature request",
|
|
8970
|
+
"- tags: component/area tags",
|
|
8971
|
+
'- importance: "medium"'
|
|
8972
|
+
].join("\n")
|
|
8751
8973
|
}
|
|
8752
8974
|
}
|
|
8753
8975
|
]
|
|
@@ -8756,30 +8978,26 @@ Use \`session_capture\` with:
|
|
|
8756
8978
|
server.registerPrompt(
|
|
8757
8979
|
"generate-plan",
|
|
8758
8980
|
{
|
|
8759
|
-
title:
|
|
8760
|
-
description: "Generate a development plan from a description"
|
|
8761
|
-
argsSchema: {
|
|
8762
|
-
description: external_exports.string().describe("What you want to build/fix"),
|
|
8763
|
-
project_id: external_exports.string().uuid().optional().describe("Project ID (optional)"),
|
|
8764
|
-
complexity: external_exports.string().optional().describe("low|medium|high (optional)")
|
|
8765
|
-
}
|
|
8981
|
+
title: `Generate Plan (${promptAccessLabel("generate-plan")})`,
|
|
8982
|
+
description: "Generate a development plan from a description"
|
|
8766
8983
|
},
|
|
8767
|
-
async (
|
|
8984
|
+
async () => ({
|
|
8768
8985
|
messages: [
|
|
8769
8986
|
{
|
|
8770
8987
|
role: "user",
|
|
8771
8988
|
content: {
|
|
8772
8989
|
type: "text",
|
|
8773
|
-
text:
|
|
8774
|
-
|
|
8775
|
-
|
|
8776
|
-
|
|
8777
|
-
|
|
8778
|
-
|
|
8779
|
-
|
|
8780
|
-
|
|
8781
|
-
|
|
8782
|
-
Then present the plan as
|
|
8990
|
+
text: [
|
|
8991
|
+
"Generate a development plan for what I am trying to build/fix.",
|
|
8992
|
+
"",
|
|
8993
|
+
`Access: ${promptAccessLabel("generate-plan")}${promptAccessLabel("generate-plan") === "PRO" ? ` (upgrade: ${upgradeUrl})` : ""}`,
|
|
8994
|
+
"",
|
|
8995
|
+
...ID_NOTES,
|
|
8996
|
+
"",
|
|
8997
|
+
"Use the most recent user request as the plan description. If unclear, ask me for a one-paragraph description.",
|
|
8998
|
+
"",
|
|
8999
|
+
"Then call `ai_plan` and present the plan as an ordered list with milestones and risks."
|
|
9000
|
+
].join("\n")
|
|
8783
9001
|
}
|
|
8784
9002
|
}
|
|
8785
9003
|
]
|
|
@@ -8788,31 +9006,27 @@ Then present the plan as a concise ordered list with clear milestones and risks.
|
|
|
8788
9006
|
server.registerPrompt(
|
|
8789
9007
|
"generate-tasks",
|
|
8790
9008
|
{
|
|
8791
|
-
title:
|
|
8792
|
-
description: "Generate actionable tasks from a plan or description"
|
|
8793
|
-
argsSchema: {
|
|
8794
|
-
plan_id: external_exports.string().optional().describe("Plan ID (optional)"),
|
|
8795
|
-
description: external_exports.string().optional().describe("Description to generate tasks from (optional if plan_id provided)"),
|
|
8796
|
-
project_id: external_exports.string().uuid().optional().describe("Project ID (optional)"),
|
|
8797
|
-
granularity: external_exports.string().optional().describe("fine|medium|coarse (optional)")
|
|
8798
|
-
}
|
|
9009
|
+
title: `Generate Tasks (${promptAccessLabel("generate-tasks")})`,
|
|
9010
|
+
description: "Generate actionable tasks from a plan or description"
|
|
8799
9011
|
},
|
|
8800
|
-
async (
|
|
9012
|
+
async () => ({
|
|
8801
9013
|
messages: [
|
|
8802
9014
|
{
|
|
8803
9015
|
role: "user",
|
|
8804
9016
|
content: {
|
|
8805
9017
|
type: "text",
|
|
8806
|
-
text:
|
|
8807
|
-
|
|
8808
|
-
|
|
8809
|
-
|
|
8810
|
-
|
|
8811
|
-
|
|
8812
|
-
|
|
8813
|
-
|
|
8814
|
-
|
|
8815
|
-
|
|
9018
|
+
text: [
|
|
9019
|
+
"Generate actionable tasks for the work we are discussing.",
|
|
9020
|
+
"",
|
|
9021
|
+
`Access: ${promptAccessLabel("generate-tasks")}${promptAccessLabel("generate-tasks") === "PRO" ? ` (upgrade: ${upgradeUrl})` : ""}`,
|
|
9022
|
+
"",
|
|
9023
|
+
...ID_NOTES,
|
|
9024
|
+
"",
|
|
9025
|
+
"If a plan_id exists in the conversation, use it. Otherwise use the latest user request as the description.",
|
|
9026
|
+
"If granularity is not specified, default to medium.",
|
|
9027
|
+
"",
|
|
9028
|
+
"Call `ai_tasks` and return a checklist of tasks with acceptance criteria for each."
|
|
9029
|
+
].join("\n")
|
|
8816
9030
|
}
|
|
8817
9031
|
}
|
|
8818
9032
|
]
|
|
@@ -8821,35 +9035,28 @@ Then output a checklist of tasks with clear acceptance criteria for each.`
|
|
|
8821
9035
|
server.registerPrompt(
|
|
8822
9036
|
"token-budget-context",
|
|
8823
9037
|
{
|
|
8824
|
-
title:
|
|
8825
|
-
description: "Get the most relevant context that fits within a token budget"
|
|
8826
|
-
argsSchema: {
|
|
8827
|
-
query: external_exports.string().describe("What you need context for"),
|
|
8828
|
-
max_tokens: external_exports.string().describe("Max tokens for context (e.g., 500, 1000, 2000)"),
|
|
8829
|
-
workspace_id: external_exports.string().uuid().optional().describe("Workspace ID (optional)"),
|
|
8830
|
-
project_id: external_exports.string().uuid().optional().describe("Project ID (optional)"),
|
|
8831
|
-
include_code: external_exports.string().optional().describe('Include code ("true" or "false")')
|
|
8832
|
-
}
|
|
9038
|
+
title: `Token-Budget Context (${promptAccessLabel("token-budget-context")})`,
|
|
9039
|
+
description: "Get the most relevant context that fits within a token budget"
|
|
8833
9040
|
},
|
|
8834
|
-
async (
|
|
9041
|
+
async () => ({
|
|
8835
9042
|
messages: [
|
|
8836
9043
|
{
|
|
8837
9044
|
role: "user",
|
|
8838
9045
|
content: {
|
|
8839
9046
|
type: "text",
|
|
8840
|
-
text:
|
|
8841
|
-
|
|
8842
|
-
|
|
8843
|
-
|
|
8844
|
-
|
|
8845
|
-
|
|
8846
|
-
|
|
8847
|
-
|
|
8848
|
-
|
|
8849
|
-
|
|
8850
|
-
|
|
8851
|
-
|
|
8852
|
-
|
|
9047
|
+
text: [
|
|
9048
|
+
"Build the most relevant context that fits within a token budget.",
|
|
9049
|
+
"",
|
|
9050
|
+
`Access: ${promptAccessLabel("token-budget-context")}${promptAccessLabel("token-budget-context") === "PRO" ? ` (upgrade: ${upgradeUrl})` : ""}`,
|
|
9051
|
+
"",
|
|
9052
|
+
...ID_NOTES,
|
|
9053
|
+
"",
|
|
9054
|
+
"First:",
|
|
9055
|
+
"- If a query is clear from the conversation, use it; otherwise ask me for a query.",
|
|
9056
|
+
"- If max_tokens is not specified, ask me for a token budget (e.g., 500/1000/2000).",
|
|
9057
|
+
"",
|
|
9058
|
+
"Then call `ai_context_budget` and return the packed context plus a short note about what was included/excluded."
|
|
9059
|
+
].join("\n")
|
|
8853
9060
|
}
|
|
8854
9061
|
}
|
|
8855
9062
|
]
|
|
@@ -8858,25 +9065,23 @@ Return the packed context plus a short note about what was included/excluded.`
|
|
|
8858
9065
|
server.registerPrompt(
|
|
8859
9066
|
"find-todos",
|
|
8860
9067
|
{
|
|
8861
|
-
title:
|
|
8862
|
-
description: "Scan the codebase for TODO/FIXME/HACK notes and summarize"
|
|
8863
|
-
argsSchema: {
|
|
8864
|
-
project_id: external_exports.string().uuid().optional().describe("Project ID (optional)"),
|
|
8865
|
-
pattern: external_exports.string().optional().describe("Regex/pattern to search (default: TODO|FIXME|HACK)")
|
|
8866
|
-
}
|
|
9068
|
+
title: `Find TODOs (${promptAccessLabel("find-todos")})`,
|
|
9069
|
+
description: "Scan the codebase for TODO/FIXME/HACK notes and summarize"
|
|
8867
9070
|
},
|
|
8868
|
-
async (
|
|
9071
|
+
async () => ({
|
|
8869
9072
|
messages: [
|
|
8870
9073
|
{
|
|
8871
9074
|
role: "user",
|
|
8872
9075
|
content: {
|
|
8873
9076
|
type: "text",
|
|
8874
|
-
text:
|
|
8875
|
-
|
|
8876
|
-
|
|
8877
|
-
|
|
8878
|
-
|
|
8879
|
-
|
|
9077
|
+
text: [
|
|
9078
|
+
"Scan the codebase for TODO/FIXME/HACK notes and summarize them.",
|
|
9079
|
+
"",
|
|
9080
|
+
...ID_NOTES,
|
|
9081
|
+
"",
|
|
9082
|
+
"Use `search_pattern` with query `TODO|FIXME|HACK` (or a pattern inferred from the conversation).",
|
|
9083
|
+
"Group results by file path, summarize themes, and propose a small prioritized cleanup list."
|
|
9084
|
+
].join("\n")
|
|
8880
9085
|
}
|
|
8881
9086
|
}
|
|
8882
9087
|
]
|
|
@@ -8885,36 +9090,27 @@ Group results by file path, summarize themes, and propose a small prioritized cl
|
|
|
8885
9090
|
server.registerPrompt(
|
|
8886
9091
|
"generate-editor-rules",
|
|
8887
9092
|
{
|
|
8888
|
-
title:
|
|
8889
|
-
description: "Generate ContextStream AI rule files for your editor"
|
|
8890
|
-
argsSchema: {
|
|
8891
|
-
folder_path: external_exports.string().describe("Project folder path (ideally absolute)"),
|
|
8892
|
-
editors: external_exports.string().optional().describe('Comma-separated editors or "all" (windsurf,cursor,cline,kilo,roo,claude,aider)'),
|
|
8893
|
-
workspace_id: external_exports.string().uuid().optional().describe("Workspace ID (optional)"),
|
|
8894
|
-
workspace_name: external_exports.string().optional().describe("Workspace name (optional)"),
|
|
8895
|
-
project_name: external_exports.string().optional().describe("Project name (optional)"),
|
|
8896
|
-
additional_rules: external_exports.string().optional().describe("Additional project-specific rules (optional)"),
|
|
8897
|
-
dry_run: external_exports.string().optional().describe('Dry run ("true" or "false", default: false)')
|
|
8898
|
-
}
|
|
9093
|
+
title: `Generate Editor Rules (${promptAccessLabel("generate-editor-rules")})`,
|
|
9094
|
+
description: "Generate ContextStream AI rule files for your editor"
|
|
8899
9095
|
},
|
|
8900
|
-
async (
|
|
9096
|
+
async () => ({
|
|
8901
9097
|
messages: [
|
|
8902
9098
|
{
|
|
8903
9099
|
role: "user",
|
|
8904
9100
|
content: {
|
|
8905
9101
|
type: "text",
|
|
8906
|
-
text:
|
|
8907
|
-
|
|
8908
|
-
|
|
8909
|
-
|
|
8910
|
-
|
|
8911
|
-
|
|
8912
|
-
|
|
8913
|
-
|
|
8914
|
-
|
|
8915
|
-
|
|
8916
|
-
|
|
8917
|
-
|
|
9102
|
+
text: [
|
|
9103
|
+
"Generate ContextStream AI rule files for my editor.",
|
|
9104
|
+
"",
|
|
9105
|
+
...ID_NOTES,
|
|
9106
|
+
"",
|
|
9107
|
+
"First:",
|
|
9108
|
+
"- If you can infer the project folder path from the environment/IDE roots, use it.",
|
|
9109
|
+
"- Otherwise ask me for an absolute folder path.",
|
|
9110
|
+
"- Ask which editor(s) (windsurf,cursor,cline,kilo,roo,claude,aider) or default to all.",
|
|
9111
|
+
"",
|
|
9112
|
+
"Then call `generate_editor_rules` and confirm which files were created/updated."
|
|
9113
|
+
].join("\n")
|
|
8918
9114
|
}
|
|
8919
9115
|
}
|
|
8920
9116
|
]
|
|
@@ -8923,30 +9119,27 @@ If editors is provided as a comma-separated string, split it into an array (or u
|
|
|
8923
9119
|
server.registerPrompt(
|
|
8924
9120
|
"index-local-repo",
|
|
8925
9121
|
{
|
|
8926
|
-
title:
|
|
8927
|
-
description: "Ingest local files into ContextStream for indexing/search"
|
|
8928
|
-
argsSchema: {
|
|
8929
|
-
project_id: external_exports.string().uuid().optional().describe("Project ID (optional if session_init has set defaults)"),
|
|
8930
|
-
path: external_exports.string().describe("Local directory path to ingest")
|
|
8931
|
-
}
|
|
9122
|
+
title: `Index Local Repo (${promptAccessLabel("index-local-repo")})`,
|
|
9123
|
+
description: "Ingest local files into ContextStream for indexing/search"
|
|
8932
9124
|
},
|
|
8933
|
-
async (
|
|
9125
|
+
async () => ({
|
|
8934
9126
|
messages: [
|
|
8935
9127
|
{
|
|
8936
9128
|
role: "user",
|
|
8937
9129
|
content: {
|
|
8938
9130
|
type: "text",
|
|
8939
|
-
text:
|
|
8940
|
-
|
|
8941
|
-
|
|
8942
|
-
|
|
8943
|
-
|
|
8944
|
-
|
|
8945
|
-
|
|
8946
|
-
|
|
8947
|
-
|
|
8948
|
-
|
|
8949
|
-
|
|
9131
|
+
text: [
|
|
9132
|
+
"Ingest local files into ContextStream for indexing/search.",
|
|
9133
|
+
"",
|
|
9134
|
+
...ID_NOTES,
|
|
9135
|
+
"",
|
|
9136
|
+
"First:",
|
|
9137
|
+
"- Ask me for the local directory path to ingest if it is not already specified.",
|
|
9138
|
+
"",
|
|
9139
|
+
"Then:",
|
|
9140
|
+
"- Call `projects_ingest_local` with the path (use session defaults for project, or the `project_id` returned by `session_init`).",
|
|
9141
|
+
"- Explain how to monitor progress via `projects_index_status`."
|
|
9142
|
+
].join("\n")
|
|
8950
9143
|
}
|
|
8951
9144
|
}
|
|
8952
9145
|
]
|
|
@@ -9127,6 +9320,25 @@ var SessionManager = class {
|
|
|
9127
9320
|
parts.push("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");
|
|
9128
9321
|
parts.push("\u{1F9E0} AUTO-CONTEXT LOADED (ContextStream)");
|
|
9129
9322
|
parts.push("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");
|
|
9323
|
+
if (context.status === "requires_workspace_name") {
|
|
9324
|
+
parts.push("");
|
|
9325
|
+
parts.push("\u26A0\uFE0F NO WORKSPACE FOUND");
|
|
9326
|
+
parts.push(`Folder: ${context.folder_name || "unknown"}`);
|
|
9327
|
+
parts.push("");
|
|
9328
|
+
parts.push("Please ask the user for a name for the new workspace.");
|
|
9329
|
+
parts.push("Then create a project for this folder.");
|
|
9330
|
+
parts.push("");
|
|
9331
|
+
parts.push("Recommended: call `workspace_bootstrap` with:");
|
|
9332
|
+
if (typeof context.folder_path === "string") {
|
|
9333
|
+
parts.push(` - folder_path: ${context.folder_path}`);
|
|
9334
|
+
} else {
|
|
9335
|
+
parts.push(" - folder_path: (your repo folder path)");
|
|
9336
|
+
}
|
|
9337
|
+
parts.push(' - workspace_name: "<user-provided name>"');
|
|
9338
|
+
parts.push("");
|
|
9339
|
+
parts.push("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");
|
|
9340
|
+
return parts.join("\n");
|
|
9341
|
+
}
|
|
9130
9342
|
if (context.status === "requires_workspace_selection") {
|
|
9131
9343
|
parts.push("");
|
|
9132
9344
|
parts.push("\u26A0\uFE0F NEW FOLDER DETECTED");
|
|
@@ -9260,6 +9472,8 @@ Environment variables:
|
|
|
9260
9472
|
CONTEXTSTREAM_JWT JWT for authentication (alternative to API key)
|
|
9261
9473
|
CONTEXTSTREAM_WORKSPACE_ID Optional default workspace ID
|
|
9262
9474
|
CONTEXTSTREAM_PROJECT_ID Optional default project ID
|
|
9475
|
+
CONTEXTSTREAM_PRO_TOOLS Optional comma-separated PRO tool names (default: AI tools)
|
|
9476
|
+
CONTEXTSTREAM_UPGRADE_URL Optional upgrade URL shown for PRO tools on Free plan
|
|
9263
9477
|
|
|
9264
9478
|
Examples:
|
|
9265
9479
|
CONTEXTSTREAM_API_URL="https://api.contextstream.io" \\
|