@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.
@@ -1,6 +1,6 @@
1
1
  // src/omx/index.ts
2
- import { existsSync as existsSync5, readFileSync as readFileSync5, unlinkSync } from "node:fs";
3
- import { join as join5 } from "node:path";
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.29",
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.28",
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/omx/agents-md.ts
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, readFileSync as readFileSync4, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3 } from "node:fs";
552
- import { homedir } from "node:os";
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
- join4(homedir(), ".omx", "mcp-registry.json"),
569
- join4(homedir(), ".omc", "mcp-registry.json")
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 (existsSync4(p)) {
636
+ if (existsSync5(p)) {
577
637
  targetPath = p;
578
638
  break;
579
639
  }
580
640
  }
581
641
  let registry = {};
582
- if (existsSync4(targetPath)) {
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(dirname2(targetPath), { recursive: true });
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(join5(projectDir, "AGENTS.md"), STATIC_KNOWLEDGE_CONTEXT);
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 = join5(projectDir, DEFAULTS.workCompleteFile);
782
- if (existsSync5(workCompleteFile)) {
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.29",
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.28",
45
+ "@ksm0709/context": "^0.0.30",
46
46
  "@modelcontextprotocol/sdk": "^1.27.1",
47
47
  "jsonc-parser": "^3.0.0"
48
48
  },