@ksm0709/context 0.0.18 → 0.0.20

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 CHANGED
@@ -8,6 +8,10 @@ Context plugin for Bun
8
8
 
9
9
  <!-- Example usage code goes here -->
10
10
 
11
+ ## OMX Support
12
+
13
+ This plugin supports OMX (OpenCode Managed eXtension). See [[docs/omx-setup.md]] for setup instructions.
14
+
11
15
  ## Installation
12
16
 
13
17
  <!-- Installation instructions go here -->
package/dist/cli/index.js CHANGED
@@ -2,24 +2,25 @@
2
2
  // @bun
3
3
 
4
4
  // src/cli/commands/update.ts
5
- import { resolve, join as join2 } from "path";
6
- import { existsSync as existsSync2 } from "fs";
5
+ import { resolve, join as join3 } from "path";
6
+ import { existsSync as existsSync3 } from "fs";
7
7
  import { homedir } from "os";
8
8
 
9
9
  // src/lib/scaffold.ts
10
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
11
- import { join } from "path";
10
+ import { existsSync as existsSync2, mkdirSync, readFileSync, writeFileSync } from "fs";
11
+ import { join as join2 } from "path";
12
12
 
13
13
  // src/constants.ts
14
14
  var DEFAULTS = {
15
- configPath: ".opencode/context/config.jsonc",
16
- promptDir: ".opencode/context/prompts",
15
+ configPath: ".context/config.jsonc",
16
+ promptDir: ".context/prompts",
17
17
  turnStartFile: "turn-start.md",
18
18
  turnEndFile: "turn-end.md",
19
19
  knowledgeSources: ["AGENTS.md"],
20
- templateDir: ".opencode/context/templates",
20
+ templateDir: ".context/templates",
21
21
  indexFilename: "INDEX.md",
22
- maxDomainDepth: 2
22
+ maxDomainDepth: 2,
23
+ knowledgeDir: "docs"
23
24
  };
