@ksm0709/context 0.0.28 → 0.0.30

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.28",
108
+ version: "0.0.30",
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.27",
150
+ "@ksm0709/context": "^0.0.29",
141
151
  "@modelcontextprotocol/sdk": "^1.27.1",
142
152
  "jsonc-parser": "^3.0.0"
143
153
  },
@@ -386,14 +396,14 @@ turn_id={{turnId}}
386
396
  `;
387
397
  var DEFAULT_DAILY_NOTE_GUIDE = `# 데일리 노트 기록 가이드
388
398
 
389
- - [ ] \`context-mcp_append_daily_note\` 도구를 사용하여 기록을 추가하세요.
399
+ - [ ] \`context_mcp_append_daily_note\` 도구를 사용하여 기록을 추가하세요.
390
400
  - [ ] **주의**: 데일리 노트의 기존 내용은 절대 수정하거나 삭제하지 마세요.
391
401
  - [ ] 기록은 다음과 같은 형식으로 추가됩니다:
392
402
  \`[{{currentTimestamp}}] <기억 할 내용>\`
393
403
  - [ ] \`<기억 할 내용>\`에는 완벽한 컨텍스트 인계를 위해 오늘 완료한 핵심 작업 요약, 미해결 이슈(TODO), 중요 메모, 지식 노트 \`[[wikilink]]\` 등을 포함하세요.`;
