@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/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.29",
28
+ version: "0.0.31",
29
29
  author: {
30
30
  name: "TaehoKang",
31
31
  email: "ksm07091@gmail.com"
@@ -55,10 +55,10 @@ var package_default = {
55
55
  access: "public"
56
56
  },
57
57
  scripts: {
58
- 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",
58
+ 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",
59
59
  test: "vitest run",
60
60
  lint: "eslint src --ext .ts",
61
- 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"
61
+ 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"
62
62
  },
63
63
  files: [
64
64
  "dist"
@@ -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.28",
70
+ "@ksm0709/context": "^0.0.30",
71
71
  "@modelcontextprotocol/sdk": "^1.27.1",
72
72
  "jsonc-parser": "^3.0.0"
73
73
  },
@@ -0,0 +1,514 @@
1
+ // @bun
2
+ // src/lib/scaffold.ts
3
+ import { existsSync as existsSync2, mkdirSync, readFileSync, writeFileSync } from "fs";
4
+ import { join as join2 } from "path";
5
+
6
+ // src/lib/context-dir.ts
7
+ import { existsSync } from "fs";
8
+ import { join } from "path";
9
+ function resolveContextDir(projectDir) {
10
+ const nextContextDir = ".context";
11
+ if (existsSync(join(projectDir, nextContextDir))) {
12
+ return nextContextDir;
13
+ }
14
+ const legacyContextDir = ".opencode/context";
15
+ if (existsSync(join(projectDir, legacyContextDir))) {
16
+ return legacyContextDir;
17
+ }
18
+ return nextContextDir;
19
+ }
20
+ // package.json
21
+ var package_default = {
22
+ name: "@ksm0709/context",
23
+ version: "0.0.31",
24
+ author: {
25
+ name: "TaehoKang",
26
+ email: "ksm07091@gmail.com"
27
+ },
28
+ type: "module",
29
+ main: "./dist/index.js",
30
+ bin: {
31
+ context: "dist/cli/index.js"
32
+ },
33
+ exports: {
34
+ ".": {
35
+ import: "./dist/index.js",
36
+ types: "./dist/index.d.ts",
37
+ default: "./dist/index.js"
38
+ },
39
+ "./omx": {
40
+ import: "./dist/omx/index.mjs",
41
+ types: "./dist/omx/index.d.ts",
42
+ default: "./dist/omx/index.mjs"
43
+ }
44
+ },
45
+ repository: {
46
+ type: "git",
47
+ url: "git+ssh://git@github.com/ksm0709/context.git"
48
+ },
49
+ publishConfig: {
50
+ access: "public"
51
+ },
52
+ scripts: {
53
+ 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",
54
+ test: "vitest run",
55
+ lint: "eslint src --ext .ts",
56
+ 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"
57
+ },
58
+ files: [
59
+ "dist"
60
+ ],
61
+ peerDependencies: {
62
+ "@opencode-ai/plugin": ">=1.0.0"
63
+ },
64
+ dependencies: {
65
+ "@ksm0709/context": "^0.0.30",
66
+ "@modelcontextprotocol/sdk": "^1.27.1",
67
+ "jsonc-parser": "^3.0.0"
68
+ },
69
+ devDependencies: {
70
+ "@opencode-ai/plugin": "^1.2.10",
71
+ "@eslint/js": "^9.39.1",
72
+ "@types/node": "^20.11.5",
73
+ "@typescript-eslint/eslint-plugin": "8.47.0",
74
+ "@typescript-eslint/parser": "8.47.0",
75
+ "bun-types": "latest",
76
+ eslint: "^9.39.1",
77
+ "eslint-config-prettier": "10.1.8",
78
+ "eslint-plugin-prettier": "^5.1.3",
79
+ prettier: "^3.2.4",
80
+ "typescript-eslint": "^8.47.0",
81
+ vitest: "^3.2.4",
82
+ "@vitest/coverage-v8": "^3.2.4"
83
+ }
84
+ };
85
+
86
+ // src/lib/scaffold.ts
87
+ var PLUGIN_VERSION = package_default.version;
88
+ var DEFAULT_CONFIG = `{
89
+ // Context Plugin Configuration
90
+ // See: https://github.com/ksm0709/context
91
+ "knowledge": {
92
+ "dir": ".context/memory",
93
+ "sources": ["AGENTS.md"]
94
+ },
95
+ "omx": {
96
+ // Inject turn-end after native turn-complete via tmux send-keys
97
+ "turnEnd": {
98
+ "strategy": "turn-complete-sendkeys"
99
+ }
100
+ }
101
+ }`;
102
+ var DEFAULT_ADR_TEMPLATE = `# ADR-NNN: [\uC81C\uBAA9]
103
+
104
+ ## \uC0C1\uD0DC
105
+
106
+ Accepted | Deprecated | Superseded by [[ADR-YYY]]
107
+
108
+ ## \uB9E5\uB77D
109
+
110
+ \uC774 \uACB0\uC815\uC744 \uB0B4\uB9AC\uAC8C \uB41C \uBC30\uACBD/\uBB38\uC81C \uC0C1\uD669
111
+
112
+ ## \uACB0\uC815
113
+
114
+ \uBB34\uC5C7\uC744 \uC5B4\uB5BB\uAC8C \uD558\uAE30\uB85C \uD588\uB294\uC9C0
115
+
116
+ ## \uACB0\uACFC
117
+
118
+ ### \uAE0D\uC815\uC801
119
+
120
+ - ...
121
+
122
+ ### \uBD80\uC815\uC801 (\uD2B8\uB808\uC774\uB4DC\uC624\uD504)
123
+
124
+ - ...
125
+
126
+ ## \uAD00\uB828 \uB178\uD2B8
127
+
128
+ - [[\uAD00\uB828-\uACB0\uC815.md]] / [[\uAD00\uB828-\uD328\uD134.md]]
129
+ `;
130
+ var DEFAULT_PATTERN_TEMPLATE = `# Pattern: [\uD328\uD134 \uC774\uB984]
131
+
132
+ ## \uBB38\uC81C
133
+
134
+ \uC774 \uD328\uD134\uC774 \uD574\uACB0\uD558\uB294 \uBB38\uC81C
135
+
136
+ ## \uD574\uBC95
137
+
138
+ // \uD328\uD134\uC758 \uB300\uD45C\uC801 \uC608\uC2DC \uCF54\uB4DC
139
+
140
+ ## \uC0AC\uC6A9 \uC2DC\uC810
141
+
142
+ - \uC774\uB7F4 \uB54C \uC0AC\uC6A9
143
+
144
+ ## \uC0AC\uC6A9\uD558\uC9C0 \uB9D0 \uAC83
145
+
146
+ - \uC774\uB7F4 \uB54C\uB294 \uC0AC\uC6A9 \uAE08\uC9C0 (\uC548\uD2F0\uD328\uD134 \uACBD\uACE0)
147
+
148
+ ## \uCF54\uB4DC\uBCA0\uC774\uC2A4 \uB0B4 \uC608\uC2DC
149
+
150
+ - [[\uACBD\uB85C/\uD30C\uC77C.ts]] -- \uC2E4\uC81C \uC801\uC6A9 \uC0AC\uB840
151
+
152
+ ## \uAD00\uB828 \uD328\uD134
153
+
154
+ - [[\uB300\uC548-\uD328\uD134.md]] / [[\uBCF4\uC644-\uD328\uD134.md]]
155
+ `;
156
+ var DEFAULT_BUG_TEMPLATE = `# Bug: [\uAC04\uB2E8\uD55C \uC124\uBA85]
157
+
158
+ ## \uC99D\uC0C1
159
+
160
+ - \uC5D0\uB7EC \uBA54\uC2DC\uC9C0: \`...\`
161
+ - \uAD00\uCC30\uB41C \uB3D9\uC791: ...
162
+
163
+ ## \uC6D0\uC778
164
+
165
+ \uC2E4\uC81C \uC6D0\uC778 \uBD84\uC11D
166
+
167
+ ## \uD574\uACB0
168
+
169
+ // \uC218\uC815 \uCF54\uB4DC
170
+
171
+ ## \uC608\uBC29
172
+
173
+ \uD5A5\uD6C4 \uAC19\uC740 \uBB38\uC81C\uB97C \uBC29\uC9C0\uD558\uB294 \uBC29\uBC95
174
+
175
+ ## \uAD00\uB828 \uB178\uD2B8
176
+
177
+ - [[\uC720\uC0AC-\uBC84\uADF8.md]] / [[\uC608\uBC29-\uD328\uD134.md]]
178
+ `;
179
+ var DEFAULT_GOTCHA_TEMPLATE = `# Gotcha: [\uB77C\uC774\uBE0C\uB7EC\uB9AC] -- [\uD568\uC815 \uC124\uBA85]
180
+
181
+ ## \uC608\uC0C1 vs \uC2E4\uC81C
182
+
183
+ \uC608\uC0C1\uD55C \uB3D9\uC791\uACFC \uC2E4\uC81C \uB3D9\uC791\uC758 \uCC28\uC774
184
+
185
+ ## \uC6B0\uD68C\uBC95
186
+
187
+ // \uC791\uB3D9\uD558\uB294 \uD574\uACB0 \uCF54\uB4DC
188
+
189
+ ## \uC6D0\uC778 (\uC54C\uB824\uC9C4 \uACBD\uC6B0)
190
+
191
+ \uC65C \uC774\uB807\uAC8C \uB3D9\uC791\uD558\uB294\uC9C0
192
+
193
+ ## \uAD00\uB828
194
+
195
+ - \uC774\uC288: [GitHub issue / \uBB38\uC11C \uB9C1\uD06C]
196
+ - [[\uAD00\uB828-gotcha.md]]
197
+ `;
198
+ var DEFAULT_DECISION_TEMPLATE = `# Decision: [\uC81C\uBAA9]
199
+
200
+ ## \uACB0\uC815
201
+
202
+ \uBB34\uC5C7\uC744 \uC120\uD0DD\uD588\uB294\uC9C0
203
+
204
+ ## \uADFC\uAC70
205
+
206
+ \uC65C \uC774\uAC83\uC744 \uC120\uD0DD\uD588\uB294\uC9C0
207
+
208
+ ## \uACE0\uB824\uD55C \uB300\uC548
209
+
210
+ - \uB300\uC548 1: \uD0C8\uB77D \uC774\uC720
211
+ - \uB300\uC548 2: \uD0C8\uB77D \uC774\uC720
212
+
213
+ ## \uAD00\uB828 \uB178\uD2B8
214
+
215
+ - [[\uAD00\uB828-ADR.md]] / [[\uAD00\uB828-\uD328\uD134.md]]
216
+ `;
217
+ var DEFAULT_CONTEXT_TEMPLATE = `# Context: [\uD504\uB85C\uC81D\uD2B8/\uBAA8\uB4C8\uBA85]
218
+
219
+ ## \uAC1C\uC694
220
+
221
+ \uBB34\uC5C7\uC774\uACE0 \uBB34\uC5C7\uC744 \uD558\uB294\uC9C0
222
+
223
+ ## \uAE30\uC220 \uC2A4\uD0DD
224
+
225
+ - \uC5B8\uC5B4 / \uD504\uB808\uC784\uC6CC\uD06C / \uC8FC\uC694 \uB77C\uC774\uBE0C\uB7EC\uB9AC
226
+
227
+ ## \uC544\uD0A4\uD14D\uCC98
228
+
229
+ \uACE0\uC218\uC900 \uAD6C\uC870\uC640 \uD328\uD134
230
+
231
+ ## \uCEE8\uBCA4\uC158
232
+
233
+ - \uD30C\uC77C \uAD6C\uC870 / \uB124\uC774\uBC0D / \uD14C\uC2A4\uD2B8 \uBC29\uC2DD
234
+
235
+ ## \uC9C4\uC785\uC810
236
+
237
+ - [[src/index.ts]] / [[config.json]]
238
+
239
+ ## \uAD00\uB828 \uB178\uD2B8
240
+
241
+ - [[\uAD00\uB828-context.md]] / [[\uC8FC\uC694-ADR.md]]
242
+ `;
243
+ var DEFAULT_RUNBOOK_TEMPLATE = `# Runbook: [\uC808\uCC28 \uC774\uB984]
244
+
245
+ ## \uBAA9\uC801
246
+
247
+ \uC774 \uC808\uCC28\uAC00 \uB2EC\uC131\uD558\uB294 \uAC83
248
+
249
+ ## \uC0AC\uC804 \uC870\uAC74
250
+
251
+ - \uD544\uC694\uD55C \uAC83 1
252
+
253
+ ## \uB2E8\uACC4
254
+
255
+ 1. \uCCAB \uBC88\uC9F8 \uB2E8\uACC4
256
+ 2. \uB450 \uBC88\uC9F8 \uB2E8\uACC4
257
+
258
+ ## \uD655\uC778 \uBC29\uBC95
259
+
260
+ \uC131\uACF5\uD588\uB294\uC9C0 \uD655\uC778\uD558\uB294 \uBC29\uBC95
261
+
262
+ ## \uBB38\uC81C \uD574\uACB0
263
+
264
+ | \uC99D\uC0C1 | \uD574\uACB0 |
265
+ | ------ | --------------- |
266
+ | \uC774\uC288 1 | [[\uAD00\uB828-bug.md]] |
267
+
268
+ ## \uAD00\uB828 \uB178\uD2B8
269
+
270
+ - [[\uAD00\uB828-runbook.md]] / [[\uAD00\uB828-context.md]]
271
+ `;
272
+ var DEFAULT_INSIGHT_TEMPLATE = `# Insight: [\uBC1C\uACAC \uC81C\uBAA9]
273
+
274
+ ## \uBC1C\uACAC
275
+
276
+ \uBB34\uC5C7\uC744 \uC54C\uAC8C \uB418\uC5C8\uB294\uC9C0
277
+
278
+ ## \uB9E5\uB77D
279
+
280
+ \uC5B4\uB5BB\uAC8C \uBC1C\uACAC\uD588\uB294\uC9C0 (\uC5B4\uB5A4 \uC791\uC5C5 \uC911, \uC5B4\uB5A4 \uC2E4\uD5D8)
281
+
282
+ ## \uC2DC\uC0AC\uC810
283
+
284
+ \uC774\uAC83\uC774 \uD5A5\uD6C4 \uC791\uC5C5\uC5D0 \uBBF8\uCE58\uB294 \uC601\uD5A5
285
+
286
+ ## \uC801\uC6A9
287
+
288
+ \uC774 \uBC1C\uACAC\uC744 \uBC14\uD0D5\uC73C\uB85C \uC5B4\uB5BB\uAC8C \uD589\uB3D9\uC744 \uBC14\uAFD4\uC57C \uD558\uB294\uC9C0
289
+
290
+ ## \uAD00\uB828 \uB178\uD2B8
291
+
292
+ - [[\uAD00\uB828-insight.md]] / [[\uC601\uD5A5\uBC1B\uB294-\uD328\uD134.md]] / [[\uAD00\uB828-ADR.md]]
293
+ `;
294
+ var DEFAULT_INDEX_TEMPLATE = `# [Domain] Domain
295
+
296
+ Overview: [1-2 sentence description of this domain]
297
+
298
+ ## Notes
299
+
300
+ | File | Summary | Read When... |
301
+ |------|---------|--------------|
302
+ | [[example.md]] | Example summary | Working on X |
303
+
304
+ ## Related Domains
305
+
306
+ - [[../other-domain/INDEX.md]] -- Description
307
+ `;
308
+ var DEFAULT_WORK_COMPLETE_TEMPLATE = `timestamp={{currentTimestamp}}
309
+ session_id={{sessionId}}
310
+ turn_id={{turnId}}
311
+ `;
312
+ var DEFAULT_DAILY_NOTE_GUIDE = `# \uB370\uC77C\uB9AC \uB178\uD2B8 \uAE30\uB85D \uAC00\uC774\uB4DC
313
+
314
+ - [ ] \`context_mcp_append_daily_note\` \uB3C4\uAD6C\uB97C \uC0AC\uC6A9\uD558\uC5EC \uAE30\uB85D\uC744 \uCD94\uAC00\uD558\uC138\uC694.
315
+ - [ ] **\uC8FC\uC758**: \uB370\uC77C\uB9AC \uB178\uD2B8\uC758 \uAE30\uC874 \uB0B4\uC6A9\uC740 \uC808\uB300 \uC218\uC815\uD558\uAC70\uB098 \uC0AD\uC81C\uD558\uC9C0 \uB9C8\uC138\uC694.
316
+ - [ ] \uAE30\uB85D\uC740 \uB2E4\uC74C\uACFC \uAC19\uC740 \uD615\uC2DD\uC73C\uB85C \uCD94\uAC00\uB429\uB2C8\uB2E4:
317
+ \`[{{currentTimestamp}}] <\uAE30\uC5B5 \uD560 \uB0B4\uC6A9>\`
318
+ - [ ] \`<\uAE30\uC5B5 \uD560 \uB0B4\uC6A9>\`\uC5D0\uB294 \uC644\uBCBD\uD55C \uCEE8\uD14D\uC2A4\uD2B8 \uC778\uACC4\uB97C \uC704\uD574 \uC624\uB298 \uC644\uB8CC\uD55C \uD575\uC2EC \uC791\uC5C5 \uC694\uC57D, \uBBF8\uD574\uACB0 \uC774\uC288(TODO), \uC911\uC694 \uBA54\uBAA8, \uC9C0\uC2DD \uB178\uD2B8 \`[[wikilink]]\` \uB4F1\uC744 \uD3EC\uD568\uD558\uC138\uC694.`;
319
+ var DEFAULT_NOTE_GUIDE = `# \uC9C0\uC2DD \uB178\uD2B8 \uC791\uC131 \uBC0F \uAD00\uB9AC \uAC00\uC774\uB4DC
320
+
321
+ - [ ] **\uB178\uD2B8 \uC0DD\uC131**: \`context_mcp_create_knowledge_note\` \uB3C4\uAD6C\uB97C \uC0AC\uC6A9\uD558\uC5EC \uC0DD\uC131\uD558\uC138\uC694.
322
+ - [ ] \uC81C\uD154\uCE74\uC2A4\uD150(Zettelkasten) 3\uB300 \uC6D0\uCE59 \uC900\uC218:
323
+ - [ ] \uC6D0\uC790\uC131: \uD55C \uB178\uD2B8\uB2F9 \uD55C \uC8FC\uC81C
324
+ - [ ] \uC5F0\uACB0: \uACE0\uB9BD\uB41C \uB178\uD2B8 \uBC29\uC9C0
325
+ - [ ] \uC790\uAE30 \uC5B8\uC5B4 \uC11C\uC220: \uD575\uC2EC\uC744 \uC774\uD574\uD558\uACE0 \uAC04\uACB0\uD558\uAC8C \uC11C\uC220
326
+ - [ ] **\uAE30\uB85D \uB300\uC0C1 \uD310\uB2E8 \uAE30\uC900:**
327
+
328
+ | \uC0C1\uD669 | \uD15C\uD50C\uB9BF | \uD30C\uC77C\uBA85 \uD328\uD134 |
329
+ | --- | --- | --- |
330
+ | \uC544\uD0A4\uD14D\uCC98/\uAE30\uC220 \uC2A4\uD0DD \uC911\uB300 \uACB0\uC815 | \`.context/templates/adr.md\` | \`adr-NNN-\uC81C\uBAA9.md\` |
331
+ | \uBC18\uBCF5 \uC0AC\uC6A9\uD560 \uCF54\uB4DC \uD328\uD134 \uBC1C\uACAC | \`.context/templates/pattern.md\` | \`pattern-\uC81C\uBAA9.md\` |
332
+ | \uBE44\uC790\uBA85\uD55C \uBC84\uADF8 \uD574\uACB0 | \`.context/templates/bug.md\` | \`bug-\uC81C\uBAA9.md\` |
333
+ | \uC678\uBD80 API/\uB77C\uC774\uBE0C\uB7EC\uB9AC \uC608\uC0C1\uC678 \uB3D9\uC791 | \`.context/templates/gotcha.md\` | \`gotcha-\uB77C\uC774\uBE0C\uB7EC\uB9AC-\uC81C\uBAA9.md\` |
334
+ | \uC791\uC740 \uAE30\uC220\uC801 \uC120\uD0DD | \`.context/templates/decision.md\` | \`decision-\uC81C\uBAA9.md\` |
335
+ | \uBAA8\uB4C8/\uD504\uB85C\uC81D\uD2B8 \uAC1C\uC694 \uD544\uC694 | \`.context/templates/context.md\` | \`context-\uC81C\uBAA9.md\` |
336
+ | \uBC18\uBCF5 \uAC00\uB2A5\uD55C \uD504\uB85C\uC138\uC2A4 \uC815\uB9BD | \`.context/templates/runbook.md\` | \`runbook-\uC81C\uBAA9.md\` |
337
+ | \uC2E4\uD5D8/\uB514\uBC84\uAE45 \uC911 \uD559\uC2B5 | \`.context/templates/insight.md\` | \`insight-\uC81C\uBAA9.md\` |
338
+
339
+ - [ ] \uC0C8\uB85C \uC791\uC131\uD55C \uB178\uD2B8\uB294 \uACE0\uB9BD\uB418\uC9C0 \uC54A\uB3C4\uB85D \uBC18\uB4DC\uC2DC \uAE30\uC874 \uAD00\uB828 \uB178\uD2B8\uB098 \`INDEX.md\`\uC640 \`[[wikilink]]\`\uB85C \uC591\uBC29\uD5A5 \uC5F0\uACB0\uD558\uC138\uC694.
340
+ - [ ] **\uC9C0\uC2DD \uC815\uB9AC \uBC0F \uC720\uC9C0\uBCF4\uC218 \uC6CC\uD06C\uD50C\uB85C\uC6B0:**
341
+ - [ ] **\uBD88\uD544\uC694\uD574\uC9C4 \uC9C0\uC2DD \uC81C\uAC70**: \uB354 \uC774\uC0C1 \uC720\uD6A8\uD558\uC9C0 \uC54A\uAC70\uB098 \uC798\uBABB\uB41C \uC815\uBCF4\uAC00 \uB2F4\uAE34 \uACFC\uAC70 \uB178\uD2B8\uB294 \uACFC\uAC10\uD788 \uC0AD\uC81C\uD558\uAC70\uB098 \uC0C1\uB2E8\uC5D0 Deprecated \uD45C\uC2DC\uB97C \uD558\uC5EC \uD63C\uB780\uC744 \uBC29\uC9C0\uD558\uC138\uC694.
342
+ - [ ] **\uC911\uBCF5 \uB178\uD2B8 \uD569\uBCD1(Merge)**: \uBE44\uC2B7\uD55C \uC8FC\uC81C\uB97C \uB2E4\uB8E8\uB294 \uC5EC\uB7EC \uAC1C\uC758 \uB178\uD2B8(redundant notes)\uAC00 \uBC1C\uACAC\uB418\uBA74, \uD558\uB098\uC758 \uD575\uC2EC \uB178\uD2B8\uB85C \uB0B4\uC6A9\uC744 \uD1B5\uD569\uD558\uACE0 \uB098\uBA38\uC9C0 \uB178\uD2B8\uB294 \uC0AD\uC81C\uD558\uC138\uC694.
343
+ - [ ] **\uC5F0\uACB0\uC131 \uC810\uAC80**: \uC9C0\uC2DD\uC744 \uAC31\uC2E0\uD558\uAC70\uB098 \uD569\uBCD1\uD560 \uB54C \uB04A\uC5B4\uC9C4 \uB9C1\uD06C(Dead link)\uAC00 \uBC1C\uC0DD\uD558\uC9C0 \uC54A\uB3C4\uB85D, \uC774 \uB178\uD2B8\uB97C \uCC38\uC870\uD558\uB358 \uB2E4\uB978 \uB178\uD2B8\uB098 \`INDEX.md\`\uC758 \uB9C1\uD06C\uB4E4\uB3C4 \uD568\uAED8 \uC5C5\uB370\uC774\uD2B8\uD558\uC138\uC694.`;
344
+ var DEFAULT_SEARCH_GUIDE = `# \uB178\uD2B8/\uC2A4\uD0AC \uAC80\uC0C9 \uBC0F \uC77D\uAE30 \uAC00\uC774\uB4DC
345
+
346
+ - [ ] \uAD00\uB828 \uD0A4\uC6CC\uB4DC \uAC80\uC0C9
347
+ - [ ] INDEX.md \uD655\uC778
348
+ - [ ] \uAD00\uB828 \uB178\uD2B8 \uD0D0\uC0C9`;
349
+ var DEFAULT_QUALITY_CHECK_GUIDE = `# \uD004\uB9AC\uD2F0 \uAC80\uC99D \uAC00\uC774\uB4DC
350
+
351
+ - [ ] Lint/Format \uD655\uC778
352
+ - [ ] \uD14C\uC2A4\uD2B8 \uC2E4\uD589
353
+ - [ ] \uBE4C\uB4DC \uD655\uC778
354
+ - [ ] \uCF54\uB4DC \uB9AC\uBDF0 \uC694\uCCAD \uBC0F \uD1B5\uACFC`;
355
+ var DEFAULT_SCOPE_REVIEW_GUIDE = `# \uC791\uC5C5 \uACBD\uB85C \uB9AC\uBDF0 \uAC00\uC774\uB4DC
356
+
357
+ - [ ] \uD604\uC7AC \uC791\uC5C5 \uBC94\uC704 \uD655\uC778
358
+ - [ ] \uC2A4\uCF54\uD504 \uC774\uD0C8 \uC5EC\uBD80 \uAC80\uD1A0`;
359
+ var DEFAULT_COMMIT_GUIDE = `# \uCCB4\uD06C\uD3EC\uC778\uD2B8 \uCEE4\uBC0B \uAC00\uC774\uB4DC
360
+
361
+ - [ ] \uC791\uC5C5 \uB0B4\uC6A9 \uC2A4\uD14C\uC774\uC9D5
362
+ - [ ] \uC6D0\uC790\uC801 \uCEE4\uBC0B \uBA54\uC2DC\uC9C0 \uC791\uC131`;
363
+ var DEFAULT_COMPLETE_GUIDE = `# \uC791\uC5C5 \uC644\uB8CC \uAC00\uC774\uB4DC
364
+
365
+ - [ ] \uBAA8\uB4E0 \uCEE4\uBC0B \uBC0F \uD478\uC2DC \uC791\uC5C5 \uC644\uB8CC \uD6C4 \uC218\uD589\uD558\uC138\uC694.
366
+ - [ ] \uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8\uC5D0 \`.context/.work-complete\` \uD30C\uC77C\uC744 \uC0DD\uC131\uD558\uAC70\uB098 \uB36E\uC5B4\uC4F0\uC138\uC694.
367
+ - [ ] \uD30C\uC77C \uB0B4\uC6A9\uC740 \`.context/templates/work-complete.txt\` \uD15C\uD50C\uB9BF\uC744 \uBCF5\uC0AC\uD558\uC5EC \uC791\uC131\uD574\uC57C \uD569\uB2C8\uB2E4. (\uC815\uD655\uD788 \uC544\uB798 3\uC904 \uD615\uC2DD\uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4):
368
+ timestamp={{currentTimestamp}}
369
+ session_id={{sessionId}}
370
+ turn_id={{turnId}}
371
+ - [ ] \uC774 \uB3D9\uC791\uC740 \uC791\uC5C5 \uC644\uB8CC\uB97C \uC2DC\uC2A4\uD15C\uC5D0 \uC54C\uB9AC\uACE0 \uD504\uB86C\uD504\uD2B8 \uC8FC\uC785 \uB8E8\uD504\uB97C \uC885\uB8CC\uC2DC\uD0A4\uB294 \uD2B8\uB9AC\uAC70\uC785\uB2C8\uB2E4.`;
372
+ var GUIDE_FILES = {
373
+ "daily-note-guide.md": DEFAULT_DAILY_NOTE_GUIDE,
374
+ "note-guide.md": DEFAULT_NOTE_GUIDE,
375
+ "search-guide.md": DEFAULT_SEARCH_GUIDE,
376
+ "quality-check.md": DEFAULT_QUALITY_CHECK_GUIDE,
377
+ "scope-review.md": DEFAULT_SCOPE_REVIEW_GUIDE,
378
+ "commit-guide.md": DEFAULT_COMMIT_GUIDE,
379
+ "complete-guide.md": DEFAULT_COMPLETE_GUIDE
380
+ };
381
+ var TEMPLATE_FILES = {
382
+ "adr.md": DEFAULT_ADR_TEMPLATE,
383
+ "pattern.md": DEFAULT_PATTERN_TEMPLATE,
384
+ "bug.md": DEFAULT_BUG_TEMPLATE,
385
+ "gotcha.md": DEFAULT_GOTCHA_TEMPLATE,
386
+ "decision.md": DEFAULT_DECISION_TEMPLATE,
387
+ "context.md": DEFAULT_CONTEXT_TEMPLATE,
388
+ "runbook.md": DEFAULT_RUNBOOK_TEMPLATE,
389
+ "insight.md": DEFAULT_INSIGHT_TEMPLATE,
390
+ "index.md": DEFAULT_INDEX_TEMPLATE,
391
+ "work-complete.txt": DEFAULT_WORK_COMPLETE_TEMPLATE
392
+ };
393
+ function scaffoldIfNeeded(projectDir) {
394
+ const contextDir = join2(projectDir, resolveContextDir(projectDir));
395
+ if (existsSync2(contextDir)) {
396
+ return false;
397
+ }
398
+ try {
399
+ const templatesDir = join2(contextDir, "templates");
400
+ mkdirSync(templatesDir, { recursive: true });
401
+ const guidesDir = join2(contextDir, "guides");
402
+ mkdirSync(guidesDir, { recursive: true });
403
+ writeFileSync(join2(contextDir, "config.jsonc"), DEFAULT_CONFIG, "utf-8");
404
+ for (const [filename, content] of Object.entries(TEMPLATE_FILES)) {
405
+ writeFileSync(join2(templatesDir, filename), content, "utf-8");
406
+ }
407
+ for (const [filename, content] of Object.entries(GUIDE_FILES)) {
408
+ writeFileSync(join2(guidesDir, filename), content, "utf-8");
409
+ }
410
+ writeVersion(contextDir, PLUGIN_VERSION);
411
+ return true;
412
+ } catch {
413
+ return false;
414
+ }
415
+ }
416
+ function writeVersion(contextDir, version) {
417
+ writeFileSync(join2(contextDir, ".version"), version, "utf-8");
418
+ }
419
+
420
+ // src/shared/agents-md.ts
421
+ import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync2, renameSync, writeFileSync as writeFileSync2 } from "fs";
422
+ import { dirname } from "path";
423
+ var START_MARKER = "<!-- context:start -->";
424
+ var END_MARKER = "<!-- context:end -->";
425
+ function renderMarkerBlock(content, trailingNewline) {
426
+ const block = `${START_MARKER}
427
+ ${content}
428
+ ${END_MARKER}`;
429
+ if (trailingNewline) {
430
+ return `${block}
431
+ `;
432
+ }
433
+ return block;
434
+ }
435
+ function appendMarkerBlock(existingContent, content) {
436
+ if (existingContent.length === 0) {
437
+ return renderMarkerBlock(content, true);
438
+ }
439
+ const separator = existingContent.endsWith(`
440
+ `) ? `
441
+ ` : `
442
+
443
+ `;
444
+ return `${existingContent}${separator}${renderMarkerBlock(content, true)}`;
445
+ }
446
+ function replaceMarkerBlock(existingContent, content) {
447
+ const startIndex = existingContent.indexOf(START_MARKER);
448
+ const endIndex = existingContent.indexOf(END_MARKER, startIndex + START_MARKER.length);
449
+ if (startIndex === -1 || endIndex === -1 || endIndex < startIndex) {
450
+ return appendMarkerBlock(existingContent, content);
451
+ }
452
+ const before = existingContent.slice(0, startIndex);
453
+ const after = existingContent.slice(endIndex + END_MARKER.length);
454
+ const replacement = renderMarkerBlock(content, false);
455
+ return `${before}${replacement}${after}`;
456
+ }
457
+ function writeFileAtomically(filePath, content) {
458
+ const tempPath = `${filePath}.tmp`;
459
+ writeFileSync2(tempPath, content, "utf-8");
460
+ renameSync(tempPath, filePath);
461
+ }
462
+ function injectIntoAgentsMd(agentsMdPath, content) {
463
+ mkdirSync2(dirname(agentsMdPath), { recursive: true });
464
+ if (!existsSync3(agentsMdPath)) {
465
+ writeFileAtomically(agentsMdPath, renderMarkerBlock(content, true));
466
+ return;
467
+ }
468
+ const existingContent = readFileSync2(agentsMdPath, "utf-8");
469
+ const nextContent = existingContent.includes(START_MARKER) && existingContent.includes(END_MARKER) ? replaceMarkerBlock(existingContent, content) : appendMarkerBlock(existingContent, content);
470
+ writeFileAtomically(agentsMdPath, nextContent);
471
+ }
472
+
473
+ // src/shared/knowledge-context.ts
474
+ var STATIC_KNOWLEDGE_CONTEXT = `## Knowledge Context
475
+
476
+ \uC774 \uD504\uB85C\uC81D\uD2B8\uB294 **\uC81C\uD154\uCE74\uC2A4\uD150(Zettelkasten)** \uBC29\uC2DD\uC73C\uB85C \uC9C0\uC2DD\uC744 \uAD00\uB9AC\uD569\uB2C8\uB2E4.
477
+ \uC138\uC158 \uAC04 \uCEE8\uD14D\uC2A4\uD2B8\uB97C \uBCF4\uC874\uD558\uC5EC, \uC774\uC804 \uC138\uC158\uC758 \uACB0\uC815/\uD328\uD134/\uC2E4\uC218\uAC00 \uB2E4\uC74C \uC138\uC158\uC5D0\uC11C \uC7AC\uD65C\uC6A9\uB429\uB2C8\uB2E4.
478
+
479
+ ### \uC81C\uD154\uCE74\uC2A4\uD150 \uD575\uC2EC \uC6D0\uCE59
480
+ 1. **\uC6D0\uC790\uC131** -- \uD558\uB098\uC758 \uB178\uD2B8 = \uD558\uB098\uC758 \uC8FC\uC81C. \uC5EC\uB7EC \uC8FC\uC81C\uB97C \uC11E\uC9C0 \uB9C8\uC138\uC694.
481
+ 2. **\uC5F0\uACB0** -- \uBAA8\uB4E0 \uB178\uD2B8\uB294 [[wikilink]]\uB85C \uAD00\uB828 \uB178\uD2B8\uC5D0 \uC5F0\uACB0. \uACE0\uB9BD\uB41C \uB178\uD2B8\uB294 \uBC1C\uACAC\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.
482
+ 3. **\uC790\uAE30 \uC5B8\uC5B4** -- \uBCF5\uC0AC-\uBD99\uC5EC\uB123\uAE30\uAC00 \uC544\uB2CC, \uD575\uC2EC\uC744 \uC774\uD574\uD558\uACE0 \uAC04\uACB0\uD558\uAC8C \uC11C\uC220\uD558\uC138\uC694.
483
+
484
+ ### MCP Tools
485
+ - **\uC9C0\uC2DD \uAD00\uB9AC**: \`context_mcp_search_knowledge\`, \`context_mcp_read_knowledge\`, \`context_mcp_create_knowledge_note\`, \`context_mcp_update_knowledge_note\`
486
+ - **\uB370\uC77C\uB9AC \uB178\uD2B8**: \`context_mcp_read_daily_note\`, \`context_mcp_append_daily_note\`
487
+ - **\uC791\uC5C5 \uC644\uB8CC**: \`context_mcp_submit_turn_complete\` (\uC791\uC5C5 \uC885\uB8CC \uC2DC \uD544\uC218 \uD638\uCD9C)
488
+
489
+ ### \uC791\uC5C5 \uC804 \uD544\uC218
490
+ - **\uB370\uC77C\uB9AC \uB178\uD2B8 \uD655\uC778**: \uAC00\uC7A5 \uCD5C\uADFC\uC758 \uB370\uC77C\uB9AC \uB178\uD2B8\uB97C \uC77D\uACE0 \uC774\uC804 \uC138\uC158\uC758 \uCEE8\uD14D\uC2A4\uD2B8\uC640 \uBBF8\uD574\uACB0 \uC774\uC288\uB97C \uD30C\uC545\uD558\uC138\uC694.
491
+ - **\uC791\uC5C5 \uC758\uB3C4 \uC120\uC5B8**: \uC791\uC5C5 \uC2DC\uC791 \uC804, \uD604\uC7AC \uC138\uC158\uC758 \uBAA9\uD45C\uC640 \uC791\uC5C5 \uC758\uB3C4\uB97C \uBA85\uD655\uD788 \uD30C\uC545\uD558\uACE0 \uC120\uC5B8\uD558\uC138\uC694.
492
+ - **\uC9C0\uC2DD \uAC80\uC0C9**: \uC791\uC5C5\uACFC \uAD00\uB828\uB41C \uBB38\uC11C\uB97C **\uC9C1\uC811 \uBA3C\uC800** \uAC80\uC0C9\uD558\uACE0 \uC77D\uC73C\uC138\uC694.
493
+ - \uC9C0\uC2DD \uD30C\uC77C\uC5D0 \uAE30\uB85D\uB41C \uC544\uD0A4\uD14D\uCC98 \uACB0\uC815, \uD328\uD134, \uC81C\uC57D\uC0AC\uD56D\uC744 \uBC18\uB4DC\uC2DC \uB530\uB974\uC138\uC694.
494
+
495
+ ### \uAC1C\uBC1C \uC6D0\uCE59
496
+ - **TDD** (Test-Driven Development): \uD14C\uC2A4\uD2B8\uB97C \uBA3C\uC800 \uC791\uC131\uD558\uACE0(RED), \uAD6C\uD604\uD558\uC5EC \uD1B5\uACFC\uC2DC\uD0A8 \uB4A4(GREEN), \uB9AC\uD329\uD1A0\uB9C1\uD558\uC138\uC694.
497
+ - **DDD** (Domain-Driven Design): \uB3C4\uBA54\uC778 \uAC1C\uB150\uC744 \uCF54\uB4DC \uAD6C\uC870\uC5D0 \uBC18\uC601\uD558\uC138\uC694.
498
+ - **\uD14C\uC2A4\uD2B8 \uCEE4\uBC84\uB9AC\uC9C0**: \uC0C8\uB85C \uC791\uC131\uD558\uAC70\uB098 \uBCC0\uACBD\uD55C \uCF54\uB4DC\uB294 \uD14C\uC2A4\uD2B8 \uCEE4\uBC84\uB9AC\uC9C0 80% \uC774\uC0C1\uC744 \uBAA9\uD45C\uB85C \uD558\uC138\uC694.
499
+
500
+ ### \uC6B0\uC120\uC21C\uC704
501
+ - AGENTS.md\uC758 \uC9C0\uC2DC\uC0AC\uD56D\uC774 \uD56D\uC0C1 \uCD5C\uC6B0\uC120
502
+ - \uC9C0\uC2DD \uB178\uD2B8\uC758 \uACB0\uC815\uC0AC\uD56D > \uC77C\uBC18\uC801 \uAD00\uD589
503
+ - \uC9C0\uC2DD \uB178\uD2B8\uC5D0 \uC5C6\uB294 \uC0C8\uB85C\uC6B4 \uACB0\uC815\uC774\uB098 \uBC18\uBCF5 \uAC00\uCE58\uAC00 \uC788\uB294 \uBC1C\uACAC\uC740 \uC791\uC5C5 \uBA54\uBAA8\uB098 \uC9C0\uC2DD \uB178\uD2B8 \uD6C4\uBCF4\uB85C \uAE30\uB85D\uD558\uC138\uC694.
504
+
505
+ ### \uC791\uC5C5 \uC644\uB8CC \uD504\uB85C\uD1A0\uCF5C
506
+ - **\uD544\uC218**: \uBAA8\uB4E0 \uC791\uC5C5\uC774 \uC644\uB8CC\uB418\uBA74 \uBC18\uB4DC\uC2DC \`context-mcp\` MCP \uC11C\uBC84\uC758 \`submit_turn_complete\` \uB3C4\uAD6C\uB97C \uD638\uCD9C\uD558\uC138\uC694.
507
+ - \uC774 \uD638\uCD9C \uC5C6\uC774 \uC138\uC158\uC744 \uC885\uB8CC\uD558\uBA74 \uC791\uC5C5 \uAE30\uB85D\uC774 \uBCF4\uC874\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.
508
+ - \uD544\uC694\uD55C \uC778\uC790: daily_note_update_proof, knowledge_note_proof, quality_check_output, checkpoint_commit_hashes, scope_review_notes`;
509
+
510
+ // src/omc/session-start-hook.ts
511
+ import { join as join3 } from "path";
512
+ var projectDir = process.env.CLAUDE_PROJECT_DIR ?? process.cwd();
513
+ scaffoldIfNeeded(projectDir);
514
+ injectIntoAgentsMd(join3(projectDir, "AGENTS.md"), STATIC_KNOWLEDGE_CONTEXT);
@@ -0,0 +1,40 @@
1
+ // @bun
2
+ // src/omc/stop-hook.ts
3
+ import { existsSync, statSync, unlinkSync } from "fs";
4
+ import { join } from "path";
5
+
6
+ // src/constants.ts
7
+ var DEFAULTS = {
8
+ configPath: ".context/config.jsonc",
9
+ knowledgeSources: ["AGENTS.md"],
10
+ templateDir: ".context/templates",
11
+ indexFilename: "INDEX.md",
12
+ maxDomainDepth: 2,
13
+ knowledgeDir: "docs",
14
+ guidesDir: ".context/guides",
15
+ workCompleteFile: ".context/.work-complete"
16
+ };
17
+ var LIMITS = {
18
+ maxPromptFileSize: 64 * 1024,
19
+ maxIndexEntries: 100,
20
+ maxTotalInjectionSize: 128 * 1024,
21
+ maxScanDepth: 3,
22
+ maxSummaryLength: 100,
23
+ maxIndexFileSize: 32 * 1024
24
+ };
25
+
26
+ // src/omc/stop-hook.ts
27
+ var projectDir = process.env.CLAUDE_PROJECT_DIR ?? process.cwd();
28
+ var workCompleteFile = join(projectDir, DEFAULTS.workCompleteFile);
29
+ if (!existsSync(workCompleteFile)) {
30
+ process.stderr.write(`[context] Warning: Session ended without submit_turn_complete. Work may not be recorded in daily notes.
31
+ `);
32
+ process.exit(0);
33
+ }
34
+ try {
35
+ const stat = statSync(workCompleteFile);
36
+ const ageMs = Date.now() - stat.mtimeMs;
37
+ if (ageMs > 24 * 60 * 60 * 1000) {
38
+ unlinkSync(workCompleteFile);
39
+ }
40
+ } catch {}