clikit-plugin 0.2.23 → 0.2.25

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.d.ts CHANGED
@@ -7,5 +7,6 @@ interface ScaffoldStats {
7
7
  export declare function resolveProjectDir(env?: NodeJS.ProcessEnv, cwd?: string): string;
8
8
  export declare function upsertPluginEntry(existingPlugins: string[], pluginName: string, version: string): string[];
9
9
  export declare function scaffoldProjectOpencode(projectDir: string, packageRoot?: string): ScaffoldStats;
10
+ export declare function scaffoldGlobalPluginAssets(configDir: string, packageRoot?: string): ScaffoldStats;
10
11
  export {};
11
12
  //# sourceMappingURL=cli.d.ts.map
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AASA,UAAU,aAAa;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B;AA4BD,wBAAgB,iBAAiB,CAC/B,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,GAAG,GAAE,MAAsB,GAC1B,MAAM,CAiBR;AAED,wBAAgB,iBAAiB,CAAC,eAAe,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAM1G;AA0CD,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,SAAmB,GAAG,aAAa,CAoDzG"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AASA,UAAU,aAAa;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B;AA4BD,wBAAgB,iBAAiB,CAC/B,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,GAAG,GAAE,MAAsB,GAC1B,MAAM,CAiBR;AAED,wBAAgB,iBAAiB,CAAC,eAAe,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAM1G;AA0CD,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,SAAmB,GAAG,aAAa,CA0DzG;AAED,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,SAAmB,GAAG,aAAa,CAqB3G"}
package/dist/cli.js CHANGED
@@ -108,6 +108,7 @@ function scaffoldProjectOpencode(projectDir, packageRoot = getPackageRoot()) {
108
108
  copyDirectoryFilesIfMissing(path.join(packageRoot, "command"), path.join(projectOpencodeDir, "command"), stats);
109
109
  copyDirectoryFilesIfMissing(path.join(packageRoot, "skill"), path.join(projectOpencodeDir, "skill"), stats);
110
110
  copyDirectoryFilesIfMissing(path.join(packageRoot, "memory", "_templates"), path.join(projectOpencodeDir, "memory", "_templates"), stats);
111
+ copyDirectoryFilesIfMissing(path.join(packageRoot, "src", "agents"), path.join(projectOpencodeDir, "src", "agents"), stats);
111
112
  copyFileIfMissing(path.join(packageRoot, "README.md"), path.join(projectOpencodeDir, "README-clikit.md"), stats);
112
113
  const indexPath = path.join(projectOpencodeDir, "index.ts");
113
114
  if (!fs.existsSync(indexPath)) {
@@ -121,6 +122,17 @@ export default CliKitPlugin;
121
122
  }
122
123
  return stats;
123
124
  }
