holycodex 0.5.2 → 0.5.3
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/package.json +1 -1
- package/plugin/.codex-plugin/plugin.json +1 -1
- package/plugin/agents/explorer.toml +1 -1
- package/plugin/agents/librarian.toml +1 -1
- package/plugin/agents/worker.toml +1 -1
- package/plugin/runtime/cli.js +2 -2
- package/plugin/runtime/core-instructions.js +1 -1
- package/plugin/runtime/git-bash.js +4 -4
- package/plugin/runtime/lsp.js +84 -138
- package/plugin/runtime/mcp-stdio-core.js +5 -2
- package/plugin/skills/define-goal/SKILL.md +3 -3
- package/plugin/skills/frontend/SKILL.md +13 -13
- package/plugin/skills/programming/SKILL.md +16 -7
- package/plugin/skills/security-research/SKILL.md +8 -8
package/package.json
CHANGED
|
@@ -2,5 +2,5 @@ description = "Use for a narrow, read-only repository fact question with explici
|
|
|
2
2
|
model = "gpt-5.6-luna"
|
|
3
3
|
model_reasoning_effort = "low"
|
|
4
4
|
developer_instructions = """
|
|
5
|
-
Start: "I detect investigation intent — [reason]. [action]." Default user-facing replies: grammatical sentences; no filler or hedging. Preserve technical terms, code, paths, error text, and commit keywords; use full grammar for safety warnings, irreversible confirmations, ordered steps, ambiguity, or clarification. Accept one task packet containing exact question; repository root; allowed paths and symbols; forbidden paths; relevant architecture and existing behavior; required skills; exact inputs; output format; acceptance criteria; required commands or evidence; unchanged constraints; prohibited expansion; known uncertainty; blocker behavior; exact stop condition. Reject incomplete or ambiguous packets. Inspect only assigned scope. On native Windows, before any shell call resolve `mcp__git_bash__run` from the full callable registry, including deferred tools, and use it when available; otherwise use native shell directly. Search, read, diagnose, or inspect history; never edit, install, research external facts, choose architecture, make final judgments, ask user, or broaden scope. Stop when criteria pass, evidence is unavailable, scope conflicts, or a write is required. Return exactly requested format with paths, symbols, commands, decisive output, uncertainty or blocker; no proposed extra work.
|
|
5
|
+
Start: "I detect investigation intent — [reason]. [action]." Default user-facing replies: grammatical sentences; no filler or hedging. Preserve technical terms, code, paths, error text, and commit keywords; use full grammar for safety warnings, irreversible confirmations, ordered steps, ambiguity, or clarification. Before any plan, skill routing, or task action, inspect the full callable tool registry, including deferred tools; treat only that registry as availability evidence. Accept one task packet containing exact question; repository root; allowed paths and symbols; forbidden paths; relevant architecture and existing behavior; required skills; exact inputs; output format; acceptance criteria; required commands or evidence; unchanged constraints; prohibited expansion; known uncertainty; blocker behavior; exact stop condition. Reject incomplete or ambiguous packets. Inspect only assigned scope. On native Windows, before any shell call resolve `mcp__git_bash__run` from the full callable registry, including deferred tools, and use it when available; otherwise use native shell directly. Search, read, diagnose, or inspect history; never edit, install, research external facts, choose architecture, make final judgments, ask user, or broaden scope. Stop when criteria pass, evidence is unavailable, scope conflicts, or a write is required. Return exactly requested format with paths, symbols, commands, decisive output, uncertainty or blocker; no proposed extra work.
|
|
6
6
|
"""
|
|
@@ -2,5 +2,5 @@ description = "Use for a narrow current external-fact question requiring primary
|
|
|
2
2
|
model = "gpt-5.6-luna"
|
|
3
3
|
model_reasoning_effort = "low"
|
|
4
4
|
developer_instructions = """
|
|
5
|
-
Start: "I detect research intent — [reason]. [action]." Default user-facing replies: grammatical sentences; no filler or hedging. Preserve technical terms, code, paths, error text, and commit keywords; use full grammar for safety warnings, irreversible confirmations, ordered steps, ambiguity, or clarification. Accept one task packet containing exact question; repository root only as context; allowed paths and symbols, normally none; forbidden paths and sources; allowed external sources; relevant architecture and existing behavior; required skills; exact inputs; output format; acceptance criteria; required commands or evidence; unchanged constraints; prohibited expansion; known uncertainty; blocker behavior; exact stop condition. Reject incomplete or ambiguous packets. On native Windows, before any shell call resolve `mcp__git_bash__run` from the full callable registry, including deferred tools, and use it when available; otherwise use native shell directly. Prefer current primary sources; distinguish source fact from inference. Never inspect repo beyond supplied context, implement, write externally, choose architecture, make final judgments, ask user, or broaden scope. Stop when criteria pass, authoritative evidence is unavailable or conflicting, or answer needs repository work. Return exactly requested format with claim-linked source, version or date, conflicts, inference, uncertainty or blocker; no proposed extra work.
|
|
5
|
+
Start: "I detect research intent — [reason]. [action]." Default user-facing replies: grammatical sentences; no filler or hedging. Preserve technical terms, code, paths, error text, and commit keywords; use full grammar for safety warnings, irreversible confirmations, ordered steps, ambiguity, or clarification. Before any plan, skill routing, or task action, inspect the full callable tool registry, including deferred tools; treat only that registry as availability evidence. Accept one task packet containing exact question; repository root only as context; allowed paths and symbols, normally none; forbidden paths and sources; allowed external sources; relevant architecture and existing behavior; required skills; exact inputs; output format; acceptance criteria; required commands or evidence; unchanged constraints; prohibited expansion; known uncertainty; blocker behavior; exact stop condition. Reject incomplete or ambiguous packets. On native Windows, before any shell call resolve `mcp__git_bash__run` from the full callable registry, including deferred tools, and use it when available; otherwise use native shell directly. Prefer current primary sources; distinguish source fact from inference. Never inspect repo beyond supplied context, implement, write externally, choose architecture, make final judgments, ask user, or broaden scope. Stop when criteria pass, authoritative evidence is unavailable or conflicting, or answer needs repository work. Return exactly requested format with claim-linked source, version or date, conflicts, inference, uncertainty or blocker; no proposed extra work.
|
|
6
6
|
"""
|
|
@@ -2,5 +2,5 @@ description = "Use for an isolated implementation slice with fixed files and acc
|
|
|
2
2
|
model = "gpt-5.6-luna"
|
|
3
3
|
model_reasoning_effort = "medium"
|
|
4
4
|
developer_instructions = """
|
|
5
|
-
Start: "I detect implementation intent — [reason]. [action]." Default user-facing replies: grammatical sentences; no filler or hedging. Preserve technical terms, code, paths, error text, and commit keywords; use full grammar for safety warnings, irreversible confirmations, ordered steps, ambiguity, or clarification. Accept one task packet containing exact implementation outcome; repository root; allowed paths and symbols; forbidden paths; relevant architecture and existing behavior; required skills; exact inputs; output format; acceptance criteria; required commands or evidence; unchanged constraints; prohibited expansion; known uncertainty; blocker behavior; exact stop condition. Reject or stop on ambiguity, overlap, architecture choice, coupled out-of-scope work, user-work conflict, or missing authority. On native Windows, before any shell call resolve `mcp__git_bash__run` from the full callable registry, including deferred tools, and use it when available; otherwise use native shell directly. Prompt, skill, or instruction task: load caveman first; preserve constraints. Load required skills before governed action. Change only assigned files. Preserve architecture, API, behavior, naming, style, and user work. Add no speculative cleanup, abstraction, dependency, docs, or scope. Run specified proof; never claim integration or final verification. Return exactly requested format with changed paths and behavior, command results, criteria status, blocker or residual risk; no proposed extra work.
|
|
5
|
+
Start: "I detect implementation intent — [reason]. [action]." Default user-facing replies: grammatical sentences; no filler or hedging. Preserve technical terms, code, paths, error text, and commit keywords; use full grammar for safety warnings, irreversible confirmations, ordered steps, ambiguity, or clarification. Before any plan, skill routing, or task action, inspect the full callable tool registry, including deferred tools; treat only that registry as availability evidence. Accept one task packet containing exact implementation outcome; repository root; allowed paths and symbols; forbidden paths; relevant architecture and existing behavior; required skills; exact inputs; output format; acceptance criteria; required commands or evidence; unchanged constraints; prohibited expansion; known uncertainty; blocker behavior; exact stop condition. Reject or stop on ambiguity, overlap, architecture choice, coupled out-of-scope work, user-work conflict, or missing authority. On native Windows, before any shell call resolve `mcp__git_bash__run` from the full callable registry, including deferred tools, and use it when available; otherwise use native shell directly. Prompt, skill, or instruction task: load caveman first; preserve constraints. Load required skills before governed action. Change only assigned files. Preserve architecture, API, behavior, naming, style, and user work. Add no speculative cleanup, abstraction, dependency, docs, or scope. Run specified proof; never claim integration or final verification. Return exactly requested format with changed paths and behavior, command results, criteria status, blocker or residual risk; no proposed extra work.
|
|
6
6
|
"""
|
package/plugin/runtime/cli.js
CHANGED
|
@@ -122,7 +122,7 @@ function paths(home = process.env.CODEX_HOME ?? join(homedir(), ".codex")) {
|
|
|
122
122
|
config: join(home, "config.toml"),
|
|
123
123
|
marketplaceCache,
|
|
124
124
|
cacheRoot,
|
|
125
|
-
cache: join(cacheRoot, "0.5.
|
|
125
|
+
cache: join(cacheRoot, "0.5.3"),
|
|
126
126
|
agents: join(home, "holycodex", "agents"),
|
|
127
127
|
legacy: [
|
|
128
128
|
join(home, "plugins", "cache", "sisyphuslabs", "omo"),
|
|
@@ -210,7 +210,7 @@ async function cleanup(_options) {
|
|
|
210
210
|
}
|
|
211
211
|
//#endregion
|
|
212
212
|
//#region src/cli.ts
|
|
213
|
-
var VERSION = "0.5.
|
|
213
|
+
var VERSION = "0.5.3";
|
|
214
214
|
var HELP = `HolyCodex ${VERSION}\n\nUsage: holycodex <install|cleanup> [options]\n\nOptions:\n --help Show help\n --version Show version\n --no-tui Accepted; commands are noninteractive\n --codex-autonomous Set autonomous Codex permissions (default)\n --no-codex-autonomous Preserve existing Codex permissions\n --json Print machine-readable result\n`;
|
|
215
215
|
async function main() {
|
|
216
216
|
const args = process$1.argv.slice(2);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
//#region src/core-instructions.ts
|
|
2
|
-
var CORE_INSTRUCTIONS = "HolyCodex: Start first user-facing update: \"I detect [fix/implementation/investigation/question] intent — [reason]. [action].\" Act. Default user-facing replies: grammatical sentences; no filler or hedging. Preserve technical terms, code, paths, error text, and commit keywords; use full grammar for safety warnings, irreversible confirmations, ordered steps, ambiguity, or clarification. Shell: on native Windows, before any shell call resolve `mcp__git_bash__run` from the full callable registry, including deferred tools, and use it when available; otherwise use the native shell directly. Prompt, skill, or instruction edit: load caveman; preserve constraints. Main agent owns intent, scope, architecture, decisions, integration, and final verification. Load each applicable skill before its governed action; a skill alone is sufficient when the main agent can complete the work directly. Delegate only a bounded, independent, unambiguous slice cheaper to integrate than local work and suitable for its Luna model: explorer=read-only exact repo facts; librarian=read-only current external facts from primary sources; worker=isolated fixed-scope implementation. Never delegate trivial or coupled work, architecture, user clarification, integration, final judgment, or final verification. Every packet states exact question or outcome; repository root; allowed paths and symbols; forbidden paths; relevant architecture and existing behavior; required skills; exact inputs; output format; acceptance criteria; required commands or evidence; unchanged constraints; prohibited expansion; known uncertainty; blocker behavior; exact stop condition. Use concrete names, paths, APIs, functions, tests, versions, and expected observations when known; include no unrelated transcript. Treat returns as input: inspect, reconcile, integrate, and verify. Stop when packet is satisfied or blocked; never recurse or create agent organizations. Use GPT 5.6 Luna low for explorer and librarian; use GPT 5.6 Luna medium for worker.";
|
|
2
|
+
var CORE_INSTRUCTIONS = "HolyCodex: Start first user-facing update: \"I detect [fix/implementation/investigation/question] intent — [reason]. [action].\" Act. Default user-facing replies: grammatical sentences; no filler or hedging. Preserve technical terms, code, paths, error text, and commit keywords; use full grammar for safety warnings, irreversible confirmations, ordered steps, ambiguity, or clarification. Before any plan, skill routing, delegation, or task action, inspect the full callable tool registry, including deferred tools; treat only that registry as availability evidence. Shell: on native Windows, before any shell call resolve `mcp__git_bash__run` from the full callable registry, including deferred tools, and use it when available; otherwise use the native shell directly. Prompt, skill, or instruction edit: load caveman; preserve constraints. Main agent owns intent, scope, architecture, decisions, integration, and final verification. Load each applicable skill before its governed action; a skill alone is sufficient when the main agent can complete the work directly. Delegate only a bounded, independent, unambiguous slice cheaper to integrate than local work and suitable for its Luna model: explorer=read-only exact repo facts; librarian=read-only current external facts from primary sources; worker=isolated fixed-scope implementation. Never delegate trivial or coupled work, architecture, user clarification, integration, final judgment, or final verification. Every packet states exact question or outcome; repository root; allowed paths and symbols; forbidden paths; relevant architecture and existing behavior; required skills; exact inputs; output format; acceptance criteria; required commands or evidence; unchanged constraints; prohibited expansion; known uncertainty; blocker behavior; exact stop condition. Use concrete names, paths, APIs, functions, tests, versions, and expected observations when known; include no unrelated transcript. Treat returns as input: inspect, reconcile, integrate, and verify. Stop when packet is satisfied or blocked; never recurse or create agent organizations. Use GPT 5.6 Luna low for explorer and librarian; use GPT 5.6 Luna medium for worker.";
|
|
3
3
|
//#endregion
|
|
4
4
|
export { CORE_INSTRUCTIONS as t };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as
|
|
2
|
+
import { a as stackOrMessageFromError, i as messageFromError, n as errorResponse, o as successResponse, r as jsonRpcId, s as isPlainRecord, t as runJsonRpcStdioServer } from "./mcp-stdio-core.js";
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { argv, stderr } from "node:process";
|
|
5
5
|
import { tmpdir } from "node:os";
|
|
@@ -166,7 +166,7 @@ async function handleGitBashMcpRequest(input, options = {}) {
|
|
|
166
166
|
capabilities: { tools: { listChanged: false } },
|
|
167
167
|
serverInfo: {
|
|
168
168
|
name: "git_bash",
|
|
169
|
-
version: "0.5.
|
|
169
|
+
version: "0.5.3"
|
|
170
170
|
},
|
|
171
171
|
protocolVersion: protocolVersionFromInput(input) ?? "2024-11-05"
|
|
172
172
|
});
|
|
@@ -216,7 +216,7 @@ async function runToolResponse(id, args, options) {
|
|
|
216
216
|
});
|
|
217
217
|
return toolResponse(id, JSON.stringify(result, null, 2));
|
|
218
218
|
} catch (error) {
|
|
219
|
-
return toolResponse(id,
|
|
219
|
+
return toolResponse(id, messageFromError(error), true);
|
|
220
220
|
}
|
|
221
221
|
}
|
|
222
222
|
function toolsForOptions(options) {
|
|
@@ -349,7 +349,7 @@ async function main() {
|
|
|
349
349
|
process.exitCode = 2;
|
|
350
350
|
}
|
|
351
351
|
main().catch((error) => {
|
|
352
|
-
stderr.write(`${
|
|
352
|
+
stderr.write(`${stackOrMessageFromError(error)}\n`);
|
|
353
353
|
process.exitCode = 1;
|
|
354
354
|
});
|
|
355
355
|
//#endregion
|
package/plugin/runtime/lsp.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as
|
|
2
|
+
import { a as stackOrMessageFromError, i as messageFromError, n as errorResponse, o as successResponse, r as jsonRpcId, s as isPlainRecord, t as runJsonRpcStdioServer } from "./mcp-stdio-core.js";
|
|
3
3
|
import { basename, delimiter, dirname, extname, isAbsolute, join, relative, resolve } from "node:path";
|
|
4
4
|
import { argv, execPath, stderr } from "node:process";
|
|
5
5
|
import { homedir, tmpdir } from "node:os";
|
|
@@ -94,7 +94,7 @@ function isLspDeadConnectionError(err) {
|
|
|
94
94
|
//#region packages/lsp-core/src/lsp/cleanup-errors.ts
|
|
95
95
|
function reportBestEffortCleanupError(operation, error) {
|
|
96
96
|
if (process.env["CODEX_LSP_DEBUG_CLEANUP"] !== "1") return;
|
|
97
|
-
const message =
|
|
97
|
+
const message = messageFromError(error);
|
|
98
98
|
console.error(`[codex-lsp] ignored ${operation} failure during cleanup: ${message}`);
|
|
99
99
|
}
|
|
100
100
|
var STOP_HARD_KILL_TIMEOUT_MS = 5e3;
|
|
@@ -328,15 +328,12 @@ function parseContentLength(headers) {
|
|
|
328
328
|
}
|
|
329
329
|
return null;
|
|
330
330
|
}
|
|
331
|
-
function isJsonRpcObject(value) {
|
|
332
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
333
|
-
}
|
|
334
331
|
function getMessageId(message) {
|
|
335
332
|
const id = message["id"];
|
|
336
333
|
if (typeof id === "number" || typeof id === "string" || id === null) return id;
|
|
337
334
|
}
|
|
338
335
|
function jsonRpcErrorToError(value) {
|
|
339
|
-
if (!
|
|
336
|
+
if (!isPlainRecord(value)) return /* @__PURE__ */ new Error("JSON-RPC request failed");
|
|
340
337
|
const message = typeof value["message"] === "string" ? value["message"] : "JSON-RPC request failed";
|
|
341
338
|
const error = new Error(message);
|
|
342
339
|
if (typeof value["code"] === "number") error.name = `JsonRpcError(${value["code"]})`;
|
|
@@ -499,21 +496,18 @@ function spawnProcess(command, options) {
|
|
|
499
496
|
}
|
|
500
497
|
//#endregion
|
|
501
498
|
//#region packages/lsp-core/src/lsp/transport.ts
|
|
502
|
-
function isRecord$3(value) {
|
|
503
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
504
|
-
}
|
|
505
499
|
function parseConfigurationItems(params) {
|
|
506
|
-
if (!
|
|
500
|
+
if (!isPlainRecord(params) || !Array.isArray(params["items"])) return [];
|
|
507
501
|
const items = [];
|
|
508
502
|
for (const item of params["items"]) {
|
|
509
|
-
if (!
|
|
503
|
+
if (!isPlainRecord(item)) continue;
|
|
510
504
|
const section = item["section"];
|
|
511
505
|
items.push(section === void 0 || typeof section !== "string" ? {} : { section });
|
|
512
506
|
}
|
|
513
507
|
return items;
|
|
514
508
|
}
|
|
515
509
|
function parseDiagnosticsParams(params) {
|
|
516
|
-
if (!
|
|
510
|
+
if (!isPlainRecord(params) || typeof params["uri"] !== "string") return null;
|
|
517
511
|
const diagnostics = Array.isArray(params["diagnostics"]) ? params["diagnostics"].filter(isDiagnostic) : [];
|
|
518
512
|
return {
|
|
519
513
|
uri: params["uri"],
|
|
@@ -680,13 +674,13 @@ function createLspSpawnEnv(_root, input) {
|
|
|
680
674
|
return { ...input };
|
|
681
675
|
}
|
|
682
676
|
function isDiagnostic(value) {
|
|
683
|
-
return
|
|
677
|
+
return isPlainRecord(value) && isRange(value["range"]) && typeof value["message"] === "string";
|
|
684
678
|
}
|
|
685
679
|
function isRange(value) {
|
|
686
|
-
return
|
|
680
|
+
return isPlainRecord(value) && isPosition(value["start"]) && isPosition(value["end"]);
|
|
687
681
|
}
|
|
688
682
|
function isPosition(value) {
|
|
689
|
-
return
|
|
683
|
+
return isPlainRecord(value) && typeof value["line"] === "number" && typeof value["character"] === "number";
|
|
690
684
|
}
|
|
691
685
|
//#endregion
|
|
692
686
|
//#region packages/lsp-core/src/lsp/connection.ts
|
|
@@ -969,10 +963,9 @@ var LspClient = class extends LspClientConnection {
|
|
|
969
963
|
});
|
|
970
964
|
}
|
|
971
965
|
async definition(filePath, line, character) {
|
|
972
|
-
const
|
|
973
|
-
await this.openFile(absPath);
|
|
966
|
+
const textDocument = await this.openTextDocument(filePath);
|
|
974
967
|
return this.sendRequest("textDocument/definition", {
|
|
975
|
-
textDocument
|
|
968
|
+
textDocument,
|
|
976
969
|
position: {
|
|
977
970
|
line: line - 1,
|
|
978
971
|
character
|
|
@@ -980,10 +973,9 @@ var LspClient = class extends LspClientConnection {
|
|
|
980
973
|
});
|
|
981
974
|
}
|
|
982
975
|
async references(filePath, line, character, includeDeclaration = true) {
|
|
983
|
-
const
|
|
984
|
-
await this.openFile(absPath);
|
|
976
|
+
const textDocument = await this.openTextDocument(filePath);
|
|
985
977
|
return this.sendRequest("textDocument/references", {
|
|
986
|
-
textDocument
|
|
978
|
+
textDocument,
|
|
987
979
|
position: {
|
|
988
980
|
line: line - 1,
|
|
989
981
|
character
|
|
@@ -992,9 +984,8 @@ var LspClient = class extends LspClientConnection {
|
|
|
992
984
|
});
|
|
993
985
|
}
|
|
994
986
|
async documentSymbols(filePath) {
|
|
995
|
-
const
|
|
996
|
-
|
|
997
|
-
return this.sendRequest("textDocument/documentSymbol", { textDocument: { uri: pathToFileURL(absPath).href } });
|
|
987
|
+
const textDocument = await this.openTextDocument(filePath);
|
|
988
|
+
return this.sendRequest("textDocument/documentSymbol", { textDocument });
|
|
998
989
|
}
|
|
999
990
|
async workspaceSymbols(query) {
|
|
1000
991
|
return this.sendRequest("workspace/symbol", { query });
|
|
@@ -1005,9 +996,7 @@ var LspClient = class extends LspClientConnection {
|
|
|
1005
996
|
return /unsupported|not supported|method not found|unknown request/i.test(error.message);
|
|
1006
997
|
}
|
|
1007
998
|
async diagnostics(filePath) {
|
|
1008
|
-
const
|
|
1009
|
-
const uri = pathToFileURL(absPath).href;
|
|
1010
|
-
await this.openFile(absPath);
|
|
999
|
+
const { uri } = await this.openTextDocument(filePath);
|
|
1011
1000
|
await new Promise((r) => setTimeout(r, POST_DIAGNOSTICS_WAIT_MS));
|
|
1012
1001
|
try {
|
|
1013
1002
|
const result = await this.sendRequest("textDocument/diagnostic", { textDocument: { uri } });
|
|
@@ -1018,10 +1007,9 @@ var LspClient = class extends LspClientConnection {
|
|
|
1018
1007
|
return { items: this.getStoredDiagnostics(uri) };
|
|
1019
1008
|
}
|
|
1020
1009
|
async prepareRename(filePath, line, character) {
|
|
1021
|
-
const
|
|
1022
|
-
await this.openFile(absPath);
|
|
1010
|
+
const textDocument = await this.openTextDocument(filePath);
|
|
1023
1011
|
return this.sendRequest("textDocument/prepareRename", {
|
|
1024
|
-
textDocument
|
|
1012
|
+
textDocument,
|
|
1025
1013
|
position: {
|
|
1026
1014
|
line: line - 1,
|
|
1027
1015
|
character
|
|
@@ -1029,10 +1017,9 @@ var LspClient = class extends LspClientConnection {
|
|
|
1029
1017
|
});
|
|
1030
1018
|
}
|
|
1031
1019
|
async rename(filePath, line, character, newName) {
|
|
1032
|
-
const
|
|
1033
|
-
await this.openFile(absPath);
|
|
1020
|
+
const textDocument = await this.openTextDocument(filePath);
|
|
1034
1021
|
return this.sendRequest("textDocument/rename", {
|
|
1035
|
-
textDocument
|
|
1022
|
+
textDocument,
|
|
1036
1023
|
position: {
|
|
1037
1024
|
line: line - 1,
|
|
1038
1025
|
character
|
|
@@ -1040,6 +1027,11 @@ var LspClient = class extends LspClientConnection {
|
|
|
1040
1027
|
newName
|
|
1041
1028
|
});
|
|
1042
1029
|
}
|
|
1030
|
+
async openTextDocument(filePath) {
|
|
1031
|
+
const absPath = resolve(contextCwd(), filePath);
|
|
1032
|
+
await this.openFile(absPath);
|
|
1033
|
+
return { uri: pathToFileURL(absPath).href };
|
|
1034
|
+
}
|
|
1043
1035
|
};
|
|
1044
1036
|
//#endregion
|
|
1045
1037
|
//#region packages/lsp-core/src/lsp/process-signal-cleanup.ts
|
|
@@ -1352,15 +1344,12 @@ function writeInstallDecisions(decisions) {
|
|
|
1352
1344
|
renameSync(tmpPath, path);
|
|
1353
1345
|
}
|
|
1354
1346
|
function isInstallDecisions(value) {
|
|
1355
|
-
return
|
|
1347
|
+
return isPlainRecord(value) && Object.values(value).every(isInstallDecisionRecord);
|
|
1356
1348
|
}
|
|
1357
1349
|
function isInstallDecisionRecord(value) {
|
|
1358
|
-
if (!
|
|
1350
|
+
if (!isPlainRecord(value)) return false;
|
|
1359
1351
|
return isInstallDecision(value["decision"]) && typeof value["decidedAt"] === "string";
|
|
1360
1352
|
}
|
|
1361
|
-
function isRecord$2(value) {
|
|
1362
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1363
|
-
}
|
|
1364
1353
|
//#endregion
|
|
1365
1354
|
//#region packages/lsp-core/src/lsp/server-definitions.ts
|
|
1366
1355
|
var LSP_INSTALL_HINTS = {
|
|
@@ -1826,31 +1815,28 @@ function applyOptionalServerFields(server, entry) {
|
|
|
1826
1815
|
if (entry.initialization !== void 0) server.initialization = entry.initialization;
|
|
1827
1816
|
}
|
|
1828
1817
|
function isConfigJson(value) {
|
|
1829
|
-
if (!
|
|
1818
|
+
if (!isPlainRecord(value)) return false;
|
|
1830
1819
|
const lsp = value["lsp"];
|
|
1831
|
-
return lsp === void 0 ||
|
|
1820
|
+
return lsp === void 0 || isPlainRecord(lsp);
|
|
1832
1821
|
}
|
|
1833
1822
|
function parseLspEntry(value) {
|
|
1834
1823
|
return isLspEntry(value) ? value : null;
|
|
1835
1824
|
}
|
|
1836
1825
|
function isLspEntry(value) {
|
|
1837
|
-
if (!
|
|
1826
|
+
if (!isPlainRecord(value)) return false;
|
|
1838
1827
|
const disabled = value["disabled"];
|
|
1839
1828
|
const command = value["command"];
|
|
1840
1829
|
const extensions = value["extensions"];
|
|
1841
1830
|
const priority = value["priority"];
|
|
1842
1831
|
const env = value["env"];
|
|
1843
1832
|
const initialization = value["initialization"];
|
|
1844
|
-
return (disabled === void 0 || typeof disabled === "boolean") && (command === void 0 || isStringArray(command)) && (extensions === void 0 || isStringArray(extensions)) && (priority === void 0 || typeof priority === "number") && (env === void 0 || isStringRecord$1(env)) && (initialization === void 0 ||
|
|
1833
|
+
return (disabled === void 0 || typeof disabled === "boolean") && (command === void 0 || isStringArray(command)) && (extensions === void 0 || isStringArray(extensions)) && (priority === void 0 || typeof priority === "number") && (env === void 0 || isStringRecord$1(env)) && (initialization === void 0 || isPlainRecord(initialization));
|
|
1845
1834
|
}
|
|
1846
1835
|
function isStringArray(value) {
|
|
1847
1836
|
return Array.isArray(value) && value.every((item) => typeof item === "string");
|
|
1848
1837
|
}
|
|
1849
1838
|
function isStringRecord$1(value) {
|
|
1850
|
-
return
|
|
1851
|
-
}
|
|
1852
|
-
function isRecord$1(value) {
|
|
1853
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1839
|
+
return isPlainRecord(value) && Object.values(value).every((item) => typeof item === "string");
|
|
1854
1840
|
}
|
|
1855
1841
|
function getDisabledServerIds() {
|
|
1856
1842
|
const configs = loadAllConfigs();
|
|
@@ -2311,9 +2297,7 @@ var RUST_SRC_REPAIR_MESSAGE = [
|
|
|
2311
2297
|
" rustup component remove rust-src",
|
|
2312
2298
|
" rustup component add rust-src"
|
|
2313
2299
|
];
|
|
2314
|
-
|
|
2315
|
-
return error instanceof Error ? error.message : String(error);
|
|
2316
|
-
}
|
|
2300
|
+
var errorMessage = messageFromError;
|
|
2317
2301
|
function formatKnownLspStartupFailure(error) {
|
|
2318
2302
|
if (!(error instanceof LspProcessExitedError)) return null;
|
|
2319
2303
|
if (error.serverId !== "rust") return null;
|
|
@@ -2330,7 +2314,7 @@ function formatKnownLspStartupFailure(error) {
|
|
|
2330
2314
|
function handleMissingDependencyError(error) {
|
|
2331
2315
|
const knownStartupFailure = formatKnownLspStartupFailure(error);
|
|
2332
2316
|
if (knownStartupFailure) return knownStartupFailure;
|
|
2333
|
-
const message = errorMessage
|
|
2317
|
+
const message = errorMessage(error);
|
|
2334
2318
|
return message.includes("NOT INSTALLED") || message.includes("No LSP server configured") ? message : null;
|
|
2335
2319
|
}
|
|
2336
2320
|
//#endregion
|
|
@@ -2350,10 +2334,20 @@ function missingDependencyResult(error, details) {
|
|
|
2350
2334
|
}
|
|
2351
2335
|
};
|
|
2352
2336
|
}
|
|
2337
|
+
function missingDependencyResultOrThrow(error, details) {
|
|
2338
|
+
const result = missingDependencyResult(error, details);
|
|
2339
|
+
if (result !== null) return result;
|
|
2340
|
+
throw error;
|
|
2341
|
+
}
|
|
2353
2342
|
//#endregion
|
|
2354
2343
|
//#region packages/lsp-core/src/tools/parameters.ts
|
|
2355
|
-
|
|
2356
|
-
|
|
2344
|
+
var isRecord = isPlainRecord;
|
|
2345
|
+
function sourcePosition(params) {
|
|
2346
|
+
return {
|
|
2347
|
+
filePath: requireString(params, "filePath"),
|
|
2348
|
+
line: requireNumber(params, "line"),
|
|
2349
|
+
character: requireNumber(params, "character")
|
|
2350
|
+
};
|
|
2357
2351
|
}
|
|
2358
2352
|
function requireString(params, key) {
|
|
2359
2353
|
const value = params[key];
|
|
@@ -2449,7 +2443,7 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
2449
2443
|
truncated
|
|
2450
2444
|
});
|
|
2451
2445
|
} catch (error) {
|
|
2452
|
-
|
|
2446
|
+
return missingDependencyResultOrThrow(error, {
|
|
2453
2447
|
filePath,
|
|
2454
2448
|
severity,
|
|
2455
2449
|
mode: "file",
|
|
@@ -2457,8 +2451,6 @@ async function executeLspDiagnostics(params, signal) {
|
|
|
2457
2451
|
totalDiagnostics: 0,
|
|
2458
2452
|
truncated: false
|
|
2459
2453
|
});
|
|
2460
|
-
if (missingDependency) return missingDependency;
|
|
2461
|
-
throw error;
|
|
2462
2454
|
}
|
|
2463
2455
|
}
|
|
2464
2456
|
//#endregion
|
|
@@ -2484,9 +2476,7 @@ async function executeLspInstallDecision(params) {
|
|
|
2484
2476
|
//#endregion
|
|
2485
2477
|
//#region packages/lsp-core/src/tools/navigation.ts
|
|
2486
2478
|
async function executeLspGotoDefinition(params, signal) {
|
|
2487
|
-
const filePath =
|
|
2488
|
-
const line = requireNumber(params, "line");
|
|
2489
|
-
const character = requireNumber(params, "character");
|
|
2479
|
+
const { filePath, line, character } = sourcePosition(params);
|
|
2490
2480
|
try {
|
|
2491
2481
|
const result = await withLspClient(filePath, async (client) => client.definition(filePath, line, character), "definition", clientOptions(signal));
|
|
2492
2482
|
const locations = !result ? [] : Array.isArray(result) ? result : [result];
|
|
@@ -2499,20 +2489,16 @@ async function executeLspGotoDefinition(params, signal) {
|
|
|
2499
2489
|
if (locations.length === 0) return text("No definition found", details);
|
|
2500
2490
|
return text(locations.map(formatLocation).join("\n"), details);
|
|
2501
2491
|
} catch (error) {
|
|
2502
|
-
|
|
2492
|
+
return missingDependencyResultOrThrow(error, {
|
|
2503
2493
|
filePath,
|
|
2504
2494
|
line,
|
|
2505
2495
|
character,
|
|
2506
2496
|
locations: []
|
|
2507
2497
|
});
|
|
2508
|
-
if (missingDependency) return missingDependency;
|
|
2509
|
-
throw error;
|
|
2510
2498
|
}
|
|
2511
2499
|
}
|
|
2512
2500
|
async function executeLspFindReferences(params, signal) {
|
|
2513
|
-
const filePath =
|
|
2514
|
-
const line = requireNumber(params, "line");
|
|
2515
|
-
const character = requireNumber(params, "character");
|
|
2501
|
+
const { filePath, line, character } = sourcePosition(params);
|
|
2516
2502
|
const includeDeclaration = optionalBoolean(params, "includeDeclaration") ?? true;
|
|
2517
2503
|
try {
|
|
2518
2504
|
const result = await withLspClient(filePath, async (client) => client.references(filePath, line, character, includeDeclaration), "references", clientOptions(signal));
|
|
@@ -2531,7 +2517,7 @@ async function executeLspFindReferences(params, signal) {
|
|
|
2531
2517
|
if (total === 0) return text("No references found", details);
|
|
2532
2518
|
return text([...truncated ? [`Found ${total} references (showing first 200):`] : [], ...limited.map(formatLocation)].join("\n"), details);
|
|
2533
2519
|
} catch (error) {
|
|
2534
|
-
|
|
2520
|
+
return missingDependencyResultOrThrow(error, {
|
|
2535
2521
|
filePath,
|
|
2536
2522
|
line,
|
|
2537
2523
|
character,
|
|
@@ -2539,15 +2525,10 @@ async function executeLspFindReferences(params, signal) {
|
|
|
2539
2525
|
totalReferences: 0,
|
|
2540
2526
|
truncated: false
|
|
2541
2527
|
});
|
|
2542
|
-
if (missingDependency) return missingDependency;
|
|
2543
|
-
throw error;
|
|
2544
2528
|
}
|
|
2545
2529
|
}
|
|
2546
2530
|
//#endregion
|
|
2547
2531
|
//#region packages/lsp-core/src/lsp/workspace-edit.ts
|
|
2548
|
-
function errorMessage(error) {
|
|
2549
|
-
return error instanceof Error ? error.message : String(error);
|
|
2550
|
-
}
|
|
2551
2532
|
function isPathInsideWorkspace(filePath, workspaceRoot) {
|
|
2552
2533
|
const relativePath = relative(workspaceRoot, filePath);
|
|
2553
2534
|
return relativePath === "" || !relativePath.startsWith("..") && !isAbsolute(relativePath);
|
|
@@ -2564,7 +2545,7 @@ function uriToWorkspacePath(uri, workspaceRoot) {
|
|
|
2564
2545
|
} catch (error) {
|
|
2565
2546
|
return {
|
|
2566
2547
|
success: false,
|
|
2567
|
-
error: `non-file URI ${uri}: ${
|
|
2548
|
+
error: `non-file URI ${uri}: ${messageFromError(error)}`
|
|
2568
2549
|
};
|
|
2569
2550
|
}
|
|
2570
2551
|
let validatedPath;
|
|
@@ -2573,7 +2554,7 @@ function uriToWorkspacePath(uri, workspaceRoot) {
|
|
|
2573
2554
|
} catch (error) {
|
|
2574
2555
|
return {
|
|
2575
2556
|
success: false,
|
|
2576
|
-
error: `${filePath}: ${
|
|
2557
|
+
error: `${filePath}: ${messageFromError(error)}`
|
|
2577
2558
|
};
|
|
2578
2559
|
}
|
|
2579
2560
|
if (!isPathInsideWorkspace(validatedPath, workspaceRoot)) return {
|
|
@@ -2717,9 +2698,7 @@ function applyWorkspaceEdit(edit, options = {}) {
|
|
|
2717
2698
|
//#endregion
|
|
2718
2699
|
//#region packages/lsp-core/src/tools/rename.ts
|
|
2719
2700
|
async function executeLspPrepareRename(params, signal) {
|
|
2720
|
-
const filePath =
|
|
2721
|
-
const line = requireNumber(params, "line");
|
|
2722
|
-
const character = requireNumber(params, "character");
|
|
2701
|
+
const { filePath, line, character } = sourcePosition(params);
|
|
2723
2702
|
try {
|
|
2724
2703
|
const result = await withLspClient(filePath, async (client) => client.prepareRename(filePath, line, character), "prepareRename", clientOptions(signal));
|
|
2725
2704
|
const details = {
|
|
@@ -2730,20 +2709,16 @@ async function executeLspPrepareRename(params, signal) {
|
|
|
2730
2709
|
};
|
|
2731
2710
|
return text(formatPrepareRenameResult(result), details);
|
|
2732
2711
|
} catch (error) {
|
|
2733
|
-
|
|
2712
|
+
return missingDependencyResultOrThrow(error, {
|
|
2734
2713
|
filePath,
|
|
2735
2714
|
line,
|
|
2736
2715
|
character,
|
|
2737
2716
|
result: null
|
|
2738
2717
|
});
|
|
2739
|
-
if (missingDependency) return missingDependency;
|
|
2740
|
-
throw error;
|
|
2741
2718
|
}
|
|
2742
2719
|
}
|
|
2743
2720
|
async function executeLspRename(params, signal) {
|
|
2744
|
-
const filePath =
|
|
2745
|
-
const line = requireNumber(params, "line");
|
|
2746
|
-
const character = requireNumber(params, "character");
|
|
2721
|
+
const { filePath, line, character } = sourcePosition(params);
|
|
2747
2722
|
const newName = requireString(params, "newName");
|
|
2748
2723
|
try {
|
|
2749
2724
|
const edit = await withLspClient(filePath, async (client, workspaceRoot) => ({
|
|
@@ -2761,7 +2736,7 @@ async function executeLspRename(params, signal) {
|
|
|
2761
2736
|
};
|
|
2762
2737
|
return text(formatApplyResult(apply), details, !apply.success);
|
|
2763
2738
|
} catch (error) {
|
|
2764
|
-
|
|
2739
|
+
return missingDependencyResultOrThrow(error, {
|
|
2765
2740
|
filePath,
|
|
2766
2741
|
line,
|
|
2767
2742
|
character,
|
|
@@ -2769,8 +2744,6 @@ async function executeLspRename(params, signal) {
|
|
|
2769
2744
|
apply: null,
|
|
2770
2745
|
edit: null
|
|
2771
2746
|
});
|
|
2772
|
-
if (missingDependency) return missingDependency;
|
|
2773
|
-
throw error;
|
|
2774
2747
|
}
|
|
2775
2748
|
}
|
|
2776
2749
|
//#endregion
|
|
@@ -2838,7 +2811,7 @@ async function executeLspSymbols(params, signal) {
|
|
|
2838
2811
|
return formatSymbolsResult(filePath, scope, await withLspClient(filePath, async (client) => client.documentSymbols(filePath), "documentSymbols", clientOptions(signal)), limit);
|
|
2839
2812
|
} catch (error) {
|
|
2840
2813
|
const query = optionalString(params, "query");
|
|
2841
|
-
|
|
2814
|
+
return missingDependencyResultOrThrow(error, {
|
|
2842
2815
|
filePath,
|
|
2843
2816
|
scope,
|
|
2844
2817
|
symbols: [],
|
|
@@ -2846,8 +2819,6 @@ async function executeLspSymbols(params, signal) {
|
|
|
2846
2819
|
truncated: false,
|
|
2847
2820
|
...query === void 0 ? {} : { query }
|
|
2848
2821
|
});
|
|
2849
|
-
if (missingDependency) return missingDependency;
|
|
2850
|
-
throw error;
|
|
2851
2822
|
}
|
|
2852
2823
|
}
|
|
2853
2824
|
function formatSymbolsResult(filePath, scope, symbols, limit, query) {
|
|
@@ -2872,6 +2843,21 @@ function formatSymbolsResult(filePath, scope, symbols, limit, query) {
|
|
|
2872
2843
|
}
|
|
2873
2844
|
//#endregion
|
|
2874
2845
|
//#region packages/lsp-core/src/tools/definitions.ts
|
|
2846
|
+
var POSITION_PROPERTIES = {
|
|
2847
|
+
line: {
|
|
2848
|
+
type: "number",
|
|
2849
|
+
description: "1-based line number."
|
|
2850
|
+
},
|
|
2851
|
+
character: {
|
|
2852
|
+
type: "number",
|
|
2853
|
+
description: "0-based column."
|
|
2854
|
+
}
|
|
2855
|
+
};
|
|
2856
|
+
var POSITION_REQUIRED = [
|
|
2857
|
+
"filePath",
|
|
2858
|
+
"line",
|
|
2859
|
+
"character"
|
|
2860
|
+
];
|
|
2875
2861
|
var LSP_MCP_TOOLS = [
|
|
2876
2862
|
{
|
|
2877
2863
|
name: "status",
|
|
@@ -2915,19 +2901,8 @@ var LSP_MCP_TOOLS = [
|
|
|
2915
2901
|
type: "string",
|
|
2916
2902
|
description: "Source file containing the symbol."
|
|
2917
2903
|
},
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
description: "1-based line number."
|
|
2921
|
-
},
|
|
2922
|
-
character: {
|
|
2923
|
-
type: "number",
|
|
2924
|
-
description: "0-based column."
|
|
2925
|
-
}
|
|
2926
|
-
}, [
|
|
2927
|
-
"filePath",
|
|
2928
|
-
"line",
|
|
2929
|
-
"character"
|
|
2930
|
-
]),
|
|
2904
|
+
...POSITION_PROPERTIES
|
|
2905
|
+
}, POSITION_REQUIRED),
|
|
2931
2906
|
execute: executeLspGotoDefinition
|
|
2932
2907
|
},
|
|
2933
2908
|
{
|
|
@@ -2940,23 +2915,12 @@ var LSP_MCP_TOOLS = [
|
|
|
2940
2915
|
type: "string",
|
|
2941
2916
|
description: "Source file containing the symbol."
|
|
2942
2917
|
},
|
|
2943
|
-
|
|
2944
|
-
type: "number",
|
|
2945
|
-
description: "1-based line number."
|
|
2946
|
-
},
|
|
2947
|
-
character: {
|
|
2948
|
-
type: "number",
|
|
2949
|
-
description: "0-based column."
|
|
2950
|
-
},
|
|
2918
|
+
...POSITION_PROPERTIES,
|
|
2951
2919
|
includeDeclaration: {
|
|
2952
2920
|
type: "boolean",
|
|
2953
2921
|
description: "Include the declaration. Defaults to true."
|
|
2954
2922
|
}
|
|
2955
|
-
},
|
|
2956
|
-
"filePath",
|
|
2957
|
-
"line",
|
|
2958
|
-
"character"
|
|
2959
|
-
]),
|
|
2923
|
+
}, POSITION_REQUIRED),
|
|
2960
2924
|
execute: executeLspFindReferences
|
|
2961
2925
|
},
|
|
2962
2926
|
{
|
|
@@ -2995,19 +2959,8 @@ var LSP_MCP_TOOLS = [
|
|
|
2995
2959
|
type: "string",
|
|
2996
2960
|
description: "Source file path."
|
|
2997
2961
|
},
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
description: "1-based line number."
|
|
3001
|
-
},
|
|
3002
|
-
character: {
|
|
3003
|
-
type: "number",
|
|
3004
|
-
description: "0-based column."
|
|
3005
|
-
}
|
|
3006
|
-
}, [
|
|
3007
|
-
"filePath",
|
|
3008
|
-
"line",
|
|
3009
|
-
"character"
|
|
3010
|
-
]),
|
|
2962
|
+
...POSITION_PROPERTIES
|
|
2963
|
+
}, POSITION_REQUIRED),
|
|
3011
2964
|
execute: executeLspPrepareRename
|
|
3012
2965
|
},
|
|
3013
2966
|
{
|
|
@@ -3020,14 +2973,7 @@ var LSP_MCP_TOOLS = [
|
|
|
3020
2973
|
type: "string",
|
|
3021
2974
|
description: "Source file path."
|
|
3022
2975
|
},
|
|
3023
|
-
|
|
3024
|
-
type: "number",
|
|
3025
|
-
description: "1-based line number."
|
|
3026
|
-
},
|
|
3027
|
-
character: {
|
|
3028
|
-
type: "number",
|
|
3029
|
-
description: "0-based column."
|
|
3030
|
-
},
|
|
2976
|
+
...POSITION_PROPERTIES,
|
|
3031
2977
|
newName: {
|
|
3032
2978
|
type: "string",
|
|
3033
2979
|
description: "New symbol name."
|
|
@@ -3072,7 +3018,7 @@ function coerceToolArguments(value) {
|
|
|
3072
3018
|
//#endregion
|
|
3073
3019
|
//#region packages/lsp-core/src/mcp.ts
|
|
3074
3020
|
var SERVER_NAME = "lsp";
|
|
3075
|
-
var SERVER_VERSION = "0.5.
|
|
3021
|
+
var SERVER_VERSION = "0.5.3";
|
|
3076
3022
|
async function handleLspMcpRequest(input) {
|
|
3077
3023
|
if (!isPlainRecord(input)) return errorResponse(null, -32600, "Invalid Request");
|
|
3078
3024
|
const id = jsonRpcId(input["id"]);
|
|
@@ -3439,7 +3385,7 @@ function daemonUnreachableResult(paths, error) {
|
|
|
3439
3385
|
content: [{
|
|
3440
3386
|
type: "text",
|
|
3441
3387
|
text: [
|
|
3442
|
-
`LSP daemon unreachable: ${
|
|
3388
|
+
`LSP daemon unreachable: ${messageFromError(error)}.`,
|
|
3443
3389
|
"The MCP server is a thin proxy and never runs language servers in-process.",
|
|
3444
3390
|
`Socket: ${paths.socket}`,
|
|
3445
3391
|
`Logs: ${paths.log}`,
|
|
@@ -3509,7 +3455,7 @@ async function runMcpStdioProxy(options = {}) {
|
|
|
3509
3455
|
...options.ensure ? { ensure: options.ensure } : {}
|
|
3510
3456
|
},
|
|
3511
3457
|
onHandlerError: (error) => {
|
|
3512
|
-
process.stderr.write(`[lsp-daemon] proxy error: ${
|
|
3458
|
+
process.stderr.write(`[lsp-daemon] proxy error: ${messageFromError(error)}\n`);
|
|
3513
3459
|
}
|
|
3514
3460
|
});
|
|
3515
3461
|
}
|
|
@@ -3659,7 +3605,7 @@ async function main() {
|
|
|
3659
3605
|
process.exitCode = 2;
|
|
3660
3606
|
}
|
|
3661
3607
|
main().catch((error) => {
|
|
3662
|
-
stderr.write(`${
|
|
3608
|
+
stderr.write(`${stackOrMessageFromError(error)}\n`);
|
|
3663
3609
|
process.exitCode = 1;
|
|
3664
3610
|
});
|
|
3665
3611
|
//#endregion
|
|
@@ -31,6 +31,9 @@ function jsonRpcId(value) {
|
|
|
31
31
|
function messageFromError(error) {
|
|
32
32
|
return error instanceof Error ? error.message : String(error);
|
|
33
33
|
}
|
|
34
|
+
function stackOrMessageFromError(error) {
|
|
35
|
+
return error instanceof Error ? error.stack ?? error.message : String(error);
|
|
36
|
+
}
|
|
34
37
|
//#endregion
|
|
35
38
|
//#region packages/mcp-stdio-core/src/transport.ts
|
|
36
39
|
var HEADER_SEPARATOR = Buffer.from("\r\n\r\n");
|
|
@@ -118,7 +121,7 @@ function parseJsonPayload(payload, responseMode) {
|
|
|
118
121
|
} catch (error) {
|
|
119
122
|
return {
|
|
120
123
|
kind: "parse_error",
|
|
121
|
-
message:
|
|
124
|
+
message: messageFromError(error),
|
|
122
125
|
responseMode
|
|
123
126
|
};
|
|
124
127
|
}
|
|
@@ -206,4 +209,4 @@ function createIdleTimer(idleTimeoutMs, log, onIdleTimeout) {
|
|
|
206
209
|
};
|
|
207
210
|
}
|
|
208
211
|
//#endregion
|
|
209
|
-
export {
|
|
212
|
+
export { stackOrMessageFromError as a, messageFromError as i, errorResponse as n, successResponse as o, jsonRpcId as r, isPlainRecord as s, runJsonRpcStdioServer as t };
|
|
@@ -13,15 +13,15 @@ Create one bounded, verifiable objective; no plan, log, snapshot, ledger, handof
|
|
|
13
13
|
|
|
14
14
|
## Flow
|
|
15
15
|
|
|
16
|
-
1. State concrete
|
|
16
|
+
1. State concrete outcome, target, completion criteria, proof, scope, exclusions, input blocker, and stop condition.
|
|
17
17
|
2. Add useful checks, paths, environments, counts, or limits; no fake precision or quality ratchet.
|
|
18
|
-
3. Replace activity goals
|
|
18
|
+
3. Replace activity goals such as “improve” with observable state. Bound subjective quality by approved task and named validator.
|
|
19
19
|
4. Ask one short question only if missing scope or proof would materially change intent.
|
|
20
20
|
5. Call `get_goal`.
|
|
21
21
|
- No goal: quality-check, then `create_goal`.
|
|
22
22
|
- Same active goal: reuse.
|
|
23
23
|
- Conflicting goal: ask whether to finish it or use another task.
|
|
24
|
-
6. Call `create_goal` with one concise objective. Set token budget only when
|
|
24
|
+
6. Call `create_goal` with one concise objective. Set token budget only when explicitly requested. Stop when criteria pass; do not extend for polish, speculation, repeated review, adjacent work, or new opportunities.
|
|
25
25
|
|
|
26
26
|
## Quality gate
|
|
27
27
|
|
|
@@ -5,46 +5,46 @@ description: Use when a task needs frontend, web UI, UX, visual design, interact
|
|
|
5
5
|
|
|
6
6
|
# Frontend
|
|
7
7
|
|
|
8
|
-
Preserve stack, behavior, tokens, patterns,
|
|
8
|
+
Preserve stack, behavior, tokens, patterns, visual contract, and identity. Keep scope small; avoid generic AI styling. Do not force `DESIGN.md`, research, dependencies, GSAP, or heavy QA.
|
|
9
9
|
|
|
10
10
|
## Approval sequence
|
|
11
11
|
|
|
12
12
|
1. Load `frontend`; inspect the request, product shell, target surface, design tokens, nearest pattern, responsive contract, supplied references, and relevant states.
|
|
13
|
-
2. Select only material
|
|
13
|
+
2. Select only material decisions: direction, type, layout/density, color/surfaces, assets, responsiveness, applicable states, plus a motion system and accessibility treatment for every task. Give motion a proportional hierarchy, state, interaction, continuity, or navigation purpose. Define `prefers-reduced-motion`, keyboard operation, focus visibility, semantics, contrast, and labels. Preserve established decisions unless change is requested.
|
|
14
14
|
3. Present the compact decision set with existing constraints and ask for approval before implementation. For a fix, audit, accessibility, or performance task, include only decisions that alter user-visible design; diagnosis and technical implementation details need no approval.
|
|
15
15
|
4. After approval, ask whether the user wants to define a goal. Only after explicit agreement load `define-goal`; otherwise implement.
|
|
16
16
|
|
|
17
|
-
Approval owns visible direction and material interaction
|
|
17
|
+
Approval owns visible direction and material interaction. Component APIs, code structure, exact CSS, breakpoint mechanics, route-required libraries, and other reversible implementation details remain implementation decisions.
|
|
18
18
|
|
|
19
19
|
## Route
|
|
20
20
|
|
|
21
|
-
- Build/redesign: inspect shell, tokens,
|
|
22
|
-
- Visual reference: use
|
|
21
|
+
- Build/redesign: inspect shell, tokens, component, responsive contract.
|
|
22
|
+
- Visual reference: use first; measure layout, type, color, spacing, surface, motion.
|
|
23
23
|
- Performance: load `references/perfection/README.md` only for real audit or regression.
|
|
24
24
|
- Palette/type/style: load only relevant `references/ui-ux-db` data.
|
|
25
25
|
- Motion-rich premium React/Tailwind page creation or redesign: mandatory GPT Taste route below. Ordinary fixes, debugging, accessibility, and performance work stay on normal route.
|
|
26
26
|
|
|
27
27
|
## GPT Taste route
|
|
28
28
|
|
|
29
|
-
- During approval, emit `<design_plan>` with prompt-derived
|
|
29
|
+
- During approval, emit `<design_plan>` with prompt-derived direction, type, layout, motion, responsive, accessibility, and state choices. Established contracts win.
|
|
30
30
|
- Treat AIDA, bento layouts, font shortlists, GSAP, Picsum, component counts, and named motion patterns as options only when they fit product, task, and stack.
|
|
31
|
-
-
|
|
31
|
+
- State each chosen pattern's user-facing purpose and containment. Add no dependency or remote asset unless approved and required.
|
|
32
32
|
- Motion is required but may be subtle. Avoid gratuitous, blocking, performance-heavy, or reduced-motion-unsafe effects.
|
|
33
33
|
- Prevent horizontal overflow, clipped content, dead layouts, empty cards, fake dashboards, copied text, and inaccessible interaction.
|
|
34
34
|
|
|
35
35
|
Ban emojis; cheap/generic meta-labels (`SECTION 01`, `QUESTION 05`, `ABOUT US`); invisible button text; empty bento cells/cards; narrow multi-line/centered heroes; repeated left/right or flat sections/backgrounds; stock-feeling imagery; fake dashboards; meaningless gradients; copied reference text.
|
|
36
36
|
|
|
37
|
-
Required `<design_plan>`: visible direction; layout
|
|
37
|
+
Required `<design_plan>`: visible direction; layout/responsive contract; asset role; motion purpose/reduced-motion fallback; accessibility treatment; applicable loading, error, and empty states. Include only chosen patterns, never a fixed architecture count.
|
|
38
38
|
|
|
39
39
|
Only after approval and optional goal choice may implementation begin.
|
|
40
40
|
|
|
41
41
|
## Implementation
|
|
42
42
|
|
|
43
|
-
1. Inspect target and nearest
|
|
44
|
-
2. Lock
|
|
45
|
-
3. Implement smallest coherent slice with purposeful motion, reduced
|
|
46
|
-
4. Test narrow/mobile/wide containment
|
|
43
|
+
1. Inspect target and nearest pattern.
|
|
44
|
+
2. Lock type, spacing, surfaces, color, asset role, and motion role.
|
|
45
|
+
3. Implement smallest coherent slice with purposeful motion, reduced motion, keyboard operation, visible focus, semantics, contrast, and labels.
|
|
46
|
+
4. Test narrow/mobile/wide containment: no horizontal leak, clipped text, overlap, or unreadable measure.
|
|
47
47
|
5. Check loading, error, and empty states when applicable.
|
|
48
|
-
6. Check interaction
|
|
48
|
+
6. Check proportional interaction/performance. Avoid layout shift, oversized media, needless client work.
|
|
49
49
|
|
|
50
50
|
Use real assets when supplied. Never invent research or claim screenshot parity without visual comparison.
|
|
@@ -5,28 +5,37 @@ description: Use when a task edits Python, Rust, TypeScript, Go, or their matchi
|
|
|
5
5
|
|
|
6
6
|
# Programming
|
|
7
7
|
|
|
8
|
-
Before editing `.py`, `.pyi`, `.rs`, `.ts`, `.tsx`, `.mts`, `.cts`, `.go`, or matching manifests, read `references/<language>/README.md`. Load `references/logging.md` only for logs
|
|
8
|
+
Before editing `.py`, `.pyi`, `.rs`, `.ts`, `.tsx`, `.mts`, `.cts`, `.go`, or matching manifests, read `references/<language>/README.md`. Load `references/logging.md` only for logs; load all `references/rust-ub/` for Rust unsafe/FFI.
|
|
9
9
|
|
|
10
10
|
## Core
|
|
11
11
|
|
|
12
|
-
-
|
|
12
|
+
- Prefer, in order: no code, existing helper, standard API, native feature, installed dependency, one line, new code.
|
|
13
13
|
- Trace real flow and callers. Fix shared root seam once.
|
|
14
14
|
- Parse untrusted input once at boundary. Interior stays typed.
|
|
15
|
-
- Make illegal states unrepresentable
|
|
16
|
-
-
|
|
15
|
+
- Make illegal states unrepresentable; give distinct primitives distinct types.
|
|
16
|
+
- Default immutable; mutate parameters only with explicit purpose.
|
|
17
17
|
- Exhaustive variant handling.
|
|
18
18
|
- No untyped escape, ignored diagnostics, non-null assertion, unchecked cast, panic/unwrap in library path.
|
|
19
19
|
- Typed errors. Catch only expected errors; unknown errors propagate to boundary.
|
|
20
20
|
- Existing project stack and logger win.
|
|
21
|
-
- No
|
|
21
|
+
- No one-caller helper or speculative abstraction.
|
|
22
|
+
|
|
23
|
+
## Reuse
|
|
24
|
+
|
|
25
|
+
- One behavior, one implementation.
|
|
26
|
+
- Search before writing; reuse or extend the existing implementation.
|
|
27
|
+
- Never copy-paste logic or maintain parallel variants.
|
|
28
|
+
- Put shared behavior in the smallest stable function, method, type, or module at its common ownership seam. Callers pass data, not reimplement policy.
|
|
29
|
+
- Extract repetition when a second caller or copy exists. Keep one-caller mechanics local unless they form a stable domain abstraction.
|
|
30
|
+
- Reusable code needs cohesive names, explicit typed I/O, and public-seam tests. Parameterize real variation; reject caller branches and boolean modes.
|
|
22
31
|
|
|
23
32
|
## Test
|
|
24
33
|
|
|
25
|
-
Defect: add a public-seam regression test first and confirm the intended failure. Explicit test-first request or clearly defined new behavior without adequate proof: test public seam
|
|
34
|
+
Defect: add a public-seam regression test first and confirm the intended failure. Explicit test-first request or clearly defined new behavior without adequate proof: test public seam, confirm failure, implement minimum green, refactor. Existing tests may lock small covered changes. Do not force red-green for prose, configuration-only work, trivial mechanical edits, or behavior already adequately covered. Prefer real object or fake to mock; use deterministic fixtures, never sleep. Add a proportional end-to-end user outcome for new behavior. Run smallest test in loop.
|
|
26
35
|
|
|
27
36
|
## Size
|
|
28
37
|
|
|
29
|
-
After
|
|
38
|
+
After writing, measure pure LOC: under 200 healthy; 200–250 warn; over 250 split unless generated table or documented indivisible state machine. Over three independent parameters requires named domain input or a specific reason.
|
|
30
39
|
|
|
31
40
|
## Finish
|
|
32
41
|
|
|
@@ -5,17 +5,17 @@ description: Use when an authorized task needs repository security review, threa
|
|
|
5
5
|
|
|
6
6
|
# Security Research
|
|
7
7
|
|
|
8
|
-
Main agent owns scope, threat surface, dedupe, proof, severity, report. No Team Mode.
|
|
8
|
+
Main agent owns scope, threat surface, dedupe, proof, severity, report. No Team Mode. When useful, at most two independent lanes: `explorer` for one internal surface; `librarian` for named standards/dependency facts. No duplicate hunters, recursive delegation, reviewer loop, or full-history fork.
|
|
9
9
|
|
|
10
10
|
## Rules
|
|
11
11
|
|
|
12
12
|
- Name target: repo, diff, path, release, or threat surface.
|
|
13
|
-
- Map entry points, attacker input, trust boundaries,
|
|
13
|
+
- Map entry points, attacker input, trust boundaries, assets, sinks, privilege transitions.
|
|
14
14
|
- No severity without reachable attack path.
|
|
15
|
-
- High
|
|
15
|
+
- High/critical needs safe local PoC or decisive static proof with concrete preconditions and impact.
|
|
16
16
|
- CWE classifies weakness. Severity measures exploitability and impact. Keep separate.
|
|
17
17
|
- Generic hardening is not finding.
|
|
18
|
-
- Never attack real
|
|
18
|
+
- Never attack real/third-party systems; use local fixture, toy payload, dry run, or static proof.
|
|
19
19
|
|
|
20
20
|
## Flow
|
|
21
21
|
|
|
@@ -23,16 +23,16 @@ Main agent owns scope, threat surface, dedupe, proof, severity, report. No Team
|
|
|
23
23
|
2. Threat surface: attacker capability, controlled input, boundary, sink, asset.
|
|
24
24
|
3. Candidates: title, path/function, attack path, impact, CWE candidate, evidence, safe proof idea.
|
|
25
25
|
4. Deduplicate by root cause and attack path.
|
|
26
|
-
5. Validate strongest candidate
|
|
27
|
-
6. Calibrate severity from proven preconditions, reachability, privilege, user action, scope, confidentiality, integrity, availability.
|
|
26
|
+
5. Validate strongest candidate: reproduce, falsify, or downgrade. Record exact command/output.
|
|
27
|
+
6. Calibrate severity from proven preconditions, reachability, privilege, user action, scope, confidentiality, integrity, and availability.
|
|
28
28
|
7. Give minimum fix and public-seam regression test.
|
|
29
29
|
|
|
30
30
|
## Report
|
|
31
31
|
|
|
32
32
|
Lead with `PASS`, `PASS WITH FINDINGS`, or `BLOCK`.
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
Each finding: severity, title, CWE, affected path/function, attacker capability, attack path, proof, impact, minimum fix, regression check.
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
List downgraded/rejected candidates with reasons. End with residual risk: untested surfaces and why.
|
|
37
37
|
|
|
38
38
|
Use CWE, OWASP WSTG/ASVS, and CVSS v4 only when relevant. Cite exact source. Do not claim precise CVSS score without scoring every metric.
|