@ksm0709/context 0.0.29 → 0.0.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +1850 -247
- package/dist/index.js +4 -4
- package/dist/omc/session-start-hook.js +514 -0
- package/dist/omc/stop-hook.js +40 -0
- package/dist/omx/index.mjs +81 -51
- package/package.json +4 -4
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 existsSync6, readFileSync as readFileSync5, unlinkSync } from "node:fs";
|
|
3
|
+
import { join as join6 } from "node:path";
|
|
4
4
|
|
|
5
5
|
// src/constants.ts
|
|
6
6
|
var DEFAULTS = {
|
|
@@ -56,6 +56,11 @@ function getDefaultConfig() {
|
|
|
56
56
|
turnEnd: {
|
|
57
57
|
strategy: "turn-complete-sendkeys"
|
|
58
58
|
}
|
|
59
|
+
},
|
|
60
|
+
omc: {
|
|
61
|
+
turnEnd: {
|
|
62
|
+
strategy: "stop-hook"
|
|
63
|
+
}
|
|
59
64
|
}
|
|
60
65
|
};
|
|
61
66
|
}
|
|
@@ -73,6 +78,11 @@ function mergeWithDefaults(partial) {
|
|
|
73
78
|
turnEnd: {
|
|
74
79
|
strategy: partial.omx?.turnEnd?.strategy ?? defaults.omx?.turnEnd?.strategy
|
|
75
80
|
}
|
|
81
|
+
},
|
|
82
|
+
omc: {
|
|
83
|
+
turnEnd: {
|
|
84
|
+
strategy: partial.omc?.turnEnd?.strategy ?? defaults.omc?.turnEnd?.strategy ?? "stop-hook"
|
|
85
|
+
}
|
|
76
86
|
}
|
|
77
87
|
};
|
|
78
88
|
}
|
|
@@ -95,7 +105,7 @@ import { join as join3 } from "node:path";
|
|
|
95
105
|
// package.json
|
|
96
106
|
var package_default = {
|
|
97
107
|
name: "@ksm0709/context",
|
|
98
|
-
version: "0.0.
|
|
108
|
+
version: "0.0.31",
|
|
99
109
|
author: {
|
|
100
110
|
name: "TaehoKang",
|
|
101
111
|
email: "ksm07091@gmail.com"
|
|
@@ -125,10 +135,10 @@ var package_default = {
|
|
|
125
135
|
access: "public"
|
|
126
136
|
},
|
|
127
137
|
scripts: {
|
|
128
|
-
build: "bun build ./src/index.ts --outdir dist --target bun && bun build ./src/mcp.ts --outdir dist --target bun && bun build ./src/cli/index.ts --outdir dist/cli --target bun && bun build ./src/omx/index.ts --outdir dist/omx --target node --format esm --external jsonc-parser && mv dist/omx/index.js dist/omx/index.mjs",
|
|
138
|
+
build: "bun build ./src/index.ts --outdir dist --target bun && bun build ./src/mcp.ts --outdir dist --target bun && bun build ./src/cli/index.ts --outdir dist/cli --target bun && bun build ./src/omx/index.ts --outdir dist/omx --target node --format esm --external jsonc-parser && mv dist/omx/index.js dist/omx/index.mjs && bun build ./src/omc/session-start-hook.ts --outdir dist/omc --target bun && bun build ./src/omc/stop-hook.ts --outdir dist/omc --target bun",
|
|
129
139
|
test: "vitest run",
|
|
130
140
|
lint: "eslint src --ext .ts",
|
|
131
|
-
prepublishOnly: "bun build ./src/index.ts --outdir dist --target bun && bun build ./src/mcp.ts --outdir dist --target bun && bun build ./src/cli/index.ts --outdir dist/cli --target bun && bun build ./src/omx/index.ts --outdir dist/omx --target node --format esm --external jsonc-parser && mv dist/omx/index.js dist/omx/index.mjs"
|
|
141
|
+
prepublishOnly: "bun build ./src/index.ts --outdir dist --target bun && bun build ./src/mcp.ts --outdir dist --target bun && bun build ./src/cli/index.ts --outdir dist/cli --target bun && bun build ./src/omx/index.ts --outdir dist/omx --target node --format esm --external jsonc-parser && mv dist/omx/index.js dist/omx/index.mjs && bun build ./src/omc/session-start-hook.ts --outdir dist/omc --target bun && bun build ./src/omc/stop-hook.ts --outdir dist/omc --target bun"
|
|
132
142
|
},
|
|
133
143
|
files: [
|
|
134
144
|
"dist"
|
|
@@ -137,7 +147,7 @@ var package_default = {
|
|
|
137
147
|
"@opencode-ai/plugin": ">=1.0.0"
|
|
138
148
|
},
|
|
139
149
|
dependencies: {
|
|
140
|
-
"@ksm0709/context": "^0.0.
|
|
150
|
+
"@ksm0709/context": "^0.0.30",
|
|
141
151
|
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
142
152
|
"jsonc-parser": "^3.0.0"
|
|
143
153
|
},
|
|
@@ -492,7 +502,7 @@ function writeVersion(contextDir, version) {
|
|
|
492
502
|
writeFileSync(join3(contextDir, ".version"), version, "utf-8");
|
|
493
503
|
}
|
|
494
504
|
|
|
495
|
-
// src/
|
|
505
|
+
// src/shared/agents-md.ts
|
|
496
506
|
import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, renameSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
497
507
|
import { dirname } from "node:path";
|
|
498
508
|
var START_MARKER = "<!-- context:start -->";
|
|
@@ -545,41 +555,91 @@ function injectIntoAgentsMd(agentsMdPath, content) {
|
|
|
545
555
|
writeFileAtomically(agentsMdPath, nextContent);
|
|
546
556
|
}
|
|
547
557
|
|
|
558
|
+
// src/shared/knowledge-context.ts
|
|
559
|
+
var STATIC_KNOWLEDGE_CONTEXT = `## Knowledge Context
|
|
560
|
+
|
|
561
|
+
이 프로젝트는 **제텔카스텐(Zettelkasten)** 방식으로 지식을 관리합니다.
|
|
562
|
+
세션 간 컨텍스트를 보존하여, 이전 세션의 결정/패턴/실수가 다음 세션에서 재활용됩니다.
|
|
563
|
+
|
|
564
|
+
### 제텔카스텐 핵심 원칙
|
|
565
|
+
1. **원자성** -- 하나의 노트 = 하나의 주제. 여러 주제를 섞지 마세요.
|
|
566
|
+
2. **연결** -- 모든 노트는 [[wikilink]]로 관련 노트에 연결. 고립된 노트는 발견되지 않습니다.
|
|
567
|
+
3. **자기 언어** -- 복사-붙여넣기가 아닌, 핵심을 이해하고 간결하게 서술하세요.
|
|
568
|
+
|
|
569
|
+
### MCP Tools
|
|
570
|
+
- **지식 관리**: \`context_mcp_search_knowledge\`, \`context_mcp_read_knowledge\`, \`context_mcp_create_knowledge_note\`, \`context_mcp_update_knowledge_note\`
|
|
571
|
+
- **데일리 노트**: \`context_mcp_read_daily_note\`, \`context_mcp_append_daily_note\`
|
|
572
|
+
- **작업 완료**: \`context_mcp_submit_turn_complete\` (작업 종료 시 필수 호출)
|
|
573
|
+
|
|
574
|
+
### 작업 전 필수
|
|
575
|
+
- **데일리 노트 확인**: 가장 최근의 데일리 노트를 읽고 이전 세션의 컨텍스트와 미해결 이슈를 파악하세요.
|
|
576
|
+
- **작업 의도 선언**: 작업 시작 전, 현재 세션의 목표와 작업 의도를 명확히 파악하고 선언하세요.
|
|
577
|
+
- **지식 검색**: 작업과 관련된 문서를 **직접 먼저** 검색하고 읽으세요.
|
|
578
|
+
- 지식 파일에 기록된 아키텍처 결정, 패턴, 제약사항을 반드시 따르세요.
|
|
579
|
+
|
|
580
|
+
### 개발 원칙
|
|
581
|
+
- **TDD** (Test-Driven Development): 테스트를 먼저 작성하고(RED), 구현하여 통과시킨 뒤(GREEN), 리팩토링하세요.
|
|
582
|
+
- **DDD** (Domain-Driven Design): 도메인 개념을 코드 구조에 반영하세요.
|
|
583
|
+
- **테스트 커버리지**: 새로 작성하거나 변경한 코드는 테스트 커버리지 80% 이상을 목표로 하세요.
|
|
584
|
+
|
|
585
|
+
### 우선순위
|
|
586
|
+
- AGENTS.md의 지시사항이 항상 최우선
|
|
587
|
+
- 지식 노트의 결정사항 > 일반적 관행
|
|
588
|
+
- 지식 노트에 없는 새로운 결정이나 반복 가치가 있는 발견은 작업 메모나 지식 노트 후보로 기록하세요.
|
|
589
|
+
|
|
590
|
+
### 작업 완료 프로토콜
|
|
591
|
+
- **필수**: 모든 작업이 완료되면 반드시 \`context-mcp\` MCP 서버의 \`submit_turn_complete\` 도구를 호출하세요.
|
|
592
|
+
- 이 호출 없이 세션을 종료하면 작업 기록이 보존되지 않습니다.
|
|
593
|
+
- 필요한 인자: daily_note_update_proof, knowledge_note_proof, quality_check_output, checkpoint_commit_hashes, scope_review_notes`;
|
|
594
|
+
|
|
548
595
|
// src/omx/registry.ts
|
|
596
|
+
import { join as join5, dirname as dirname3 } from "node:path";
|
|
597
|
+
import { existsSync as existsSync5, readFileSync as readFileSync4, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3 } from "node:fs";
|
|
598
|
+
import { homedir } from "node:os";
|
|
599
|
+
|
|
600
|
+
// src/shared/mcp-path.ts
|
|
549
601
|
import { fileURLToPath } from "node:url";
|
|
550
602
|
import { dirname as dirname2, join as join4, resolve } from "node:path";
|
|
551
|
-
import { existsSync as existsSync4
|
|
552
|
-
import {
|
|
603
|
+
import { existsSync as existsSync4 } from "node:fs";
|
|
604
|
+
import { createRequire } from "node:module";
|
|
553
605
|
function resolveMcpPath() {
|
|
606
|
+
try {
|
|
607
|
+
const req = createRequire(import.meta.url);
|
|
608
|
+
const pkgJsonPath = req.resolve("@ksm0709/context/package.json");
|
|
609
|
+
const pkgRoot = dirname2(pkgJsonPath);
|
|
610
|
+
const distMcp = join4(pkgRoot, "dist", "mcp.js");
|
|
611
|
+
if (existsSync4(distMcp))
|
|
612
|
+
return distMcp;
|
|
613
|
+
} catch {}
|
|
554
614
|
const currentFile = fileURLToPath(import.meta.url);
|
|
555
615
|
const currentDir = dirname2(currentFile);
|
|
556
616
|
const distMcpPath = resolve(currentDir, "..", "mcp.js");
|
|
557
|
-
if (existsSync4(distMcpPath))
|
|
617
|
+
if (existsSync4(distMcpPath))
|
|
558
618
|
return distMcpPath;
|
|
559
|
-
}
|
|
560
619
|
const srcMcpPath = resolve(currentDir, "..", "mcp.ts");
|
|
561
|
-
if (existsSync4(srcMcpPath))
|
|
620
|
+
if (existsSync4(srcMcpPath))
|
|
562
621
|
return srcMcpPath;
|
|
563
|
-
}
|
|
564
622
|
return distMcpPath;
|
|
565
623
|
}
|
|
624
|
+
|
|
625
|
+
// src/omx/registry.ts
|
|
566
626
|
function getRegistryPaths() {
|
|
567
627
|
return [
|
|
568
|
-
|
|
569
|
-
|
|
628
|
+
join5(homedir(), ".omx", "mcp-registry.json"),
|
|
629
|
+
join5(homedir(), ".omc", "mcp-registry.json")
|
|
570
630
|
];
|
|
571
631
|
}
|
|
572
632
|
function ensureMcpRegistered(sdkLog) {
|
|
573
633
|
const registryPaths = getRegistryPaths();
|
|
574
634
|
let targetPath = registryPaths[0];
|
|
575
635
|
for (const p of registryPaths) {
|
|
576
|
-
if (
|
|
636
|
+
if (existsSync5(p)) {
|
|
577
637
|
targetPath = p;
|
|
578
638
|
break;
|
|
579
639
|
}
|
|
580
640
|
}
|
|
581
641
|
let registry = {};
|
|
582
|
-
if (
|
|
642
|
+
if (existsSync5(targetPath)) {
|
|
583
643
|
try {
|
|
584
644
|
const content = readFileSync4(targetPath, "utf-8");
|
|
585
645
|
registry = JSON.parse(content);
|
|
@@ -607,7 +667,7 @@ function ensureMcpRegistered(sdkLog) {
|
|
|
607
667
|
}
|
|
608
668
|
if (changed) {
|
|
609
669
|
try {
|
|
610
|
-
mkdirSync3(
|
|
670
|
+
mkdirSync3(dirname3(targetPath), { recursive: true });
|
|
611
671
|
writeFileSync3(targetPath, JSON.stringify(registry, null, 2), "utf-8");
|
|
612
672
|
if (sdkLog) {
|
|
613
673
|
sdkLog(`[INFO] Registered context_mcp in ${targetPath}`);
|
|
@@ -705,40 +765,10 @@ async function logWarn(sdk, message, meta = {}) {
|
|
|
705
765
|
}
|
|
706
766
|
await sdk.log.info(message, meta);
|
|
707
767
|
}
|
|
708
|
-
var STATIC_KNOWLEDGE_CONTEXT = `## Knowledge Context
|
|
709
|
-
|
|
710
|
-
이 프로젝트는 **제텔카스텐(Zettelkasten)** 방식으로 지식을 관리합니다.
|
|
711
|
-
세션 간 컨텍스트를 보존하여, 이전 세션의 결정/패턴/실수가 다음 세션에서 재활용됩니다.
|
|
712
|
-
|
|
713
|
-
### 제텔카스텐 핵심 원칙
|
|
714
|
-
1. **원자성** -- 하나의 노트 = 하나의 주제. 여러 주제를 섞지 마세요.
|
|
715
|
-
2. **연결** -- 모든 노트는 [[wikilink]]로 관련 노트에 연결. 고립된 노트는 발견되지 않습니다.
|
|
716
|
-
3. **자기 언어** -- 복사-붙여넣기가 아닌, 핵심을 이해하고 간결하게 서술하세요.
|
|
717
|
-
|
|
718
|
-
### MCP Tools
|
|
719
|
-
- **지식 관리**: \`context_mcp_search_knowledge\`, \`context_mcp_read_knowledge\`, \`context_mcp_create_knowledge_note\`, \`context_mcp_update_knowledge_note\`
|
|
720
|
-
- **데일리 노트**: \`context_mcp_read_daily_note\`, \`context_mcp_append_daily_note\`
|
|
721
|
-
- **작업 완료**: \`context_mcp_submit_turn_complete\` (작업 종료 시 필수 호출)
|
|
722
|
-
|
|
723
|
-
### 작업 전 필수
|
|
724
|
-
- **데일리 노트 확인**: 가장 최근의 데일리 노트를 읽고 이전 세션의 컨텍스트와 미해결 이슈를 파악하세요.
|
|
725
|
-
- **작업 의도 선언**: 작업 시작 전, 현재 세션의 목표와 작업 의도를 명확히 파악하고 선언하세요.
|
|
726
|
-
- **지식 검색**: 작업과 관련된 문서를 **직접 먼저** 검색하고 읽으세요.
|
|
727
|
-
- 지식 파일에 기록된 아키텍처 결정, 패턴, 제약사항을 반드시 따르세요.
|
|
728
|
-
|
|
729
|
-
### 개발 원칙
|
|
730
|
-
- **TDD** (Test-Driven Development): 테스트를 먼저 작성하고(RED), 구현하여 통과시킨 뒤(GREEN), 리팩토링하세요.
|
|
731
|
-
- **DDD** (Domain-Driven Design): 도메인 개념을 코드 구조에 반영하세요.
|
|
732
|
-
- **테스트 커버리지**: 새로 작성하거나 변경한 코드는 테스트 커버리지 80% 이상을 목표로 하세요.
|
|
733
|
-
|
|
734
|
-
### 우선순위
|
|
735
|
-
- AGENTS.md의 지시사항이 항상 최우선
|
|
736
|
-
- 지식 노트의 결정사항 > 일반적 관행
|
|
737
|
-
- 지식 노트에 없는 새로운 결정이나 반복 가치가 있는 발견은 작업 메모나 지식 노트 후보로 기록하세요.`;
|
|
738
768
|
async function onSessionStart(event, sdk) {
|
|
739
769
|
const projectDir = resolveProjectDir(event);
|
|
740
770
|
scaffoldIfNeeded(projectDir);
|
|
741
|
-
injectIntoAgentsMd(
|
|
771
|
+
injectIntoAgentsMd(join6(projectDir, "AGENTS.md"), STATIC_KNOWLEDGE_CONTEXT);
|
|
742
772
|
await sdk.log.info(`Injected context into AGENTS.md for ${projectDir}`);
|
|
743
773
|
const wasRegistered = ensureMcpRegistered(sdk.log.info);
|
|
744
774
|
if (wasRegistered) {
|
|
@@ -778,8 +808,8 @@ async function onTurnComplete(event, sdk) {
|
|
|
778
808
|
}
|
|
779
809
|
const followupScopeKey = resolveFollowupScopeKey(event);
|
|
780
810
|
let pendingFollowupScopes = typeof sdk.state?.read === "function" ? await sdk.state.read(TURN_END_PENDING_SKIP_KEY, {}) ?? {} : {};
|
|
781
|
-
const workCompleteFile =
|
|
782
|
-
if (
|
|
811
|
+
const workCompleteFile = join6(projectDir, DEFAULTS.workCompleteFile);
|
|
812
|
+
if (existsSync6(workCompleteFile)) {
|
|
783
813
|
const content = readFileSync5(workCompleteFile, "utf-8");
|
|
784
814
|
const { sessionId: fileSessionId, turnId: fileTurnId } = parseWorkComplete(content);
|
|
785
815
|
const currentScopeId = event.session_id ?? event.thread_id ?? "";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ksm0709/context",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.31",
|
|
4
4
|
"author": {
|
|
5
5
|
"name": "TaehoKang",
|
|
6
6
|
"email": "ksm07091@gmail.com"
|
|
@@ -30,10 +30,10 @@
|
|
|
30
30
|
"access": "public"
|
|
31
31
|
},
|
|
32
32
|
"scripts": {
|
|
33
|
-
"build": "bun build ./src/index.ts --outdir dist --target bun && bun build ./src/mcp.ts --outdir dist --target bun && bun build ./src/cli/index.ts --outdir dist/cli --target bun && bun build ./src/omx/index.ts --outdir dist/omx --target node --format esm --external jsonc-parser && mv dist/omx/index.js dist/omx/index.mjs",
|
|
33
|
+
"build": "bun build ./src/index.ts --outdir dist --target bun && bun build ./src/mcp.ts --outdir dist --target bun && bun build ./src/cli/index.ts --outdir dist/cli --target bun && bun build ./src/omx/index.ts --outdir dist/omx --target node --format esm --external jsonc-parser && mv dist/omx/index.js dist/omx/index.mjs && bun build ./src/omc/session-start-hook.ts --outdir dist/omc --target bun && bun build ./src/omc/stop-hook.ts --outdir dist/omc --target bun",
|
|
34
34
|
"test": "vitest run",
|
|
35
35
|
"lint": "eslint src --ext .ts",
|
|
36
|
-
"prepublishOnly": "bun build ./src/index.ts --outdir dist --target bun && bun build ./src/mcp.ts --outdir dist --target bun && bun build ./src/cli/index.ts --outdir dist/cli --target bun && bun build ./src/omx/index.ts --outdir dist/omx --target node --format esm --external jsonc-parser && mv dist/omx/index.js dist/omx/index.mjs"
|
|
36
|
+
"prepublishOnly": "bun build ./src/index.ts --outdir dist --target bun && bun build ./src/mcp.ts --outdir dist --target bun && bun build ./src/cli/index.ts --outdir dist/cli --target bun && bun build ./src/omx/index.ts --outdir dist/omx --target node --format esm --external jsonc-parser && mv dist/omx/index.js dist/omx/index.mjs && bun build ./src/omc/session-start-hook.ts --outdir dist/omc --target bun && bun build ./src/omc/stop-hook.ts --outdir dist/omc --target bun"
|
|
37
37
|
},
|
|
38
38
|
"files": [
|
|
39
39
|
"dist"
|
|
@@ -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.30",
|
|
46
46
|
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
47
47
|
"jsonc-parser": "^3.0.0"
|
|
48
48
|
},
|