@ksm0709/context 0.0.12 → 0.0.14

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 CHANGED
@@ -2,8 +2,9 @@
2
2
  // @bun
3
3
 
4
4
  // src/cli/commands/update.ts
5
- import { resolve } from "path";
5
+ import { resolve, join as join2 } from "path";
6
6
  import { existsSync as existsSync2 } from "fs";
7
+ import { homedir } from "os";
7
8
 
8
9
  // src/lib/scaffold.ts
9
10
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
@@ -15,8 +16,9 @@ var DEFAULTS = {
15
16
  promptDir: ".opencode/context/prompts",
16
17
  turnStartFile: "turn-start.md",
17
18
  turnEndFile: "turn-end.md",
19
+ subagentTurnEndFile: "subagent-turn-end.md",
20
+ blockedToolPatterns: ["^task$", "^background_", "agent"],
18
21
  knowledgeSources: ["AGENTS.md"],
19
- knowledgeDir: "docs",
20
22
  templateDir: ".opencode/context/templates",
21
23
  indexFilename: "INDEX.md",
22
24
  maxDomainDepth: 2
@@ -32,7 +34,7 @@ var LIMITS = {
32
34
  // package.json
33
35
  var package_default = {
34
36
  name: "@ksm0709/context",
35
- version: "0.0.12",
37
+ version: "0.0.14",
36
38
  author: {
37
39
  name: "TaehoKang",
38
40
  email: "ksm07091@gmail.com"
@@ -68,7 +70,7 @@ var package_default = {
68
70
  "@opencode-ai/plugin": ">=1.0.0"
69
71
  },
70
72
  dependencies: {
71
- "@ksm0709/context": "^0.0.11",
73
+ "@ksm0709/context": "^0.0.12",
72
74
  "jsonc-parser": "^3.0.0"
73
75
  },
74
76
  devDependencies: {
@@ -94,7 +96,11 @@ var DEFAULT_CONFIG = `{
94
96
  // See: https://github.com/ksm0709/context
95
97
  "prompts": {
96
98
  "turnStart": ".opencode/context/prompts/turn-start.md",
97
- "turnEnd": ".opencode/context/prompts/turn-end.md"
99
+ "turnEnd": ".opencode/context/prompts/turn-end.md",
100
+ "subagentTurnEnd": ".opencode/context/prompts/subagent-turn-end.md"
101
+ },
102
+ "subagentConfig": {
103
+ "blockedToolPatterns": ["^task$", "^background_", "agent"]
98
104
  },
99
105
  "knowledge": {
100
106
  "dir": "docs",
@@ -247,6 +253,13 @@ task(
247
253
  )
248
254
  \`\`\`
249
255
  `;
256
+ var DEFAULT_SUBAGENT_TURN_END = `<environment-constraints>
257
+ \uB2F9\uC2E0\uC740 \uD604\uC7AC \uBA54\uC778 \uC624\uCF00\uC2A4\uD2B8\uB808\uC774\uD130\uAC00 \uD638\uCD9C\uD55C **\uB9D0\uB2E8 \uC6CC\uCEE4(Worker) \uC5D0\uC774\uC804\uD2B8**\uC785\uB2C8\uB2E4.
258
+ \uD604\uC7AC \uB2F9\uC2E0\uC758 \uC2E4\uD589 \uD658\uACBD(Sandbox)\uC5D0\uC11C\uB294 \uB124\uD2B8\uC6CC\uD06C \uC790\uC6D0 \uBCF4\uD638\uB97C \uC704\uD574 **\uB2E4\uB978 \uC5D0\uC774\uC804\uD2B8\uB97C \uC0DD\uC131, \uD638\uCD9C, \uC704\uC784\uD558\uB294 \uBAA8\uB4E0 \uB3C4\uAD6C(\uC608: task, background_task \uB4F1)\uC758 \uAD8C\uD55C\uC774 \uC2DC\uC2A4\uD15C \uB808\uBCA8\uC5D0\uC11C \uD68C\uC218**\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
259
+
260
+ \uB9CC\uC57D \uC791\uC5C5 \uC911 \uB2E4\uB978 \uC804\uBB38\uAC00(explore, librarian \uB4F1)\uC758 \uB3C4\uC6C0\uC774 \uD544\uC694\uD558\uB2E4\uBA74, \uC9C1\uC811 \uC5D0\uC774\uC804\uD2B8\uB97C \uBD80\uB974\uB824 \uC2DC\uB3C4\uD558\uC9C0 \uB9C8\uC138\uC694. \uB300\uC2E0 \uD604\uC7AC\uAE4C\uC9C0\uC758 \uBD84\uC11D \uACB0\uACFC\uB97C \uC694\uC57D\uD558\uACE0 "OOO \uC5D0\uC774\uC804\uD2B8\uC758 \uB3C4\uC6C0\uC774 \uD544\uC694\uD568"\uC774\uB77C\uB294 \uBA54\uC2DC\uC9C0\uC640 \uD568\uAED8 \uC791\uC5C5\uC744 \uC885\uB8CC(Complete)\uD558\uC5EC \uBA54\uC778 \uC5D0\uC774\uC804\uD2B8\uC5D0\uAC8C \uC81C\uC5B4\uAD8C\uC744 \uBC18\uD658\uD558\uC138\uC694.
261
+ </environment-constraints>
262
+ `;
250
263
  var DEFAULT_ADR_TEMPLATE = `# ADR-NNN: [\uC81C\uBAA9]
251
264
 
252
265
  ## \uC0C1\uD0DC
@@ -473,6 +486,7 @@ function updateScaffold(projectDir) {
473
486
  "config.jsonc": DEFAULT_CONFIG,
474
487
  [`prompts/${DEFAULTS.turnStartFile}`]: DEFAULT_TURN_START,
475
488
  [`prompts/${DEFAULTS.turnEndFile}`]: DEFAULT_TURN_END,
489
+ [`prompts/${DEFAULTS.subagentTurnEndFile}`]: DEFAULT_SUBAGENT_TURN_END,
476
490
  ...templateEntries
477
491
  };
478
492
  const updated = [];
@@ -497,7 +511,8 @@ function updatePrompts(projectDir) {
497
511
  mkdirSync(join(contextDir, "prompts"), { recursive: true });
498
512
  const prompts = {
499
513
  [`prompts/${DEFAULTS.turnStartFile}`]: DEFAULT_TURN_START,
500
- [`prompts/${DEFAULTS.turnEndFile}`]: DEFAULT_TURN_END
514
+ [`prompts/${DEFAULTS.turnEndFile}`]: DEFAULT_TURN_END,
515
+ [`prompts/${DEFAULTS.subagentTurnEndFile}`]: DEFAULT_SUBAGENT_TURN_END
501
516
  };
502
517
  const updated = [];
503
518
  for (const [path, content] of Object.entries(prompts)) {
@@ -578,18 +593,37 @@ function detectPackageManager() {
578
593
  return "npm";
579
594
  return "bun";
580
595
  }
596
+ function isGloballyInstalled() {
597
+ const globalBin = join2(homedir(), ".bun", "bin", "context");
598
+ return existsSync2(globalBin);
599
+ }
581
600
  function runUpdatePlugin(version) {
582
- const pm = detectPackageManager();
583
601
  const pkg = `@ksm0709/context@${version}`;
584
- process.stdout.write(`Updating ${pkg} using ${pm}...
602
+ const globalInstalled = isGloballyInstalled();
603
+ if (globalInstalled) {
604
+ process.stdout.write(`Updating global ${pkg}...
605
+ `);
606
+ const globalResult = Bun.spawnSync(["bun", "install", "-g", pkg]);
607
+ if (globalResult.exitCode !== 0) {
608
+ process.stderr.write(`Failed to update global: ${globalResult.stderr.toString()}
585
609
  `);
586
- const result = Bun.spawnSync([pm, "add", pkg]);
587
- if (result.exitCode !== 0) {
588
- process.stderr.write(`Failed to update: ${result.stderr.toString()}
610
+ process.exit(1);
611
+ return;
612
+ }
613
+ process.stdout.write(`Successfully updated global ${pkg}.
614
+ `);
615
+ }
616
+ const pm = detectPackageManager();
617
+ process.stdout.write(`Updating local ${pkg} using ${pm}...
618
+ `);
619
+ const localResult = Bun.spawnSync([pm, "add", pkg]);
620
+ if (localResult.exitCode !== 0) {
621
+ process.stderr.write(`Failed to update local: ${localResult.stderr.toString()}
589
622
  `);
590
623
  process.exit(1);
624
+ return;
591
625
  }
592
- process.stdout.write(`Successfully updated to ${pkg}.
626
+ process.stdout.write(`Successfully updated local ${pkg}.
593
627
  `);
594
628
  }
595
629
 
package/dist/index.js CHANGED
@@ -816,8 +816,9 @@ var DEFAULTS = {
816
816
  promptDir: ".opencode/context/prompts",
817
817
  turnStartFile: "turn-start.md",
818
818
  turnEndFile: "turn-end.md",
819
+ subagentTurnEndFile: "subagent-turn-end.md",
820
+ blockedToolPatterns: ["^task$", "^background_", "agent"],
819
821
  knowledgeSources: ["AGENTS.md"],
820
- knowledgeDir: "docs",
821
822
  templateDir: ".opencode/context/templates",
822
823
  indexFilename: "INDEX.md",
823
824
  maxDomainDepth: 2
@@ -836,7 +837,11 @@ function getDefaultConfig() {
836
837
  return {
837
838
  prompts: {
838
839
  turnStart: join(DEFAULTS.promptDir, DEFAULTS.turnStartFile),
839
- turnEnd: join(DEFAULTS.promptDir, DEFAULTS.turnEndFile)
840
+ turnEnd: join(DEFAULTS.promptDir, DEFAULTS.turnEndFile),
841
+ subagentTurnEnd: join(DEFAULTS.promptDir, DEFAULTS.subagentTurnEndFile)
842
+ },
843
+ subagentConfig: {
844
+ blockedToolPatterns: [...DEFAULTS.blockedToolPatterns]
840
845
  },
841
846
  knowledge: {
842
847
  dir: DEFAULTS.knowledgeDir,
@@ -852,7 +857,11 @@ function mergeWithDefaults(partial) {
852
857
  return {
853
858
  prompts: {
854
859
  turnStart: partial.prompts?.turnStart ?? defaults.prompts.turnStart,
855
- turnEnd: partial.prompts?.turnEnd ?? defaults.prompts.turnEnd
860
+ turnEnd: partial.prompts?.turnEnd ?? defaults.prompts.turnEnd,
861
+ subagentTurnEnd: partial.prompts?.subagentTurnEnd ?? defaults.prompts.subagentTurnEnd
862
+ },
863
+ subagentConfig: {
864
+ blockedToolPatterns: partial.subagentConfig?.blockedToolPatterns ?? defaults.subagentConfig.blockedToolPatterns
856
865
  },
857
866
  knowledge: {
858
867
  dir: partial.knowledge?.dir ?? defaults.knowledge.dir,
@@ -1094,7 +1103,7 @@ import { join as join3 } from "path";
1094
1103
  // package.json
1095
1104
  var package_default = {
1096
1105
  name: "@ksm0709/context",
1097
- version: "0.0.12",
1106
+ version: "0.0.14",
1098
1107
  author: {
1099
1108
  name: "TaehoKang",
1100
1109
  email: "ksm07091@gmail.com"
@@ -1130,7 +1139,7 @@ var package_default = {
1130
1139
  "@opencode-ai/plugin": ">=1.0.0"
1131
1140
  },
1132
1141
  dependencies: {
1133
- "@ksm0709/context": "^0.0.11",
1142
+ "@ksm0709/context": "^0.0.12",
1134
1143
  "jsonc-parser": "^3.0.0"
1135
1144
  },
1136
1145
  devDependencies: {
@@ -1156,7 +1165,11 @@ var DEFAULT_CONFIG = `{
1156
1165
  // See: https://github.com/ksm0709/context
1157
1166
  "prompts": {
1158
1167
  "turnStart": ".opencode/context/prompts/turn-start.md",
1159
- "turnEnd": ".opencode/context/prompts/turn-end.md"
1168
+ "turnEnd": ".opencode/context/prompts/turn-end.md",
1169
+ "subagentTurnEnd": ".opencode/context/prompts/subagent-turn-end.md"
1170
+ },
1171
+ "subagentConfig": {
1172
+ "blockedToolPatterns": ["^task$", "^background_", "agent"]
1160
1173
  },
1161
1174
  "knowledge": {
1162
1175
  "dir": "docs",
@@ -1309,6 +1322,13 @@ task(
1309
1322
  )
1310
1323
  \`\`\`
1311
1324
  `;
1325
+ var DEFAULT_SUBAGENT_TURN_END = `<environment-constraints>
1326
+ \uB2F9\uC2E0\uC740 \uD604\uC7AC \uBA54\uC778 \uC624\uCF00\uC2A4\uD2B8\uB808\uC774\uD130\uAC00 \uD638\uCD9C\uD55C **\uB9D0\uB2E8 \uC6CC\uCEE4(Worker) \uC5D0\uC774\uC804\uD2B8**\uC785\uB2C8\uB2E4.
1327
+ \uD604\uC7AC \uB2F9\uC2E0\uC758 \uC2E4\uD589 \uD658\uACBD(Sandbox)\uC5D0\uC11C\uB294 \uB124\uD2B8\uC6CC\uD06C \uC790\uC6D0 \uBCF4\uD638\uB97C \uC704\uD574 **\uB2E4\uB978 \uC5D0\uC774\uC804\uD2B8\uB97C \uC0DD\uC131, \uD638\uCD9C, \uC704\uC784\uD558\uB294 \uBAA8\uB4E0 \uB3C4\uAD6C(\uC608: task, background_task \uB4F1)\uC758 \uAD8C\uD55C\uC774 \uC2DC\uC2A4\uD15C \uB808\uBCA8\uC5D0\uC11C \uD68C\uC218**\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
1328
+
1329
+ \uB9CC\uC57D \uC791\uC5C5 \uC911 \uB2E4\uB978 \uC804\uBB38\uAC00(explore, librarian \uB4F1)\uC758 \uB3C4\uC6C0\uC774 \uD544\uC694\uD558\uB2E4\uBA74, \uC9C1\uC811 \uC5D0\uC774\uC804\uD2B8\uB97C \uBD80\uB974\uB824 \uC2DC\uB3C4\uD558\uC9C0 \uB9C8\uC138\uC694. \uB300\uC2E0 \uD604\uC7AC\uAE4C\uC9C0\uC758 \uBD84\uC11D \uACB0\uACFC\uB97C \uC694\uC57D\uD558\uACE0 "OOO \uC5D0\uC774\uC804\uD2B8\uC758 \uB3C4\uC6C0\uC774 \uD544\uC694\uD568"\uC774\uB77C\uB294 \uBA54\uC2DC\uC9C0\uC640 \uD568\uAED8 \uC791\uC5C5\uC744 \uC885\uB8CC(Complete)\uD558\uC5EC \uBA54\uC778 \uC5D0\uC774\uC804\uD2B8\uC5D0\uAC8C \uC81C\uC5B4\uAD8C\uC744 \uBC18\uD658\uD558\uC138\uC694.
1330
+ </environment-constraints>
1331
+ `;
1312
1332
  var DEFAULT_ADR_TEMPLATE = `# ADR-NNN: [\uC81C\uBAA9]
1313
1333
 
1314
1334
  ## \uC0C1\uD0DC
@@ -1539,6 +1559,7 @@ function scaffoldIfNeeded(projectDir) {
1539
1559
  writeFileSync(join3(contextDir, "config.jsonc"), DEFAULT_CONFIG, "utf-8");
1540
1560
  writeFileSync(join3(promptsDir, DEFAULTS.turnStartFile), DEFAULT_TURN_START, "utf-8");
1541
1561
  writeFileSync(join3(promptsDir, DEFAULTS.turnEndFile), DEFAULT_TURN_END, "utf-8");
1562
+ writeFileSync(join3(promptsDir, DEFAULTS.subagentTurnEndFile), DEFAULT_SUBAGENT_TURN_END, "utf-8");
1542
1563
  for (const [filename, content] of Object.entries(TEMPLATE_FILES)) {
1543
1564
  writeFileSync(join3(templatesDir, filename), content, "utf-8");
1544
1565
  }
@@ -1606,6 +1627,25 @@ var plugin = async ({ directory, client }) => {
1606
1627
  }
1607
1628
  const config = loadConfig(directory);
1608
1629
  return {
1630
+ "tool.execute.before": async (input) => {
1631
+ try {
1632
+ const session = await client.session.get({ path: { id: input.sessionID } });
1633
+ if (!session)
1634
+ return;
1635
+ const isSubagent = ["explore", "librarian", "oracle", "Sisyphus-Junior"].includes(session.agent);
1636
+ if (isSubagent) {
1637
+ const patterns = config.subagentConfig?.blockedToolPatterns ?? DEFAULTS.blockedToolPatterns;
1638
+ const isBlocked = patterns.some((pattern) => new RegExp(pattern, "i").test(input.tool));
1639
+ if (isBlocked) {
1640
+ throw new Error(`[Security] Subagents are not allowed to use orchestration tools (${input.tool}). Please return control to the main agent.`);
1641
+ }
1642
+ }
1643
+ } catch (err) {
1644
+ if (err instanceof Error && err.message.startsWith("[Security]")) {
1645
+ throw err;
1646
+ }
1647
+ }
1648
+ },
1609
1649
  "experimental.chat.messages.transform": async (_input, output) => {
1610
1650
  if (output.messages.length === 0)
1611
1651
  return;
@@ -1628,7 +1668,9 @@ var plugin = async ({ directory, client }) => {
1628
1668
  text: combinedContent
1629
1669
  });
1630
1670
  }
1631
- const turnEndPath = join4(directory, config.prompts.turnEnd ?? join4(DEFAULTS.promptDir, DEFAULTS.turnEndFile));
1671
+ const agentName = lastUserMsg.info.agent || "default";
1672
+ const isSubagent = ["explore", "librarian", "oracle", "Sisyphus-Junior"].includes(agentName);
1673
+ const turnEndPath = join4(directory, isSubagent ? config.prompts.subagentTurnEnd ?? join4(DEFAULTS.promptDir, DEFAULTS.subagentTurnEndFile) : config.prompts.turnEnd ?? join4(DEFAULTS.promptDir, DEFAULTS.turnEndFile));
1632
1674
  const turnEnd = readPromptFile(turnEndPath);
1633
1675
  if (!turnEnd)
1634
1676
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ksm0709/context",
3
- "version": "0.0.12",
3
+ "version": "0.0.14",
4
4
  "author": {
5
5
  "name": "TaehoKang",
6
6
  "email": "ksm07091@gmail.com"
@@ -36,7 +36,7 @@
36
36
  "@opencode-ai/plugin": ">=1.0.0"
37
37
  },
38
38
  "dependencies": {
39
- "@ksm0709/context": "^0.0.11",
39
+ "@ksm0709/context": "^0.0.12",
40
40
  "jsonc-parser": "^3.0.0"
41
41
  },
42
42
  "devDependencies": {