394
404
  var DEFAULT_NOTE_GUIDE = `# 지식 노트 작성 및 관리 가이드
395
405
 
396
- - [ ] **노트 생성**: \`context-mcp_create_knowledge_note\` 도구를 사용하여 생성하세요.
406
+ - [ ] **노트 생성**: \`context_mcp_create_knowledge_note\` 도구를 사용하여 생성하세요.
397
407
  - [ ] 제텔카스텐(Zettelkasten) 3대 원칙 준수:
398
408
  - [ ] 원자성: 한 노트당 한 주제
399
409
  - [ ] 연결: 고립된 노트 방지
@@ -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);
@@ -595,14 +655,22 @@ function ensureMcpRegistered(sdkLog) {
595
655
  command: "bun",
596
656
  args: [mcpPath]
597
657
  };
598
- const currentConfig = registry["context-mcp"];
658
+ const currentConfig = registry["context_mcp"];
659
+ let changed = false;
660
+ if ("context-mcp" in registry) {
661
+ delete registry["context-mcp"];
662
+ changed = true;
663
+ }
599
664
  if (!currentConfig || currentConfig.command !== expectedConfig.command || !Array.isArray(currentConfig.args) || currentConfig.args[0] !== expectedConfig.args[0]) {
600
- registry["context-mcp"] = expectedConfig;
665
+ registry["context_mcp"] = expectedConfig;
666
+ changed = true;
667
+ }
668
+ if (changed) {
601
669
  try {
602
- mkdirSync3(dirname2(targetPath), { recursive: true });
670
+ mkdirSync3(dirname3(targetPath), { recursive: true });
603
671
  writeFileSync3(targetPath, JSON.stringify(registry, null, 2), "utf-8");
604
672
  if (sdkLog) {
605
- sdkLog(`[INFO] Registered context-mcp in ${targetPath}`);
673
+ sdkLog(`[INFO] Registered context_mcp in ${targetPath}`);
606
674
  }
607
675
  return true;
608
676
  } catch (e) {
@@ -697,40 +765,10 @@ async function logWarn(sdk, message, meta = {}) {
697
765
  }
698
766
  await sdk.log.info(message, meta);
699
767
  }
700
- var STATIC_KNOWLEDGE_CONTEXT = `## Knowledge Context
701
-
702
- 이 프로젝트는 **제텔카스텐(Zettelkasten)** 방식으로 지식을 관리합니다.
703
- 세션 간 컨텍스트를 보존하여, 이전 세션의 결정/패턴/실수가 다음 세션에서 재활용됩니다.
704
-
705
- ### 제텔카스텐 핵심 원칙
706
- 1. **원자성** -- 하나의 노트 = 하나의 주제. 여러 주제를 섞지 마세요.
707
- 2. **연결** -- 모든 노트는 [[wikilink]]로 관련 노트에 연결. 고립된 노트는 발견되지 않습니다.
708
- 3. **자기 언어** -- 복사-붙여넣기가 아닌, 핵심을 이해하고 간결하게 서술하세요.
709
-
710
- ### MCP Tools
711
- - **지식 관리**: \`context-mcp_search_knowledge\`, \`context-mcp_read_knowledge\`, \`context-mcp_create_knowledge_note\`, \`context-mcp_update_knowledge_note\`
712
- - **데일리 노트**: \`context-mcp_read_daily_note\`, \`context-mcp_append_daily_note\`
713
- - **작업 완료**: \`context-mcp_submit_turn_complete\` (작업 종료 시 필수 호출)
714
-
715
- ### 작업 전 필수
716
- - **데일리 노트 확인**: 가장 최근의 데일리 노트를 읽고 이전 세션의 컨텍스트와 미해결 이슈를 파악하세요.
717
- - **작업 의도 선언**: 작업 시작 전, 현재 세션의 목표와 작업 의도를 명확히 파악하고 선언하세요.
718
- - **지식 검색**: 작업과 관련된 문서를 **직접 먼저** 검색하고 읽으세요.
719
- - 지식 파일에 기록된 아키텍처 결정, 패턴, 제약사항을 반드시 따르세요.
720
-
721
- ### 개발 원칙
722
- - **TDD** (Test-Driven Development): 테스트를 먼저 작성하고(RED), 구현하여 통과시킨 뒤(GREEN), 리팩토링하세요.
723
- - **DDD** (Domain-Driven Design): 도메인 개념을 코드 구조에 반영하세요.
724
- - **테스트 커버리지**: 새로 작성하거나 변경한 코드는 테스트 커버리지 80% 이상을 목표로 하세요.
725
-
726
- ### 우선순위
727
- - AGENTS.md의 지시사항이 항상 최우선
728
- - 지식 노트의 결정사항 > 일반적 관행
729
- - 지식 노트에 없는 새로운 결정이나 반복 가치가 있는 발견은 작업 메모나 지식 노트 후보로 기록하세요.`;
730
768
  async function onSessionStart(event, sdk) {
731
769
  const projectDir = resolveProjectDir(event);
732
770
  scaffoldIfNeeded(projectDir);
733
- injectIntoAgentsMd(join5(projectDir, "AGENTS.md"), STATIC_KNOWLEDGE_CONTEXT);
771
+ injectIntoAgentsMd(join6(projectDir, "AGENTS.md"), STATIC_KNOWLEDGE_CONTEXT);
734
772
  await sdk.log.info(`Injected context into AGENTS.md for ${projectDir}`);
735
773
  const wasRegistered = ensureMcpRegistered(sdk.log.info);
736
774
  if (wasRegistered) {
@@ -770,8 +808,8 @@ async function onTurnComplete(event, sdk) {
770
808
  }
771
809
  const followupScopeKey = resolveFollowupScopeKey(event);
772
810
  let pendingFollowupScopes = typeof sdk.state?.read === "function" ? await sdk.state.read(TURN_END_PENDING_SKIP_KEY, {}) ?? {} : {};
773
- const workCompleteFile = join5(projectDir, DEFAULTS.workCompleteFile);
774
- if (existsSync5(workCompleteFile)) {
811
+ const workCompleteFile = join6(projectDir, DEFAULTS.workCompleteFile);
812
+ if (existsSync6(workCompleteFile)) {
775
813
  const content = readFileSync5(workCompleteFile, "utf-8");
776
814
  const { sessionId: fileSessionId, turnId: fileTurnId } = parseWorkComplete(content);
777
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.28",
3
+ "version": "0.0.30",
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.27",
45
+ "@ksm0709/context": "^0.0.29",
46
46
  "@modelcontextprotocol/sdk": "^1.27.1",
47
47
  "jsonc-parser": "^3.0.0"
48
48
  },