@ksm0709/context 0.0.26 → 0.0.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/cli/index.js +89 -13
- package/dist/index.js +2 -2
- package/dist/mcp.js +18 -0
- package/dist/omx/index.mjs +93 -10
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@ This plugin automatically registers an MCP (Model Context Protocol) server named
|
|
|
14
14
|
|
|
15
15
|
## OMX Support
|
|
16
16
|
|
|
17
|
-
This plugin supports OMX (OpenCode Managed eXtension). See [
|
|
17
|
+
This plugin supports OMX (OpenCode Managed eXtension). See [docs/omx-setup.md](docs/omx-setup.md) for setup instructions.
|
|
18
18
|
|
|
19
19
|
## Installation
|
|
20
20
|
|
package/dist/cli/index.js
CHANGED
|
@@ -27,7 +27,7 @@ function resolveContextDir(projectDir) {
|
|
|
27
27
|
// package.json
|
|
28
28
|
var package_default = {
|
|
29
29
|
name: "@ksm0709/context",
|
|
30
|
-
version: "0.0.
|
|
30
|
+
version: "0.0.28",
|
|
31
31
|
author: {
|
|
32
32
|
name: "TaehoKang",
|
|
33
33
|
email: "ksm07091@gmail.com"
|
|
@@ -69,7 +69,7 @@ var package_default = {
|
|
|
69
69
|
"@opencode-ai/plugin": ">=1.0.0"
|
|
70
70
|
},
|
|
71
71
|
dependencies: {
|
|
72
|
-
"@ksm0709/context": "^0.0.
|
|
72
|
+
"@ksm0709/context": "^0.0.27",
|
|
73
73
|
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
74
74
|
"jsonc-parser": "^3.0.0"
|
|
75
75
|
},
|
|
@@ -577,16 +577,88 @@ function updateConfigPaths(contextDir) {
|
|
|
577
577
|
}
|
|
578
578
|
|
|
579
579
|
// src/cli/commands/install.ts
|
|
580
|
-
import { join as
|
|
581
|
-
import { existsSync as
|
|
582
|
-
import { fileURLToPath } from "url";
|
|
580
|
+
import { join as join6, resolve as resolve4, dirname as dirname2 } from "path";
|
|
581
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync3, copyFileSync } from "fs";
|
|
582
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
583
583
|
import { createRequire } from "module";
|
|
584
|
+
|
|
585
|
+
// src/omx/registry.ts
|
|
586
|
+
import { fileURLToPath } from "url";
|
|
587
|
+
import { dirname, join as join5, resolve as resolve3 } from "path";
|
|
588
|
+
import { existsSync as existsSync5, readFileSync as readFileSync3, writeFileSync as writeFileSync3, mkdirSync as mkdirSync2 } from "fs";
|
|
589
|
+
import { homedir as homedir2 } from "os";
|
|
590
|
+
function resolveMcpPath() {
|
|
591
|
+
const currentFile = fileURLToPath(import.meta.url);
|
|
592
|
+
const currentDir = dirname(currentFile);
|
|
593
|
+
const distMcpPath = resolve3(currentDir, "..", "mcp.js");
|
|
594
|
+
if (existsSync5(distMcpPath)) {
|
|
595
|
+
return distMcpPath;
|
|
596
|
+
}
|
|
597
|
+
const srcMcpPath = resolve3(currentDir, "..", "mcp.ts");
|
|
598
|
+
if (existsSync5(srcMcpPath)) {
|
|
599
|
+
return srcMcpPath;
|
|
600
|
+
}
|
|
601
|
+
return distMcpPath;
|
|
602
|
+
}
|
|
603
|
+
function getRegistryPaths() {
|
|
604
|
+
return [
|
|
605
|
+
join5(homedir2(), ".omx", "mcp-registry.json"),
|
|
606
|
+
join5(homedir2(), ".omc", "mcp-registry.json")
|
|
607
|
+
];
|
|
608
|
+
}
|
|
609
|
+
function ensureMcpRegistered(sdkLog) {
|
|
610
|
+
const registryPaths = getRegistryPaths();
|
|
611
|
+
let targetPath = registryPaths[0];
|
|
612
|
+
for (const p of registryPaths) {
|
|
613
|
+
if (existsSync5(p)) {
|
|
614
|
+
targetPath = p;
|
|
615
|
+
break;
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
let registry = {};
|
|
619
|
+
if (existsSync5(targetPath)) {
|
|
620
|
+
try {
|
|
621
|
+
const content = readFileSync3(targetPath, "utf-8");
|
|
622
|
+
registry = JSON.parse(content);
|
|
623
|
+
} catch (e) {
|
|
624
|
+
if (sdkLog) {
|
|
625
|
+
sdkLog(`[ERROR] Failed to parse MCP registry at ${targetPath}: ${e instanceof Error ? e.message : String(e)}`);
|
|
626
|
+
}
|
|
627
|
+
registry = {};
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
const mcpPath = resolveMcpPath();
|
|
631
|
+
const expectedConfig = {
|
|
632
|
+
command: "bun",
|
|
633
|
+
args: [mcpPath]
|
|
634
|
+
};
|
|
635
|
+
const currentConfig = registry["context-mcp"];
|
|
636
|
+
if (!currentConfig || currentConfig.command !== expectedConfig.command || !Array.isArray(currentConfig.args) || currentConfig.args[0] !== expectedConfig.args[0]) {
|
|
637
|
+
registry["context-mcp"] = expectedConfig;
|
|
638
|
+
try {
|
|
639
|
+
mkdirSync2(dirname(targetPath), { recursive: true });
|
|
640
|
+
writeFileSync3(targetPath, JSON.stringify(registry, null, 2), "utf-8");
|
|
641
|
+
if (sdkLog) {
|
|
642
|
+
sdkLog(`[INFO] Registered context-mcp in ${targetPath}`);
|
|
643
|
+
}
|
|
644
|
+
return true;
|
|
645
|
+
} catch (e) {
|
|
646
|
+
if (sdkLog) {
|
|
647
|
+
sdkLog(`[ERROR] Failed to write MCP registry to ${targetPath}: ${e instanceof Error ? e.message : String(e)}`);
|
|
648
|
+
}
|
|
649
|
+
return false;
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
return false;
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
// src/cli/commands/install.ts
|
|
584
656
|
function resolveOmxSource() {
|
|
585
657
|
try {
|
|
586
|
-
const cliDir =
|
|
587
|
-
const pkgRoot =
|
|
588
|
-
const source =
|
|
589
|
-
if (
|
|
658
|
+
const cliDir = dirname2(fileURLToPath2(import.meta.url));
|
|
659
|
+
const pkgRoot = resolve4(cliDir, "..", "..");
|
|
660
|
+
const source = join6(pkgRoot, "dist", "omx", "index.mjs");
|
|
661
|
+
if (existsSync6(source))
|
|
590
662
|
return source;
|
|
591
663
|
} catch {}
|
|
592
664
|
try {
|
|
@@ -597,17 +669,21 @@ function resolveOmxSource() {
|
|
|
597
669
|
}
|
|
598
670
|
}
|
|
599
671
|
function installOmx(projectDir, sourcePath) {
|
|
600
|
-
if (!
|
|
672
|
+
if (!existsSync6(sourcePath)) {
|
|
601
673
|
process.stderr.write(`Could not find OMX plugin source file: ${sourcePath}
|
|
602
674
|
`);
|
|
603
675
|
process.exit(1);
|
|
604
676
|
return;
|
|
605
677
|
}
|
|
606
|
-
const targetDir =
|
|
607
|
-
|
|
608
|
-
copyFileSync(sourcePath,
|
|
678
|
+
const targetDir = join6(projectDir, ".omx", "hooks");
|
|
679
|
+
mkdirSync3(targetDir, { recursive: true });
|
|
680
|
+
copyFileSync(sourcePath, join6(targetDir, "context.mjs"));
|
|
609
681
|
process.stdout.write(`Installed context plugin to .omx/hooks/context.mjs
|
|
610
682
|
`);
|
|
683
|
+
if (ensureMcpRegistered()) {
|
|
684
|
+
process.stdout.write(`Successfully registered context-mcp in ~/.omx/mcp-registry.json
|
|
685
|
+
`);
|
|
686
|
+
}
|
|
611
687
|
}
|
|
612
688
|
function runInstall(args) {
|
|
613
689
|
const [subcommand] = args;
|
package/dist/index.js
CHANGED
|
@@ -25,7 +25,7 @@ import { join as join2 } from "path";
|
|
|
25
25
|
// package.json
|
|
26
26
|
var package_default = {
|
|
27
27
|
name: "@ksm0709/context",
|
|
28
|
-
version: "0.0.
|
|
28
|
+
version: "0.0.28",
|
|
29
29
|
author: {
|
|
30
30
|
name: "TaehoKang",
|
|
31
31
|
email: "ksm07091@gmail.com"
|
|
@@ -67,7 +67,7 @@ var package_default = {
|
|
|
67
67
|
"@opencode-ai/plugin": ">=1.0.0"
|
|
68
68
|
},
|
|
69
69
|
dependencies: {
|
|
70
|
-
"@ksm0709/context": "^0.0.
|
|
70
|
+
"@ksm0709/context": "^0.0.27",
|
|
71
71
|
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
72
72
|
"jsonc-parser": "^3.0.0"
|
|
73
73
|
},
|
package/dist/mcp.js
CHANGED
|
@@ -33087,6 +33087,24 @@ ${tags.map((t) => ` - ${t}`).join(`
|
|
|
33087
33087
|
};
|
|
33088
33088
|
}
|
|
33089
33089
|
});
|
|
33090
|
+
const listToolsMethod = ListToolsRequestSchema.shape.method.value;
|
|
33091
|
+
const originalListToolsHandler = server.server._requestHandlers?.get(listToolsMethod);
|
|
33092
|
+
if (originalListToolsHandler) {
|
|
33093
|
+
server.server.setRequestHandler(ListToolsRequestSchema, async (request, extra) => {
|
|
33094
|
+
const response = await originalListToolsHandler(request, extra);
|
|
33095
|
+
if (response.tools) {
|
|
33096
|
+
response.tools = response.tools.map((tool) => {
|
|
33097
|
+
const newTool = { ...tool };
|
|
33098
|
+
delete newTool.execution;
|
|
33099
|
+
if (newTool.inputSchema && newTool.inputSchema.$schema) {
|
|
33100
|
+
delete newTool.inputSchema.$schema;
|
|
33101
|
+
}
|
|
33102
|
+
return newTool;
|
|
33103
|
+
});
|
|
33104
|
+
}
|
|
33105
|
+
return response;
|
|
33106
|
+
});
|
|
33107
|
+
}
|
|
33090
33108
|
const transport = new StdioServerTransport;
|
|
33091
33109
|
server.connect(transport);
|
|
33092
33110
|
return server;
|
package/dist/omx/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/omx/index.ts
|
|
2
|
-
import { existsSync as
|
|
3
|
-
import { join as
|
|
2
|
+
import { existsSync as existsSync5, readFileSync as readFileSync5, unlinkSync } from "node:fs";
|
|
3
|
+
import { join as join5 } from "node:path";
|
|
4
4
|
|
|
5
5
|
// src/constants.ts
|
|
6
6
|
var DEFAULTS = {
|
|
@@ -95,7 +95,7 @@ import { join as join3 } from "node:path";
|
|
|
95
95
|
// package.json
|
|
96
96
|
var package_default = {
|
|
97
97
|
name: "@ksm0709/context",
|
|
98
|
-
version: "0.0.
|
|
98
|
+
version: "0.0.28",
|
|
99
99
|
author: {
|
|
100
100
|
name: "TaehoKang",
|
|
101
101
|
email: "ksm07091@gmail.com"
|
|
@@ -137,7 +137,7 @@ var package_default = {
|
|
|
137
137
|
"@opencode-ai/plugin": ">=1.0.0"
|
|
138
138
|
},
|
|
139
139
|
dependencies: {
|
|
140
|
-
"@ksm0709/context": "^0.0.
|
|
140
|
+
"@ksm0709/context": "^0.0.27",
|
|
141
141
|
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
142
142
|
"jsonc-parser": "^3.0.0"
|
|
143
143
|
},
|
|
@@ -545,6 +545,76 @@ function injectIntoAgentsMd(agentsMdPath, content) {
|
|
|
545
545
|
writeFileAtomically(agentsMdPath, nextContent);
|
|
546
546
|
}
|
|
547
547
|
|
|
548
|
+
// src/omx/registry.ts
|
|
549
|
+
import { fileURLToPath } from "node:url";
|
|
550
|
+
import { dirname as dirname2, join as join4, resolve } from "node:path";
|
|
551
|
+
import { existsSync as existsSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3 } from "node:fs";
|
|
552
|
+
import { homedir } from "node:os";
|
|
553
|
+
function resolveMcpPath() {
|
|
554
|
+
const currentFile = fileURLToPath(import.meta.url);
|
|
555
|
+
const currentDir = dirname2(currentFile);
|
|
556
|
+
const distMcpPath = resolve(currentDir, "..", "mcp.js");
|
|
557
|
+
if (existsSync4(distMcpPath)) {
|
|
558
|
+
return distMcpPath;
|
|
559
|
+
}
|
|
560
|
+
const srcMcpPath = resolve(currentDir, "..", "mcp.ts");
|
|
561
|
+
if (existsSync4(srcMcpPath)) {
|
|
562
|
+
return srcMcpPath;
|
|
563
|
+
}
|
|
564
|
+
return distMcpPath;
|
|
565
|
+
}
|
|
566
|
+
function getRegistryPaths() {
|
|
567
|
+
return [
|
|
568
|
+
join4(homedir(), ".omx", "mcp-registry.json"),
|
|
569
|
+
join4(homedir(), ".omc", "mcp-registry.json")
|
|
570
|
+
];
|
|
571
|
+
}
|
|
572
|
+
function ensureMcpRegistered(sdkLog) {
|
|
573
|
+
const registryPaths = getRegistryPaths();
|
|
574
|
+
let targetPath = registryPaths[0];
|
|
575
|
+
for (const p of registryPaths) {
|
|
576
|
+
if (existsSync4(p)) {
|
|
577
|
+
targetPath = p;
|
|
578
|
+
break;
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
let registry = {};
|
|
582
|
+
if (existsSync4(targetPath)) {
|
|
583
|
+
try {
|
|
584
|
+
const content = readFileSync4(targetPath, "utf-8");
|
|
585
|
+
registry = JSON.parse(content);
|
|
586
|
+
} catch (e) {
|
|
587
|
+
if (sdkLog) {
|
|
588
|
+
sdkLog(`[ERROR] Failed to parse MCP registry at ${targetPath}: ${e instanceof Error ? e.message : String(e)}`);
|
|
589
|
+
}
|
|
590
|
+
registry = {};
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
const mcpPath = resolveMcpPath();
|
|
594
|
+
const expectedConfig = {
|
|
595
|
+
command: "bun",
|
|
596
|
+
args: [mcpPath]
|
|
597
|
+
};
|
|
598
|
+
const currentConfig = registry["context-mcp"];
|
|
599
|
+
if (!currentConfig || currentConfig.command !== expectedConfig.command || !Array.isArray(currentConfig.args) || currentConfig.args[0] !== expectedConfig.args[0]) {
|
|
600
|
+
registry["context-mcp"] = expectedConfig;
|
|
601
|
+
try {
|
|
602
|
+
mkdirSync3(dirname2(targetPath), { recursive: true });
|
|
603
|
+
writeFileSync3(targetPath, JSON.stringify(registry, null, 2), "utf-8");
|
|
604
|
+
if (sdkLog) {
|
|
605
|
+
sdkLog(`[INFO] Registered context-mcp in ${targetPath}`);
|
|
606
|
+
}
|
|
607
|
+
return true;
|
|
608
|
+
} catch (e) {
|
|
609
|
+
if (sdkLog) {
|
|
610
|
+
sdkLog(`[ERROR] Failed to write MCP registry to ${targetPath}: ${e instanceof Error ? e.message : String(e)}`);
|
|
611
|
+
}
|
|
612
|
+
return false;
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
return false;
|
|
616
|
+
}
|
|
617
|
+
|
|
548
618
|
// src/omx/tmux-submit.ts
|
|
549
619
|
import { spawnSync } from "node:child_process";
|
|
550
620
|
function runTmux(args) {
|
|
@@ -561,7 +631,7 @@ function runTmux(args) {
|
|
|
561
631
|
return { ok: true };
|
|
562
632
|
}
|
|
563
633
|
function sleep(ms) {
|
|
564
|
-
return new Promise((
|
|
634
|
+
return new Promise((resolve2) => globalThis.setTimeout(resolve2, ms));
|
|
565
635
|
}
|
|
566
636
|
async function sendTmuxSubmitSequence(target, attempts = 3) {
|
|
567
637
|
const totalAttempts = Math.max(1, Math.floor(attempts));
|
|
@@ -660,8 +730,21 @@ var STATIC_KNOWLEDGE_CONTEXT = `## Knowledge Context
|
|
|
660
730
|
async function onSessionStart(event, sdk) {
|
|
661
731
|
const projectDir = resolveProjectDir(event);
|
|
662
732
|
scaffoldIfNeeded(projectDir);
|
|
663
|
-
injectIntoAgentsMd(
|
|
733
|
+
injectIntoAgentsMd(join5(projectDir, "AGENTS.md"), STATIC_KNOWLEDGE_CONTEXT);
|
|
664
734
|
await sdk.log.info(`Injected context into AGENTS.md for ${projectDir}`);
|
|
735
|
+
const wasRegistered = ensureMcpRegistered(sdk.log.info);
|
|
736
|
+
if (wasRegistered) {
|
|
737
|
+
const warningMsg = "Context MCP was just added to your OMX registry. You must stop this session, run 'omx setup', and restart to use MCP tools.";
|
|
738
|
+
await sdk.log.info(warningMsg);
|
|
739
|
+
if (typeof sdk.tmux?.sendKeys === "function") {
|
|
740
|
+
const sessionName = typeof event.context?.session_name === "string" && event.context.session_name.trim().length > 0 ? event.context.session_name.trim() : undefined;
|
|
741
|
+
await sdk.tmux.sendKeys({
|
|
742
|
+
sessionName,
|
|
743
|
+
text: `# WARNING: ${warningMsg}`,
|
|
744
|
+
submit: true
|
|
745
|
+
});
|
|
746
|
+
}
|
|
747
|
+
}
|
|
665
748
|
}
|
|
666
749
|
async function onTurnComplete(event, sdk) {
|
|
667
750
|
const projectDir = resolveProjectDir(event);
|
|
@@ -687,9 +770,9 @@ async function onTurnComplete(event, sdk) {
|
|
|
687
770
|
}
|
|
688
771
|
const followupScopeKey = resolveFollowupScopeKey(event);
|
|
689
772
|
let pendingFollowupScopes = typeof sdk.state?.read === "function" ? await sdk.state.read(TURN_END_PENDING_SKIP_KEY, {}) ?? {} : {};
|
|
690
|
-
const workCompleteFile =
|
|
691
|
-
if (
|
|
692
|
-
const content =
|
|
773
|
+
const workCompleteFile = join5(projectDir, DEFAULTS.workCompleteFile);
|
|
774
|
+
if (existsSync5(workCompleteFile)) {
|
|
775
|
+
const content = readFileSync5(workCompleteFile, "utf-8");
|
|
693
776
|
const { sessionId: fileSessionId, turnId: fileTurnId } = parseWorkComplete(content);
|
|
694
777
|
const currentScopeId = event.session_id ?? event.thread_id ?? "";
|
|
695
778
|
if (!fileSessionId || fileSessionId === currentScopeId) {
|
|
@@ -755,7 +838,7 @@ async function onTurnComplete(event, sdk) {
|
|
|
755
838
|
${turnEnd}
|
|
756
839
|
</system-reminder>`;
|
|
757
840
|
const sessionName = typeof event.context?.session_name === "string" && event.context.session_name.trim().length > 0 ? event.context.session_name.trim() : undefined;
|
|
758
|
-
await new Promise((
|
|
841
|
+
await new Promise((resolve2) => globalThis.setTimeout(resolve2, 500));
|
|
759
842
|
if (typeof sdk.tmux?.sendKeys === "function") {}
|
|
760
843
|
const result = await sdk.tmux.sendKeys({
|
|
761
844
|
sessionName,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ksm0709/context",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.28",
|
|
4
4
|
"author": {
|
|
5
5
|
"name": "TaehoKang",
|
|
6
6
|
"email": "ksm07091@gmail.com"
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"@opencode-ai/plugin": ">=1.0.0"
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@ksm0709/context": "^0.0.
|
|
45
|
+
"@ksm0709/context": "^0.0.27",
|
|
46
46
|
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
47
47
|
"jsonc-parser": "^3.0.0"
|
|
48
48
|
},
|