125
+ function scaffoldGlobalPluginAssets(configDir, packageRoot = getPackageRoot()) {
126
+ const pluginsDir = path.join(configDir, "plugins");
127
+ const stats = {
128
+ copied: 0,
129
+ skipped: 0,
130
+ missingSources: []
131
+ };
132
+ copyFileIfMissing(path.join(packageRoot, "dist", "index.js"), path.join(pluginsDir, "clikit.js"), stats);
133
+ copyDirectoryFilesIfMissing(path.join(packageRoot, "src", "agents"), path.join(pluginsDir, "agents"), stats);
134
+ return stats;
135
+ }
124
136
  function getRealHome() {
125
137
  if (process.env.SNAP_REAL_HOME) {
126
138
  return process.env.SNAP_REAL_HOME;
@@ -189,7 +201,7 @@ async function install() {
189
201
  ================
190
202
  `);
191
203
  const pluginVersion = getPackageVersion();
192
- console.log("[1/4] Adding CliKit plugin to OpenCode config...");
204
+ console.log("[1/5] Adding CliKit plugin to OpenCode config...");
193
205
  try {
194
206
  ensureConfigDir();
195
207
  } catch (err) {
@@ -220,7 +232,7 @@ async function install() {
220
232
  return 1;
221
233
  }
222
234
  console.log(`
223
- [2/4] Scaffolding project .opencode assets...`);
235
+ [2/5] Scaffolding project .opencode assets...`);
224
236
  try {
225
237
  const projectDir = resolveProjectDir();
226
238
  const stats = scaffoldProjectOpencode(projectDir);
@@ -237,7 +249,23 @@ async function install() {
237
249
  return 1;
238
250
  }
239
251
  console.log(`
240
- [3/4] Creating memory directories...`);
252
+ [3/5] Installing global plugin assets...`);
253
+ try {
254
+ const stats = scaffoldGlobalPluginAssets(getConfigDir());
255
+ console.log(`\u2713 Global plugin assets ready in ${path.join(getConfigDir(), "plugins")}`);
256
+ console.log(` Copied: ${stats.copied}, Skipped existing: ${stats.skipped}`);
257
+ if (stats.missingSources.length > 0) {
258
+ console.log(" Missing bundled sources (skipped):");
259
+ for (const missing of stats.missingSources) {
260
+ console.log(` - ${missing}`);
261
+ }
262
+ }
263
+ } catch (err) {
264
+ console.error(`\u2717 Failed to install global plugin assets: ${err}`);
265
+ return 1;
266
+ }
267
+ console.log(`
268
+ [4/5] Creating memory directories...`);
241
269
  const memoryDir = path.join(getConfigDir(), "memory");
242
270
  const memorySubdirs = ["specs", "plans", "research", "reviews", "handoffs", "beads", "prds"];
243
271
  for (const subdir of memorySubdirs) {
@@ -248,7 +276,7 @@ async function install() {
248
276
  }
249
277
  console.log(`\u2713 Memory directories created in ${memoryDir}`);
250
278
  console.log(`
251
- [4/4] Creating CliKit config...`);
279
+ [5/5] Creating CliKit config...`);
252
280
  const clikitConfigPath = path.join(getConfigDir(), "clikit.config.json");
253
281
  if (!fs.existsSync(clikitConfigPath)) {
254
282
  const defaultConfig = {
@@ -333,5 +361,6 @@ if (import.meta.main) {
333
361
  export {
334
362
  upsertPluginEntry,
335
363
  scaffoldProjectOpencode,
364
+ scaffoldGlobalPluginAssets,
336
365
  resolveProjectDir
337
366
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AA6DlD,QAAA,MAAM,YAAY,EAAE,MA4TnB,CAAC;AAEF,eAAe,YAAY,CAAC;AAG5B,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACvD,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1E,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC1F,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAG1D,OAAO,EACL,mBAAmB,EAAE,uBAAuB,EAC5C,cAAc,EAAE,eAAe,EAC/B,qBAAqB,EAAE,oBAAoB,EAC3C,qBAAqB,EAAE,eAAe,EAAE,qBAAqB,EAC7D,gBAAgB,EAAE,cAAc,EAAE,oBAAoB,EACtD,mBAAmB,EAAE,sBAAsB,EAAE,oBAAoB,EACjE,cAAc,EAAE,aAAa,EAAE,gBAAgB,EAC/C,YAAY,EAAE,YAAY,EAAE,mBAAmB,EAC/C,gBAAgB,EAAE,YAAY,EAAE,sBAAsB,EACtD,gBAAgB,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,qBAAqB,EACtF,cAAc,EAAE,cAAc,EAAE,mBAAmB,EACnD,wBAAwB,EAAE,oBAAoB,EAAE,mBAAmB,GACpE,MAAM,SAAS,CAAC;AAGjB,OAAO,EAEL,UAAU,EACV,YAAY,EACZ,SAAS,EACT,cAAc,EACd,YAAY,EACZ,WAAW,EACX,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EAEtB,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,gBAAgB,EAChB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EAEtB,KAAK,EACL,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,WAAW,EAEhB,eAAe,EACf,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC1B,aAAa,EACb,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,cAAc,EACd,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,GAC1B,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AA6DlD,QAAA,MAAM,YAAY,EAAE,MAuTnB,CAAC;AAGF,eAAe,YAAY,CAAC;AAG5B,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACvD,YAAY,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1E,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC1F,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAG1D,OAAO,EACL,mBAAmB,EAAE,uBAAuB,EAC5C,cAAc,EAAE,eAAe,EAC/B,qBAAqB,EAAE,oBAAoB,EAC3C,qBAAqB,EAAE,eAAe,EAAE,qBAAqB,EAC7D,gBAAgB,EAAE,cAAc,EAAE,oBAAoB,EACtD,mBAAmB,EAAE,sBAAsB,EAAE,oBAAoB,EACjE,cAAc,EAAE,aAAa,EAAE,gBAAgB,EAC/C,YAAY,EAAE,YAAY,EAAE,mBAAmB,EAC/C,gBAAgB,EAAE,YAAY,EAAE,sBAAsB,EACtD,gBAAgB,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,qBAAqB,EACtF,cAAc,EAAE,cAAc,EAAE,mBAAmB,EACnD,wBAAwB,EAAE,oBAAoB,EAAE,mBAAmB,GACpE,MAAM,SAAS,CAAC;AAGjB,OAAO,EAEL,UAAU,EACV,YAAY,EACZ,SAAS,EACT,cAAc,EACd,YAAY,EACZ,WAAW,EACX,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EAEtB,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,gBAAgB,EAChB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EAEtB,KAAK,EACL,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,WAAW,EAEhB,eAAe,EACf,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC1B,aAAa,EACb,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,cAAc,EACd,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,GAC1B,MAAM,SAAS,CAAC"}
package/dist/index.js CHANGED
@@ -5825,250 +5825,245 @@ function buildSummary(sections, maxTokens) {
5825
5825
  var CliKitPlugin = async (ctx) => {
5826
5826
  console.log("[CliKit] Plugin initializing...");
5827
5827
  console.log("[CliKit] Context:", JSON.stringify({ directory: ctx?.directory, hasClient: !!ctx?.client }));
5828
- try {
5829
- const pluginConfig = loadCliKitConfig(ctx.directory) ?? {};
5830
- const builtinAgents = getBuiltinAgents();
5831
- const builtinCommands = getBuiltinCommands();
5832
- const filteredAgents = filterAgents(builtinAgents, pluginConfig);
5833
- const filteredCommands = filterCommands(builtinCommands, pluginConfig);
5834
- console.log(`[CliKit] Loaded ${Object.keys(filteredAgents).length}/${Object.keys(builtinAgents).length} agents`);
5835
- console.log(`[CliKit] Loaded ${Object.keys(filteredCommands).length}/${Object.keys(builtinCommands).length} commands`);
5836
- if (pluginConfig.disabled_agents?.length) {
5837
- console.log(`[CliKit] Disabled agents: ${pluginConfig.disabled_agents.join(", ")}`);
5838
- }
5839
- if (pluginConfig.disabled_commands?.length) {
5840
- console.log(`[CliKit] Disabled commands: ${pluginConfig.disabled_commands.join(", ")}`);
5841
- }
5842
- return {
5843
- config: async (config) => {
5844
- config.agent = {
5845
- ...filteredAgents,
5846
- ...config.agent
5847
- };
5848
- config.command = {
5849
- ...filteredCommands,
5850
- ...config.command
5851
- };
5852
- if (pluginConfig.lsp && Object.keys(pluginConfig.lsp).length > 0) {
5853
- const enabledLsp = {};
5854
- for (const [name, lspConfig] of Object.entries(pluginConfig.lsp)) {
5855
- if (!lspConfig.disabled) {
5856
- enabledLsp[name] = lspConfig;
5857
- }
5858
- }
5859
- if (Object.keys(enabledLsp).length > 0) {
5860
- config.lsp = {
5861
- ...enabledLsp,
5862
- ...config.lsp || {}
5863
- };
5864
- console.log(`[CliKit] Injected ${Object.keys(enabledLsp).length} LSP server(s)`);
5828
+ const pluginConfig = loadCliKitConfig(ctx.directory) ?? {};
5829
+ const builtinAgents = getBuiltinAgents();
5830
+ const builtinCommands = getBuiltinCommands();
5831
+ const filteredAgents = filterAgents(builtinAgents, pluginConfig);
5832
+ const filteredCommands = filterCommands(builtinCommands, pluginConfig);
5833
+ console.log(`[CliKit] Loaded ${Object.keys(filteredAgents).length}/${Object.keys(builtinAgents).length} agents`);
5834
+ console.log(`[CliKit] Loaded ${Object.keys(filteredCommands).length}/${Object.keys(builtinCommands).length} commands`);
5835
+ if (pluginConfig.disabled_agents?.length) {
5836
+ console.log(`[CliKit] Disabled agents: ${pluginConfig.disabled_agents.join(", ")}`);
5837
+ }
5838
+ if (pluginConfig.disabled_commands?.length) {
5839
+ console.log(`[CliKit] Disabled commands: ${pluginConfig.disabled_commands.join(", ")}`);
5840
+ }
5841
+ return {
5842
+ config: async (config) => {
5843
+ config.agent = {
5844
+ ...filteredAgents,
5845
+ ...config.agent
5846
+ };
5847
+ config.command = {
5848
+ ...filteredCommands,
5849
+ ...config.command
5850
+ };
5851
+ if (pluginConfig.lsp && Object.keys(pluginConfig.lsp).length > 0) {
5852
+ const enabledLsp = {};
5853
+ for (const [name, lspConfig] of Object.entries(pluginConfig.lsp)) {
5854
+ if (!lspConfig.disabled) {
5855
+ enabledLsp[name] = lspConfig;
5865
5856
  }
5866
5857
  }
5867
- },
5868
- event: async (input) => {
5869
- const { event } = input;
5870
- const props = event.properties;
5871
- if (event.type === "session.created") {
5872
- if (pluginConfig.hooks?.session_logging) {
5873
- const info = props?.info;
5874
- console.log(`[CliKit] Session created: ${info?.id || "unknown"}`);
5875
- }
5876
- if (pluginConfig.hooks?.env_context?.enabled !== false) {
5877
- const envConfig = pluginConfig.hooks?.env_context;
5878
- const envInfo = collectEnvInfo(ctx.directory, envConfig);
5879
- const envBlock = buildEnvBlock(envInfo);
5880
- console.log(formatEnvSummary(envInfo));
5881
- input.__envBlock = envBlock;
5882
- }
5858
+ if (Object.keys(enabledLsp).length > 0) {
5859
+ config.lsp = {
5860
+ ...enabledLsp,
5861
+ ...config.lsp || {}
5862
+ };
5863
+ console.log(`[CliKit] Injected ${Object.keys(enabledLsp).length} LSP server(s)`);
5883
5864
  }
5884
- if (event.type === "session.error") {
5885
- const error = props?.error;
5886
- if (pluginConfig.hooks?.session_logging) {
5887
- console.error(`[CliKit] Session error:`, error);
5888
- }
5889
- if (pluginConfig.hooks?.session_notification?.enabled !== false && pluginConfig.hooks?.session_notification?.on_error !== false) {
5890
- const notifConfig = pluginConfig.hooks?.session_notification;
5891
- const sessionId = props?.sessionID;
5892
- const payload = buildErrorNotification(error, sessionId, notifConfig?.title_prefix);
5893
- const sent = sendNotification(payload);
5894
- console.log(formatNotificationLog(payload, sent));
5895
- }
5865
+ }
5866
+ },
5867
+ event: async (input) => {
5868
+ const { event } = input;
5869
+ const props = event.properties;
5870
+ if (event.type === "session.created") {
5871
+ if (pluginConfig.hooks?.session_logging) {
5872
+ const info = props?.info;
5873
+ console.log(`[CliKit] Session created: ${info?.id || "unknown"}`);
5896
5874
  }
5897
- if (event.type === "session.idle") {
5898
- const sessionID = props?.sessionID;
5899
- if (pluginConfig.hooks?.session_logging) {
5900
- console.log(`[CliKit] Session idle: ${sessionID || "unknown"}`);
5901
- }
5902
- const todoConfig = pluginConfig.hooks?.todo_enforcer;
5903
- if (todoConfig?.enabled !== false) {
5904
- const todos = props?.todos;
5905
- if (Array.isArray(todos) && todos.length > 0) {
5906
- const result = checkTodoCompletion(todos);
5907
- if (!result.complete && todoConfig?.warn_on_incomplete !== false) {
5908
- console.warn(formatIncompleteWarning(result, sessionID));
5909
- }
5910
- }
5911
- }
5912
- if (pluginConfig.hooks?.session_notification?.enabled !== false && pluginConfig.hooks?.session_notification?.on_idle !== false) {
5913
- const notifConfig = pluginConfig.hooks?.session_notification;
5914
- const payload = buildIdleNotification(sessionID, notifConfig?.title_prefix);
5915
- const sent = sendNotification(payload);
5916
- console.log(formatNotificationLog(payload, sent));
5917
- }
5918
- if (pluginConfig.hooks?.compaction?.enabled !== false) {
5919
- const compConfig = pluginConfig.hooks?.compaction;
5920
- const compPayload = collectCompactionPayload(ctx.directory, compConfig);
5921
- if (compConfig?.include_todo_state !== false && props?.todos) {
5922
- compPayload.todos = props.todos;
5875
+ if (pluginConfig.hooks?.env_context?.enabled !== false) {
5876
+ const envConfig = pluginConfig.hooks?.env_context;
5877
+ const envInfo = collectEnvInfo(ctx.directory, envConfig);
5878
+ const envBlock = buildEnvBlock(envInfo);
5879
+ console.log(formatEnvSummary(envInfo));
5880
+ input.__envBlock = envBlock;
5881
+ }
5882
+ }
5883
+ if (event.type === "session.error") {
5884
+ const error = props?.error;
5885
+ if (pluginConfig.hooks?.session_logging) {
5886
+ console.error(`[CliKit] Session error:`, error);
5887
+ }
5888
+ if (pluginConfig.hooks?.session_notification?.enabled !== false && pluginConfig.hooks?.session_notification?.on_error !== false) {
5889
+ const notifConfig = pluginConfig.hooks?.session_notification;
5890
+ const sessionId = props?.sessionID;
5891
+ const payload = buildErrorNotification(error, sessionId, notifConfig?.title_prefix);
5892
+ const sent = sendNotification(payload);
5893
+ console.log(formatNotificationLog(payload, sent));
5894
+ }
5895
+ }
5896
+ if (event.type === "session.idle") {
5897
+ const sessionID = props?.sessionID;
5898
+ if (pluginConfig.hooks?.session_logging) {
5899
+ console.log(`[CliKit] Session idle: ${sessionID || "unknown"}`);
5900
+ }
5901
+ const todoConfig = pluginConfig.hooks?.todo_enforcer;
5902
+ if (todoConfig?.enabled !== false) {
5903
+ const todos = props?.todos;
5904
+ if (Array.isArray(todos) && todos.length > 0) {
5905
+ const result = checkTodoCompletion(todos);
5906
+ if (!result.complete && todoConfig?.warn_on_incomplete !== false) {
5907
+ console.warn(formatIncompleteWarning(result, sessionID));
5923
5908
  }
5924
- const block = buildCompactionBlock(compPayload, compConfig?.max_state_chars);
5925
- console.log(formatCompactionLog(compPayload));
5926
- input.__compactionBlock = block;
5927
5909
  }
5928
5910
  }
5929
- },
5930
- "tool.execute.before": async (input, _output) => {
5931
- const toolName = input.tool;
5932
- const toolInput = input.input ?? {};
5933
- if (pluginConfig.hooks?.tool_logging) {
5934
- console.log(`[CliKit] Tool executing: ${toolName}`);
5911
+ if (pluginConfig.hooks?.session_notification?.enabled !== false && pluginConfig.hooks?.session_notification?.on_idle !== false) {
5912
+ const notifConfig = pluginConfig.hooks?.session_notification;
5913
+ const payload = buildIdleNotification(sessionID, notifConfig?.title_prefix);
5914
+ const sent = sendNotification(payload);
5915
+ console.log(formatNotificationLog(payload, sent));
5935
5916
  }
5936
- if (pluginConfig.hooks?.git_guard?.enabled !== false) {
5937
- if (toolName === "bash" || toolName === "Bash") {
5938
- const command = toolInput.command;
5939
- if (command) {
5940
- const allowForceWithLease = pluginConfig.hooks?.git_guard?.allow_force_with_lease !== false;
5941
- const result = checkDangerousCommand(command, allowForceWithLease);
5942
- if (result.blocked) {
5943
- console.warn(formatBlockedWarning(result));
5944
- input.__blocked = true;
5945
- input.__blockReason = result.reason;
5946
- }
5917
+ if (pluginConfig.hooks?.compaction?.enabled !== false) {
5918
+ const compConfig = pluginConfig.hooks?.compaction;
5919
+ const compPayload = collectCompactionPayload(ctx.directory, compConfig);
5920
+ if (compConfig?.include_todo_state !== false && props?.todos) {
5921
+ compPayload.todos = props.todos;
5922
+ }
5923
+ const block = buildCompactionBlock(compPayload, compConfig?.max_state_chars);
5924
+ console.log(formatCompactionLog(compPayload));
5925
+ input.__compactionBlock = block;
5926
+ }
5927
+ }
5928
+ },
5929
+ "tool.execute.before": async (input, _output) => {
5930
+ const toolName = input.tool;
5931
+ const toolInput = input.input ?? {};
5932
+ if (pluginConfig.hooks?.tool_logging) {
5933
+ console.log(`[CliKit] Tool executing: ${toolName}`);
5934
+ }
5935
+ if (pluginConfig.hooks?.git_guard?.enabled !== false) {
5936
+ if (toolName === "bash" || toolName === "Bash") {
5937
+ const command = toolInput.command;
5938
+ if (command) {
5939
+ const allowForceWithLease = pluginConfig.hooks?.git_guard?.allow_force_with_lease !== false;
5940
+ const result = checkDangerousCommand(command, allowForceWithLease);
5941
+ if (result.blocked) {
5942
+ console.warn(formatBlockedWarning(result));
5943
+ input.__blocked = true;
5944
+ input.__blockReason = result.reason;
5947
5945
  }
5948
5946
  }
5949
5947
  }
5950
- if (pluginConfig.hooks?.security_check?.enabled !== false) {
5951
- if (toolName === "bash" || toolName === "Bash") {
5952
- const command = toolInput.command;
5953
- if (command && /git\s+(commit|add)/.test(command)) {
5954
- const secConfig = pluginConfig.hooks?.security_check;
5955
- let shouldBlock = false;
5956
- const files = toolInput.files;
5957
- if (files) {
5958
- for (const file of files) {
5959
- if (isSensitiveFile(file)) {
5960
- console.warn(`[CliKit:security] Sensitive file staged: ${file}`);
5961
- shouldBlock = true;
5962
- }
5963
- }
5964
- }
5965
- const content = toolInput.content;
5966
- if (content) {
5967
- const scanResult = scanContentForSecrets(content);
5968
- if (!scanResult.safe) {
5969
- console.warn(formatSecurityWarning(scanResult));
5948
+ }
5949
+ if (pluginConfig.hooks?.security_check?.enabled !== false) {
5950
+ if (toolName === "bash" || toolName === "Bash") {
5951
+ const command = toolInput.command;
5952
+ if (command && /git\s+(commit|add)/.test(command)) {
5953
+ const secConfig = pluginConfig.hooks?.security_check;
5954
+ let shouldBlock = false;
5955
+ const files = toolInput.files;
5956
+ if (files) {
5957
+ for (const file of files) {
5958
+ if (isSensitiveFile(file)) {
5959
+ console.warn(`[CliKit:security] Sensitive file staged: ${file}`);
5970
5960
  shouldBlock = true;
5971
5961
  }
5972
5962
  }
5973
- if (shouldBlock && secConfig?.block_commits) {
5974
- input.__blocked = true;
5975
- input.__blockReason = "Sensitive data detected in commit";
5963
+ }
5964
+ const content = toolInput.content;
5965
+ if (content) {
5966
+ const scanResult = scanContentForSecrets(content);
5967
+ if (!scanResult.safe) {
5968
+ console.warn(formatSecurityWarning(scanResult));
5969
+ shouldBlock = true;
5976
5970
  }
5977
5971
  }
5978
- }
5979
- }
5980
- if (pluginConfig.hooks?.subagent_question_blocker?.enabled !== false) {
5981
- if (isSubagentTool(toolName)) {
5982
- const prompt = toolInput.prompt;
5983
- if (prompt && containsQuestion(prompt)) {
5984
- console.warn(formatBlockerWarning());
5972
+ if (shouldBlock && secConfig?.block_commits) {
5985
5973
  input.__blocked = true;
5986
- input.__blockReason = "Subagents should not ask questions";
5974
+ input.__blockReason = "Sensitive data detected in commit";
5987
5975
  }
5988
5976
  }
5989
5977
  }
5990
- },
5991
- "tool.execute.after": async (input, output) => {
5992
- const toolName = input.tool;
5993
- const toolInput = input.input ?? {};
5994
- const toolOutput = output;
5995
- if (pluginConfig.hooks?.tool_logging) {
5996
- console.log(`[CliKit] Tool completed: ${toolName} -> ${output.title}`);
5978
+ }
5979
+ if (pluginConfig.hooks?.subagent_question_blocker?.enabled !== false) {
5980
+ if (isSubagentTool(toolName)) {
5981
+ const prompt = toolInput.prompt;
5982
+ if (prompt && containsQuestion(prompt)) {
5983
+ console.warn(formatBlockerWarning());
5984
+ input.__blocked = true;
5985
+ input.__blockReason = "Subagents should not ask questions";
5986
+ }
5997
5987
  }
5998
- const sanitizerConfig = pluginConfig.hooks?.empty_message_sanitizer;
5999
- if (sanitizerConfig?.enabled !== false) {
6000
- if (toolOutput.content !== undefined && isEmptyContent(toolOutput.content)) {
6001
- const placeholder = sanitizerConfig?.placeholder || "(No output)";
6002
- if (sanitizerConfig?.log_empty !== false) {
6003
- console.log(`[CliKit] Empty output detected for tool: ${toolName}`);
6004
- }
6005
- toolOutput.content = sanitizeContent(toolOutput.content, placeholder);
5988
+ }
5989
+ },
5990
+ "tool.execute.after": async (input, output) => {
5991
+ const toolName = input.tool;
5992
+ const toolInput = input.input ?? {};
5993
+ const toolOutput = output;
5994
+ if (pluginConfig.hooks?.tool_logging) {
5995
+ console.log(`[CliKit] Tool completed: ${toolName} -> ${output.title}`);
5996
+ }
5997
+ const sanitizerConfig = pluginConfig.hooks?.empty_message_sanitizer;
5998
+ if (sanitizerConfig?.enabled !== false) {
5999
+ if (toolOutput.content !== undefined && isEmptyContent(toolOutput.content)) {
6000
+ const placeholder = sanitizerConfig?.placeholder || "(No output)";
6001
+ if (sanitizerConfig?.log_empty !== false) {
6002
+ console.log(`[CliKit] Empty output detected for tool: ${toolName}`);
6006
6003
  }
6004
+ toolOutput.content = sanitizeContent(toolOutput.content, placeholder);
6007
6005
  }
6008
- if (pluginConfig.hooks?.comment_checker?.enabled !== false) {
6009
- if (toolName === "edit" || toolName === "Edit" || toolName === "write" || toolName === "Write") {
6010
- const content = toolOutput.content;
6011
- if (typeof content === "string" && content.length > 100) {
6012
- const threshold = pluginConfig.hooks?.comment_checker?.threshold ?? 0.3;
6013
- const densityResult = checkCommentDensity(content, threshold);
6014
- if (densityResult.excessive) {
6015
- console.warn(formatCommentWarning(densityResult));
6016
- }
6017
- if (hasExcessiveAIComments(content)) {
6018
- console.warn("[CliKit:comment-checker] Detected AI-style boilerplate comments. Remove unnecessary comments.");
6019
- }
6006
+ }
6007
+ if (pluginConfig.hooks?.comment_checker?.enabled !== false) {
6008
+ if (toolName === "edit" || toolName === "Edit" || toolName === "write" || toolName === "Write") {
6009
+ const content = toolOutput.content;
6010
+ if (typeof content === "string" && content.length > 100) {
6011
+ const threshold = pluginConfig.hooks?.comment_checker?.threshold ?? 0.3;
6012
+ const densityResult = checkCommentDensity(content, threshold);
6013
+ if (densityResult.excessive) {
6014
+ console.warn(formatCommentWarning(densityResult));
6015
+ }
6016
+ if (hasExcessiveAIComments(content)) {
6017
+ console.warn("[CliKit:comment-checker] Detected AI-style boilerplate comments. Remove unnecessary comments.");
6020
6018
  }
6021
6019
  }
6022
6020
  }
6023
- if (pluginConfig.hooks?.truncator?.enabled !== false) {
6024
- if (typeof toolOutput.content === "string" && shouldTruncate(toolOutput.content, pluginConfig.hooks?.truncator)) {
6025
- const result = truncateOutput(toolOutput.content, pluginConfig.hooks?.truncator);
6026
- if (result.truncated) {
6027
- toolOutput.content = result.content;
6028
- if (pluginConfig.hooks?.truncator?.log !== false) {
6029
- console.log(formatTruncationLog(result));
6030
- }
6021
+ }
6022
+ if (pluginConfig.hooks?.truncator?.enabled !== false) {
6023
+ if (typeof toolOutput.content === "string" && shouldTruncate(toolOutput.content, pluginConfig.hooks?.truncator)) {
6024
+ const result = truncateOutput(toolOutput.content, pluginConfig.hooks?.truncator);
6025
+ if (result.truncated) {
6026
+ toolOutput.content = result.content;
6027
+ if (pluginConfig.hooks?.truncator?.log !== false) {
6028
+ console.log(formatTruncationLog(result));
6031
6029
  }
6032
6030
  }
6033
6031
  }
6034
- if (pluginConfig.hooks?.auto_format?.enabled) {
6035
- if (toolName === "edit" || toolName === "Edit" || toolName === "write" || toolName === "Write") {
6036
- const filePath = toolInput.filePath;
6037
- if (filePath) {
6038
- const fmtConfig = pluginConfig.hooks.auto_format;
6039
- if (shouldFormat(filePath, fmtConfig?.extensions)) {
6040
- const result = runFormatter(filePath, ctx.directory, fmtConfig?.formatter);
6041
- if (fmtConfig?.log !== false) {
6042
- console.log(formatAutoFormatLog(result));
6043
- }
6032
+ }
6033
+ if (pluginConfig.hooks?.auto_format?.enabled) {
6034
+ if (toolName === "edit" || toolName === "Edit" || toolName === "write" || toolName === "Write") {
6035
+ const filePath = toolInput.filePath;
6036
+ if (filePath) {
6037
+ const fmtConfig = pluginConfig.hooks.auto_format;
6038
+ if (shouldFormat(filePath, fmtConfig?.extensions)) {
6039
+ const result = runFormatter(filePath, ctx.directory, fmtConfig?.formatter);
6040
+ if (fmtConfig?.log !== false) {
6041
+ console.log(formatAutoFormatLog(result));
6044
6042
  }
6045
6043
  }
6046
6044
  }
6047
6045
  }
6048
- if (pluginConfig.hooks?.typecheck_gate?.enabled) {
6049
- if (toolName === "edit" || toolName === "Edit" || toolName === "write" || toolName === "Write") {
6050
- const filePath = toolInput.filePath;
6051
- if (filePath && isTypeScriptFile(filePath)) {
6052
- const tcConfig = pluginConfig.hooks.typecheck_gate;
6053
- const result = runTypeCheck(filePath, ctx.directory, tcConfig);
6054
- if (!result.clean) {
6055
- console.warn(formatTypeCheckWarning(result));
6056
- if (tcConfig?.block_on_error) {
6057
- input.__blocked = true;
6058
- input.__blockReason = `Type errors in ${filePath}`;
6059
- }
6060
- } else if (tcConfig?.log !== false) {
6061
- console.log(formatTypeCheckWarning(result));
6046
+ }
6047
+ if (pluginConfig.hooks?.typecheck_gate?.enabled) {
6048
+ if (toolName === "edit" || toolName === "Edit" || toolName === "write" || toolName === "Write") {
6049
+ const filePath = toolInput.filePath;
6050
+ if (filePath && isTypeScriptFile(filePath)) {
6051
+ const tcConfig = pluginConfig.hooks.typecheck_gate;
6052
+ const result = runTypeCheck(filePath, ctx.directory, tcConfig);
6053
+ if (!result.clean) {
6054
+ console.warn(formatTypeCheckWarning(result));
6055
+ if (tcConfig?.block_on_error) {
6056
+ input.__blocked = true;
6057
+ input.__blockReason = `Type errors in ${filePath}`;
6062
6058
  }
6059
+ } else if (tcConfig?.log !== false) {
6060
+ console.log(formatTypeCheckWarning(result));
6063
6061
  }
6064
6062
  }
6065
6063
  }
6066
6064
  }
6067
- };
6068
- } catch (error) {
6069
- console.error("[CliKit] Plugin initialization error:", error);
6070
- throw error;
6071
- }
6065
+ }
6066
+ };
6072
6067
  };
6073
6068
  var src_default = CliKitPlugin;
6074
6069
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clikit-plugin",
3
- "version": "0.2.23",
3
+ "version": "0.2.25",
4
4
  "description": "OpenCode plugin with 10 agents, 19 commands, 48 skills, 14 hooks",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",