24
25
  var LIMITS = {
25
26
  maxPromptFileSize: 64 * 1024,
@@ -29,10 +30,25 @@ var LIMITS = {
29
30
  maxSummaryLength: 100,
30
31
  maxIndexFileSize: 32 * 1024
31
32
  };
33
+
34
+ // src/lib/context-dir.ts
35
+ import { existsSync } from "fs";
36
+ import { join } from "path";
37
+ function resolveContextDir(projectDir) {
38
+ const nextContextDir = ".context";
39
+ if (existsSync(join(projectDir, nextContextDir))) {
40
+ return nextContextDir;
41
+ }
42
+ const legacyContextDir = ".opencode/context";
43
+ if (existsSync(join(projectDir, legacyContextDir))) {
44
+ return legacyContextDir;
45
+ }
46
+ return nextContextDir;
47
+ }
32
48
  // package.json
33
49
  var package_default = {
34
50
  name: "@ksm0709/context",
35
- version: "0.0.18",
51
+ version: "0.0.20",
36
52
  author: {
37
53
  name: "TaehoKang",
38
54
  email: "ksm07091@gmail.com"
@@ -40,27 +56,32 @@ var package_default = {
40
56
  type: "module",
41
57
  main: "./dist/index.js",
42
58
  bin: {
43
- context: "./dist/cli/index.js"
59
+ context: "dist/cli/index.js"
44
60
  },
45
61
  exports: {
46
62
  ".": {
47
63
  import: "./dist/index.js",
48
64
  types: "./dist/index.d.ts",
49
65
  default: "./dist/index.js"
66
+ },
67
+ "./omx": {
68
+ import: "./dist/omx/index.mjs",
69
+ types: "./dist/omx/index.d.ts",
70
+ default: "./dist/omx/index.mjs"
50
71
  }
51
72
  },
52
73
  repository: {
53
74
  type: "git",
54
- url: "git@github.com:ksm0709/context.git"
75
+ url: "git+ssh://git@github.com/ksm0709/context.git"
55
76
  },
56
77
  publishConfig: {
57
78
  access: "public"
58
79
  },
59
80
  scripts: {
60
- build: "bun build ./src/index.ts --outdir dist --target bun && bun build ./src/cli/index.ts --outdir dist/cli --target bun",
81
+ build: "bun build ./src/index.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
82
  test: "vitest run",
62
83
  lint: "eslint src --ext .ts",
63
- prepublishOnly: "bun build ./src/index.ts --outdir dist --target bun && bun build ./src/cli/index.ts --outdir dist/cli --target bun"
84
+ prepublishOnly: "bun build ./src/index.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"
64
85
  },
65
86
  files: [
66
87
  "dist"
@@ -69,7 +90,6 @@ var package_default = {
69
90
  "@opencode-ai/plugin": ">=1.0.0"
70
91
  },
71
92
  dependencies: {
72
- "@ksm0709/context": "^0.0.17",
73
93
  "jsonc-parser": "^3.0.0"
74
94
  },
75
95
  devDependencies: {
@@ -95,12 +115,18 @@ var DEFAULT_CONFIG = `{
95
115
  // Context Plugin Configuration
96
116
  // See: https://github.com/ksm0709/context
97
117
  "prompts": {
98
- "turnStart": ".opencode/context/prompts/turn-start.md",
99
- "turnEnd": ".opencode/context/prompts/turn-end.md"
118
+ "turnStart": "prompts/turn-start.md",
119
+ "turnEnd": "prompts/turn-end.md"
100
120
  },
101
121
  "knowledge": {
102
122
  "dir": "docs",
103
123
  "sources": ["AGENTS.md"]
124
+ },
125
+ "omx": {
126
+ // Inject turn-end after native turn-complete via tmux send-keys
127
+ "turnEnd": {
128
+ "strategy": "turn-complete-sendkeys"
129
+ }
104
130
  }
105
131
  }`;
106
132
  var DEFAULT_TURN_START = `## Knowledge Context
@@ -154,21 +180,21 @@ var DEFAULT_TURN_END = `## \uC791\uC5C5 \uB9C8\uBB34\uB9AC
154
180
 
155
181
  | \uC0C1\uD669 | \uD15C\uD50C\uB9BF | \uD30C\uC77C\uBA85 \uD328\uD134 |
156
182
  | ------------------------------- | --------------------------------------------------- | --------------------------- |
157
- | \uC544\uD0A4\uD14D\uCC98/\uAE30\uC220 \uC2A4\uD0DD \uC911\uB300 \uACB0\uC815 | [ADR](.opencode/context/templates/adr.md) | \`adr-NNN-\uC81C\uBAA9.md\` |
158
- | \uBC18\uBCF5 \uC0AC\uC6A9\uD560 \uCF54\uB4DC \uD328\uD134 \uBC1C\uACAC | [Pattern](.opencode/context/templates/pattern.md) | \`pattern-\uC81C\uBAA9.md\` |
159
- | \uBE44\uC790\uBA85\uD55C \uBC84\uADF8 \uD574\uACB0 | [Bug](.opencode/context/templates/bug.md) | \`bug-\uC81C\uBAA9.md\` |
160
- | \uC678\uBD80 API/\uB77C\uC774\uBE0C\uB7EC\uB9AC \uC608\uC0C1\uC678 \uB3D9\uC791 | [Gotcha](.opencode/context/templates/gotcha.md) | \`gotcha-\uB77C\uC774\uBE0C\uB7EC\uB9AC-\uC81C\uBAA9.md\` |
161
- | \uC791\uC740 \uAE30\uC220\uC801 \uC120\uD0DD | [Decision](.opencode/context/templates/decision.md) | \`decision-\uC81C\uBAA9.md\` |
162
- | \uBAA8\uB4C8/\uD504\uB85C\uC81D\uD2B8 \uAC1C\uC694 \uD544\uC694 | [Context](.opencode/context/templates/context.md) | \`context-\uC81C\uBAA9.md\` |
163
- | \uBC18\uBCF5 \uAC00\uB2A5\uD55C \uD504\uB85C\uC138\uC2A4 \uC815\uB9BD | [Runbook](.opencode/context/templates/runbook.md) | \`runbook-\uC81C\uBAA9.md\` |
164
- | \uC2E4\uD5D8/\uB514\uBC84\uAE45 \uC911 \uD559\uC2B5 | [Insight](.opencode/context/templates/insight.md) | \`insight-\uC81C\uBAA9.md\` |
183
+ | \uC544\uD0A4\uD14D\uCC98/\uAE30\uC220 \uC2A4\uD0DD \uC911\uB300 \uACB0\uC815 | [ADR](.context/templates/adr.md) | \`adr-NNN-\uC81C\uBAA9.md\` |
184
+ | \uBC18\uBCF5 \uC0AC\uC6A9\uD560 \uCF54\uB4DC \uD328\uD134 \uBC1C\uACAC | [Pattern](.context/templates/pattern.md) | \`pattern-\uC81C\uBAA9.md\` |
185
+ | \uBE44\uC790\uBA85\uD55C \uBC84\uADF8 \uD574\uACB0 | [Bug](.context/templates/bug.md) | \`bug-\uC81C\uBAA9.md\` |
186
+ | \uC678\uBD80 API/\uB77C\uC774\uBE0C\uB7EC\uB9AC \uC608\uC0C1\uC678 \uB3D9\uC791 | [Gotcha](.context/templates/gotcha.md) | \`gotcha-\uB77C\uC774\uBE0C\uB7EC\uB9AC-\uC81C\uBAA9.md\` |
187
+ | \uC791\uC740 \uAE30\uC220\uC801 \uC120\uD0DD | [Decision](.context/templates/decision.md) | \`decision-\uC81C\uBAA9.md\` |
188
+ | \uBAA8\uB4C8/\uD504\uB85C\uC81D\uD2B8 \uAC1C\uC694 \uD544\uC694 | [Context](.context/templates/context.md) | \`context-\uC81C\uBAA9.md\` |
189
+ | \uBC18\uBCF5 \uAC00\uB2A5\uD55C \uD504\uB85C\uC138\uC2A4 \uC815\uB9BD | [Runbook](.context/templates/runbook.md) | \`runbook-\uC81C\uBAA9.md\` |
190
+ | \uC2E4\uD5D8/\uB514\uBC84\uAE45 \uC911 \uD559\uC2B5 | [Insight](.context/templates/insight.md) | \`insight-\uC81C\uBAA9.md\` |
165
191
 
166
192
  \uD574\uB2F9 \uC0AC\uD56D\uC774 \uC5C6\uC73C\uBA74 \uC774 \uB2E8\uACC4\uB294 \uAC74\uB108\uB6F0\uC138\uC694.
167
193
 
168
194
  - \uAD00\uB828 \uD15C\uD50C\uB9BF \uD30C\uC77C\uC744 \uC77D\uACE0 \uADF8 \uAD6C\uC870\uC5D0 \uB9DE\uCDB0 \uB0B4\uC6A9\uC744 \uC815\uB9AC\uD558\uC138\uC694
169
195
  - \uB178\uD2B8 \uCCAB \uC904\uC740 \uBA85\uD655\uD55C \uC81C\uBAA9(\`# Title\`)\uC73C\uB85C \uC2DC\uC791\uD558\uC138\uC694
170
196
  - \uD575\uC2EC \uB0B4\uC6A9\uC744 \uC790\uAE30 \uC5B8\uC5B4\uB85C \uAC04\uACB0\uD558\uAC8C \uC11C\uC220\uD558\uACE0, \uAD00\uB828 \uB178\uD2B8\uB294 \`[[relative/path/file.md]]\` \uD615\uD0DC\uB85C \uC5F0\uACB0\uD558\uC138\uC694
171
- - knowledge \uB514\uB809\uD1A0\uB9AC(\uAE30\uBCF8: \`docs/\`) \uB610\uB294 \uC801\uC808\uD55C \uB3C4\uBA54\uC778 \uD3F4\uB354\uC5D0 \uC800\uC7A5\uD558\uACE0, \uD544\uC694\uD55C \uACBD\uC6B0 \uAE30\uC874 INDEX.md\uB098 \uAD00\uB828 \uB178\uD2B8\uB97C \uD568\uAED8 \uAC31\uC2E0\uD558\uC138\uC694
197
+ - knowledge \uB514\uB809\uD1A0\uB9AC(\`{{knowledgeDir}}/\`) \uB610\uB294 \uC801\uC808\uD55C \uB3C4\uBA54\uC778 \uD3F4\uB354\uC5D0 \uC800\uC7A5\uD558\uACE0, \uD544\uC694\uD55C \uACBD\uC6B0 \uAE30\uC874 INDEX.md\uB098 \uAD00\uB828 \uB178\uD2B8\uB97C \uD568\uAED8 \uAC31\uC2E0\uD558\uC138\uC694
172
198
 
173
199
  \uAE30\uC874 \uC124\uCE58\uC758 \uC0AC\uC6A9\uC790 \uD504\uB86C\uD504\uD2B8 \uD30C\uC77C\uC740 \uC790\uB3D9\uC73C\uB85C \uBC14\uB00C\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uC0C8 \uAE30\uBCF8 \uD504\uB86C\uD504\uD2B8\uAC00 \uD544\uC694\uD558\uBA74 \`context update prompt\`\uB85C \uBA85\uC2DC\uC801\uC73C\uB85C \uC0C8\uB85C\uACE0\uCE68\uD558\uC138\uC694.
174
200
  `;
@@ -390,9 +416,9 @@ var TEMPLATE_FILES = {
390
416
  "index.md": DEFAULT_INDEX_TEMPLATE
391
417
  };
392
418
  function updateScaffold(projectDir) {
393
- const contextDir = join(projectDir, ".opencode", "context");
394
- mkdirSync(join(contextDir, "prompts"), { recursive: true });
395
- mkdirSync(join(contextDir, "templates"), { recursive: true });
419
+ const contextDir = join2(projectDir, resolveContextDir(projectDir));
420
+ mkdirSync(join2(contextDir, "prompts"), { recursive: true });
421
+ mkdirSync(join2(contextDir, "templates"), { recursive: true });
396
422
  const templateEntries = Object.fromEntries(Object.entries(TEMPLATE_FILES).map(([filename, content]) => [`templates/${filename}`, content]));
397
423
  const templates = {
398
424
  "config.jsonc": DEFAULT_CONFIG,
@@ -402,7 +428,7 @@ function updateScaffold(projectDir) {
402
428
  };
403
429
  const updated = [];
404
430
  for (const [path, content] of Object.entries(templates)) {
405
- const filePath = join(contextDir, path);
431
+ const filePath = join2(contextDir, path);
406
432
  try {
407
433
  const existing = readFileSync(filePath, "utf-8");
408
434
  if (existing === content)
@@ -415,18 +441,18 @@ function updateScaffold(projectDir) {
415
441
  return updated;
416
442
  }
417
443
  function writeVersion(contextDir, version) {
418
- writeFileSync(join(contextDir, ".version"), version, "utf-8");
444
+ writeFileSync(join2(contextDir, ".version"), version, "utf-8");
419
445
  }
420
446
  function updatePrompts(projectDir) {
421
- const contextDir = join(projectDir, ".opencode", "context");
422
- mkdirSync(join(contextDir, "prompts"), { recursive: true });
447
+ const contextDir = join2(projectDir, resolveContextDir(projectDir));
448
+ mkdirSync(join2(contextDir, "prompts"), { recursive: true });
423
449
  const prompts = {
424
450
  [`prompts/${DEFAULTS.turnStartFile}`]: DEFAULT_TURN_START,
425
451
  [`prompts/${DEFAULTS.turnEndFile}`]: DEFAULT_TURN_END
426
452
  };
427
453
  const updated = [];
428
454
  for (const [path, content] of Object.entries(prompts)) {
429
- const filePath = join(contextDir, path);
455
+ const filePath = join2(contextDir, path);
430
456
  try {
431
457
  const existing = readFileSync(filePath, "utf-8");
432
458
  if (existing === content)
@@ -493,20 +519,20 @@ function runUpdatePrompt(projectDir) {
493
519
  }
494
520
  }
495
521
  function detectPackageManager() {
496
- if (existsSync2("bun.lock") || existsSync2("bun.lockb"))
522
+ if (existsSync3("bun.lock") || existsSync3("bun.lockb"))
497
523
  return "bun";
498
- if (existsSync2("pnpm-lock.yaml"))
524
+ if (existsSync3("pnpm-lock.yaml"))
499
525
  return "pnpm";
500
- if (existsSync2("yarn.lock"))
526
+ if (existsSync3("yarn.lock"))
501
527
  return "yarn";
502
- if (existsSync2("package-lock.json"))
528
+ if (existsSync3("package-lock.json"))
503
529
  return "npm";
504
530
  return "bun";
505
531
  }
506
532
  function detectGlobalInstalls() {
507
533
  const installs = [];
508
- const bunGlobalBin = join2(homedir(), ".bun", "bin", "context");
509
- if (existsSync2(bunGlobalBin)) {
534
+ const bunGlobalBin = join3(homedir(), ".bun", "bin", "context");
535
+ if (existsSync3(bunGlobalBin)) {
510
536
  installs.push({ pm: "bun", label: "bun global", installCmd: ["bun", "install", "-g"] });
511
537
  }
512
538
  const spawnSync = globalThis.Bun?.spawnSync;
@@ -558,6 +584,108 @@ function runUpdatePlugin(version) {
558
584
  `);
559
585
  }
560
586
 
587
+ // src/cli/commands/migrate.ts
588
+ import { resolve as resolve2, join as join4 } from "path";
589
+ import { existsSync as existsSync4, cpSync, rmSync, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
590
+ var LEGACY_CONTEXT_DIR = ".opencode/context";
591
+ var NEW_CONTEXT_DIR = ".context";
592
+ function runMigrate(args) {
593
+ const keepFlag = args.includes("--keep");
594
+ const pathArg = args.find((a) => !a.startsWith("--"));
595
+ const projectDir = resolve2(pathArg ?? process.cwd());
596
+ const legacyDir = join4(projectDir, LEGACY_CONTEXT_DIR);
597
+ const newDir = join4(projectDir, NEW_CONTEXT_DIR);
598
+ if (!existsSync4(legacyDir)) {
599
+ process.stdout.write(`Nothing to migrate.
600
+ `);
601
+ return;
602
+ }
603
+ if (existsSync4(newDir)) {
604
+ process.stderr.write(`Target .context/ already exists. Aborting.
605
+ `);
606
+ process.exit(1);
607
+ return;
608
+ }
609
+ cpSync(legacyDir, newDir, { recursive: true });
610
+ updateConfigPaths(newDir);
611
+ if (!keepFlag) {
612
+ rmSync(legacyDir, { recursive: true, force: true });
613
+ }
614
+ process.stdout.write(`Migrated .opencode/context/ \u2192 .context/
615
+ `);
616
+ }
617
+ function updateConfigPaths(contextDir) {
618
+ const configPath = join4(contextDir, "config.jsonc");
619
+ if (!existsSync4(configPath))
620
+ return;
621
+ try {
622
+ const content = readFileSync2(configPath, "utf-8");
623
+ const updated = content.replaceAll(".opencode/context/", "");
624
+ if (updated !== content) {
625
+ writeFileSync2(configPath, updated, "utf-8");
626
+ }
627
+ } catch {}
628
+ }
629
+
630
+ // src/cli/commands/install.ts
631
+ import { join as join5, resolve as resolve3, dirname } from "path";
632
+ import { existsSync as existsSync5, mkdirSync as mkdirSync2, copyFileSync } from "fs";
633
+ import { fileURLToPath } from "url";
634
+ import { createRequire } from "module";
635
+ function resolveOmxSource() {
636
+ try {
637
+ const cliDir = dirname(fileURLToPath(import.meta.url));
638
+ const pkgRoot = resolve3(cliDir, "..", "..");
639
+ const source = join5(pkgRoot, "dist", "omx", "index.mjs");
640
+ if (existsSync5(source))
641
+ return source;
642
+ } catch {}
643
+ try {
644
+ const req = createRequire(import.meta.url);
645
+ return req.resolve("@ksm0709/context/omx");
646
+ } catch {
647
+ return null;
648
+ }
649
+ }
650
+ function installOmx(projectDir, sourcePath) {
651
+ if (!existsSync5(sourcePath)) {
652
+ process.stderr.write(`Could not find OMX plugin source file: ${sourcePath}
653
+ `);
654
+ process.exit(1);
655
+ return;
656
+ }
657
+ const targetDir = join5(projectDir, ".omx", "hooks");
658
+ mkdirSync2(targetDir, { recursive: true });
659
+ copyFileSync(sourcePath, join5(targetDir, "context.mjs"));
660
+ process.stdout.write(`Installed context plugin to .omx/hooks/context.mjs
661
+ `);
662
+ }
663
+ function runInstall(args) {
664
+ const [subcommand] = args;
665
+ switch (subcommand) {
666
+ case "omx": {
667
+ const source = resolveOmxSource();
668
+ if (!source) {
669
+ process.stderr.write(`Could not find OMX plugin source file (dist/omx/index.mjs).
670
+ `);
671
+ process.exit(1);
672
+ return;
673
+ }
674
+ installOmx(process.cwd(), source);
675
+ break;
676
+ }
677
+ case undefined:
678
+ process.stderr.write(`Missing install target. Usage: context install omx
679
+ `);
680
+ process.exit(1);
681
+ break;
682
+ default:
683
+ process.stderr.write(`Unknown install target: ${subcommand}
684
+ `);
685
+ process.exit(1);
686
+ }
687
+ }
688
+
561
689
  // src/cli/index.ts
562
690
  var PLUGIN_VERSION2 = package_default.version;
563
691
  function printHelp(out) {
@@ -575,6 +703,10 @@ function printHelp(out) {
575
703
  write(` update prompt [path] Force-update prompt files only
576
704
  `);
577
705
  write(` update plugin [version] Update @ksm0709/context package
706
+ `);
707
+ write(` migrate [path] [--keep] Migrate .opencode/context/ \u2192 .context/
708
+ `);
709
+ write(` install omx Install OMX hook plugin to .omx/hooks/
578
710
  `);
579
711
  write(`
580
712
  `);
@@ -589,6 +721,12 @@ function runCli(argv) {
589
721
  case "update":
590
722
  runUpdate(rest);
591
723
  break;
724
+ case "migrate":
725
+ runMigrate(rest);
726
+ break;
727
+ case "install":
728
+ runInstall(rest);
729
+ break;
592
730
  case "--version":
593
731
  case "-v":
594
732
  process.stdout.write(`${PLUGIN_VERSION2}