clikit-plugin 0.2.21 → 0.2.23

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 +1 @@
1
- {"version":3,"file":"session-notification.d.ts","sourceRoot":"","sources":["../../src/hooks/session-notification.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,MAAM,WAAW,yBAAyB;IACxC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,UAAU,CAAC;CACzC;AA0BD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAsBtE;AAED,wBAAgB,qBAAqB,CACnC,SAAS,CAAC,EAAE,OAAO,EACnB,MAAM,CAAC,EAAE,MAAM,GACd,mBAAmB,CAUrB;AAED,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,OAAO,EACd,SAAS,CAAC,EAAE,OAAO,EACnB,MAAM,CAAC,EAAE,MAAM,GACd,mBAAmB,CAerB;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,mBAAmB,EAAE,IAAI,EAAE,OAAO,GAAG,MAAM,CAIzF"}
1
+ {"version":3,"file":"session-notification.d.ts","sourceRoot":"","sources":["../../src/hooks/session-notification.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,MAAM,WAAW,yBAAyB;IACxC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,UAAU,CAAC;CACzC;AA4BD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAsBtE;AAED,wBAAgB,qBAAqB,CACnC,SAAS,CAAC,EAAE,OAAO,EACnB,MAAM,CAAC,EAAE,MAAM,GACd,mBAAmB,CAUrB;AAED,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,OAAO,EACd,SAAS,CAAC,EAAE,OAAO,EACnB,MAAM,CAAC,EAAE,MAAM,GACd,mBAAmB,CAerB;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,mBAAmB,EAAE,IAAI,EAAE,OAAO,GAAG,MAAM,CAIzF"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=session-notification.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-notification.test.d.ts","sourceRoot":"","sources":["../../src/hooks/session-notification.test.ts"],"names":[],"mappings":""}
@@ -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,MAmTnB,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,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"}
package/dist/index.js CHANGED
@@ -4499,15 +4499,17 @@ function escapeSingleQuotes(str2) {
4499
4499
  }
4500
4500
  function getNotifyCommand(payload) {
4501
4501
  const { title, body, urgency } = payload;
4502
- const escapedTitle = title.replace(/"/g, "\\\"");
4503
- const escapedBody = body.replace(/"/g, "\\\"");
4502
+ const safeTitle = typeof title === "string" ? title : "Notification";
4503
+ const safeBody = typeof body === "string" ? body : "";
4504
+ const escapedTitle = safeTitle.replace(/"/g, "\\\"");
4505
+ const escapedBody = safeBody.replace(/"/g, "\\\"");
4504
4506
  switch (process.platform) {
4505
4507
  case "linux":
4506
4508
  return `notify-send "${escapedTitle}" "${escapedBody}" --urgency=${urgency || "normal"}`;
4507
4509
  case "darwin":
4508
4510
  return `osascript -e 'display notification "${escapedBody}" with title "${escapedTitle}"'`;
4509
4511
  case "win32":
4510
- return `powershell -command "[void] [System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms'); $n = New-Object System.Windows.Forms.NotifyIcon; $n.Icon = [System.Drawing.SystemIcons]::Information; $n.Visible = $true; $n.ShowBalloonTip(5000, '${escapeSingleQuotes(title)}', '${escapeSingleQuotes(body)}', [System.Windows.Forms.ToolTipIcon]::Info)"`;
4512
+ return `powershell -command "[void] [System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms'); $n = New-Object System.Windows.Forms.NotifyIcon; $n.Icon = [System.Drawing.SystemIcons]::Information; $n.Visible = $true; $n.ShowBalloonTip(5000, '${escapeSingleQuotes(safeTitle)}', '${escapeSingleQuotes(safeBody)}', [System.Windows.Forms.ToolTipIcon]::Info)"`;
4511
4513
  default:
4512
4514
  return null;
4513
4515
  }
@@ -4522,8 +4524,8 @@ function sendNotification(payload) {
4522
4524
  } catch {
4523
4525
  if (process.platform === "linux") {
4524
4526
  try {
4525
- const wslTitle = escapeSingleQuotes(payload.title);
4526
- const wslBody = escapeSingleQuotes(payload.body);
4527
+ const wslTitle = escapeSingleQuotes(typeof payload.title === "string" ? payload.title : "Notification");
4528
+ const wslBody = escapeSingleQuotes(typeof payload.body === "string" ? payload.body : "");
4527
4529
  const wslCmd = `powershell.exe -command "[void] [System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms'); $n = New-Object System.Windows.Forms.NotifyIcon; $n.Icon = [System.Drawing.SystemIcons]::Information; $n.Visible = $true; $n.ShowBalloonTip(5000, '${wslTitle}', '${wslBody}', [System.Windows.Forms.ToolTipIcon]::Info)"`;
4528
4530
  execSync4(wslCmd, { timeout: 5000, stdio: ["pipe", "pipe", "pipe"] });
4529
4531
  return true;
@@ -5821,245 +5823,252 @@ function buildSummary(sections, maxTokens) {
5821
5823
  }
5822
5824
  // src/index.ts
5823
5825
  var CliKitPlugin = async (ctx) => {
5824
- const pluginConfig = loadCliKitConfig(ctx.directory) ?? {};
5825
- const builtinAgents = getBuiltinAgents();
5826
- const builtinCommands = getBuiltinCommands();
5827
- const filteredAgents = filterAgents(builtinAgents, pluginConfig);
5828
- const filteredCommands = filterCommands(builtinCommands, pluginConfig);
5829
- console.log(`[CliKit] Loaded ${Object.keys(filteredAgents).length}/${Object.keys(builtinAgents).length} agents`);
5830
- console.log(`[CliKit] Loaded ${Object.keys(filteredCommands).length}/${Object.keys(builtinCommands).length} commands`);
5831
- if (pluginConfig.disabled_agents?.length) {
5832
- console.log(`[CliKit] Disabled agents: ${pluginConfig.disabled_agents.join(", ")}`);
5833
- }
5834
- if (pluginConfig.disabled_commands?.length) {
5835
- console.log(`[CliKit] Disabled commands: ${pluginConfig.disabled_commands.join(", ")}`);
5836
- }
5837
- return {
5838
- config: async (config) => {
5839
- config.agent = {
5840
- ...filteredAgents,
5841
- ...config.agent
5842
- };
5843
- config.command = {
5844
- ...filteredCommands,
5845
- ...config.command
5846
- };
5847
- if (pluginConfig.lsp && Object.keys(pluginConfig.lsp).length > 0) {
5848
- const enabledLsp = {};
5849
- for (const [name, lspConfig] of Object.entries(pluginConfig.lsp)) {
5850
- if (!lspConfig.disabled) {
5851
- enabledLsp[name] = lspConfig;
5826
+ console.log("[CliKit] Plugin initializing...");
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)`);
5852
5865
  }
5853
5866
  }
5854
- if (Object.keys(enabledLsp).length > 0) {
5855
- config.lsp = {
5856
- ...enabledLsp,
5857
- ...config.lsp || {}
5858
- };
5859
- console.log(`[CliKit] Injected ${Object.keys(enabledLsp).length} LSP server(s)`);
5860
- }
5861
- }
5862
- },
5863
- event: async (input) => {
5864
- const { event } = input;
5865
- const props = event.properties;
5866
- if (event.type === "session.created") {
5867
- if (pluginConfig.hooks?.session_logging) {
5868
- const info = props?.info;
5869
- console.log(`[CliKit] Session created: ${info?.id || "unknown"}`);
5870
- }
5871
- if (pluginConfig.hooks?.env_context?.enabled !== false) {
5872
- const envConfig = pluginConfig.hooks?.env_context;
5873
- const envInfo = collectEnvInfo(ctx.directory, envConfig);
5874
- const envBlock = buildEnvBlock(envInfo);
5875
- console.log(formatEnvSummary(envInfo));
5876
- input.__envBlock = envBlock;
5877
- }
5878
- }
5879
- if (event.type === "session.error") {
5880
- const error = props?.error;
5881
- if (pluginConfig.hooks?.session_logging) {
5882
- console.error(`[CliKit] Session error:`, error);
5883
- }
5884
- if (pluginConfig.hooks?.session_notification?.enabled !== false && pluginConfig.hooks?.session_notification?.on_error !== false) {
5885
- const notifConfig = pluginConfig.hooks?.session_notification;
5886
- const sessionId = props?.sessionID;
5887
- const payload = buildErrorNotification(error, sessionId, notifConfig?.title_prefix);
5888
- const sent = sendNotification(payload);
5889
- console.log(formatNotificationLog(payload, sent));
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
+ }
5890
5883
  }
5891
- }
5892
- if (event.type === "session.idle") {
5893
- const sessionID = props?.sessionID;
5894
- if (pluginConfig.hooks?.session_logging) {
5895
- console.log(`[CliKit] Session idle: ${sessionID || "unknown"}`);
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
+ }
5896
5896
  }
5897
- const todoConfig = pluginConfig.hooks?.todo_enforcer;
5898
- if (todoConfig?.enabled !== false) {
5899
- const todos = props?.todos;
5900
- if (Array.isArray(todos) && todos.length > 0) {
5901
- const result = checkTodoCompletion(todos);
5902
- if (!result.complete && todoConfig?.warn_on_incomplete !== false) {
5903
- console.warn(formatIncompleteWarning(result, sessionID));
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
+ }
5904
5910
  }
5905
5911
  }
5906
- }
5907
- if (pluginConfig.hooks?.session_notification?.enabled !== false && pluginConfig.hooks?.session_notification?.on_idle !== false) {
5908
- const notifConfig = pluginConfig.hooks?.session_notification;
5909
- const payload = buildIdleNotification(sessionID, notifConfig?.title_prefix);
5910
- const sent = sendNotification(payload);
5911
- console.log(formatNotificationLog(payload, sent));
5912
- }
5913
- if (pluginConfig.hooks?.compaction?.enabled !== false) {
5914
- const compConfig = pluginConfig.hooks?.compaction;
5915
- const compPayload = collectCompactionPayload(ctx.directory, compConfig);
5916
- if (compConfig?.include_todo_state !== false && props?.todos) {
5917
- compPayload.todos = props.todos;
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;
5923
+ }
5924
+ const block = buildCompactionBlock(compPayload, compConfig?.max_state_chars);
5925
+ console.log(formatCompactionLog(compPayload));
5926
+ input.__compactionBlock = block;
5918
5927
  }
5919
- const block = buildCompactionBlock(compPayload, compConfig?.max_state_chars);
5920
- console.log(formatCompactionLog(compPayload));
5921
- input.__compactionBlock = block;
5922
5928
  }
5923
- }
5924
- },
5925
- "tool.execute.before": async (input, _output) => {
5926
- const toolName = input.tool;
5927
- const toolInput = input.input ?? {};
5928
- if (pluginConfig.hooks?.tool_logging) {
5929
- console.log(`[CliKit] Tool executing: ${toolName}`);
5930
- }
5931
- if (pluginConfig.hooks?.git_guard?.enabled !== false) {
5932
- if (toolName === "bash" || toolName === "Bash") {
5933
- const command = toolInput.command;
5934
- if (command) {
5935
- const allowForceWithLease = pluginConfig.hooks?.git_guard?.allow_force_with_lease !== false;
5936
- const result = checkDangerousCommand(command, allowForceWithLease);
5937
- if (result.blocked) {
5938
- console.warn(formatBlockedWarning(result));
5939
- input.__blocked = true;
5940
- input.__blockReason = result.reason;
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}`);
5935
+ }
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
+ }
5941
5947
  }
5942
5948
  }
5943
5949
  }
5944
- }
5945
- if (pluginConfig.hooks?.security_check?.enabled !== false) {
5946
- if (toolName === "bash" || toolName === "Bash") {
5947
- const command = toolInput.command;
5948
- if (command && /git\s+(commit|add)/.test(command)) {
5949
- const secConfig = pluginConfig.hooks?.security_check;
5950
- let shouldBlock = false;
5951
- const files = toolInput.files;
5952
- if (files) {
5953
- for (const file of files) {
5954
- if (isSensitiveFile(file)) {
5955
- console.warn(`[CliKit:security] Sensitive file staged: ${file}`);
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));
5956
5970
  shouldBlock = true;
5957
5971
  }
5958
5972
  }
5959
- }
5960
- const content = toolInput.content;
5961
- if (content) {
5962
- const scanResult = scanContentForSecrets(content);
5963
- if (!scanResult.safe) {
5964
- console.warn(formatSecurityWarning(scanResult));
5965
- shouldBlock = true;
5973
+ if (shouldBlock && secConfig?.block_commits) {
5974
+ input.__blocked = true;
5975
+ input.__blockReason = "Sensitive data detected in commit";
5966
5976
  }
5967
5977
  }
5968
- if (shouldBlock && secConfig?.block_commits) {
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());
5969
5985
  input.__blocked = true;
5970
- input.__blockReason = "Sensitive data detected in commit";
5986
+ input.__blockReason = "Subagents should not ask questions";
5971
5987
  }
5972
5988
  }
5973
5989
  }
5974
- }
5975
- if (pluginConfig.hooks?.subagent_question_blocker?.enabled !== false) {
5976
- if (isSubagentTool(toolName)) {
5977
- const prompt = toolInput.prompt;
5978
- if (prompt && containsQuestion(prompt)) {
5979
- console.warn(formatBlockerWarning());
5980
- input.__blocked = true;
5981
- input.__blockReason = "Subagents should not ask questions";
5982
- }
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}`);
5983
5997
  }
5984
- }
5985
- },
5986
- "tool.execute.after": async (input, output) => {
5987
- const toolName = input.tool;
5988
- const toolInput = input.input ?? {};
5989
- const toolOutput = output;
5990
- if (pluginConfig.hooks?.tool_logging) {
5991
- console.log(`[CliKit] Tool completed: ${toolName} -> ${output.title}`);
5992
- }
5993
- const sanitizerConfig = pluginConfig.hooks?.empty_message_sanitizer;
5994
- if (sanitizerConfig?.enabled !== false) {
5995
- if (toolOutput.content !== undefined && isEmptyContent(toolOutput.content)) {
5996
- const placeholder = sanitizerConfig?.placeholder || "(No output)";
5997
- if (sanitizerConfig?.log_empty !== false) {
5998
- console.log(`[CliKit] Empty output detected for tool: ${toolName}`);
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);
5999
6006
  }
6000
- toolOutput.content = sanitizeContent(toolOutput.content, placeholder);
6001
6007
  }
6002
- }
6003
- if (pluginConfig.hooks?.comment_checker?.enabled !== false) {
6004
- if (toolName === "edit" || toolName === "Edit" || toolName === "write" || toolName === "Write") {
6005
- const content = toolOutput.content;
6006
- if (typeof content === "string" && content.length > 100) {
6007
- const threshold = pluginConfig.hooks?.comment_checker?.threshold ?? 0.3;
6008
- const densityResult = checkCommentDensity(content, threshold);
6009
- if (densityResult.excessive) {
6010
- console.warn(formatCommentWarning(densityResult));
6011
- }
6012
- if (hasExcessiveAIComments(content)) {
6013
- console.warn("[CliKit:comment-checker] Detected AI-style boilerplate comments. Remove unnecessary comments.");
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
+ }
6014
6020
  }
6015
6021
  }
6016
6022
  }
6017
- }
6018
- if (pluginConfig.hooks?.truncator?.enabled !== false) {
6019
- if (typeof toolOutput.content === "string" && shouldTruncate(toolOutput.content, pluginConfig.hooks?.truncator)) {
6020
- const result = truncateOutput(toolOutput.content, pluginConfig.hooks?.truncator);
6021
- if (result.truncated) {
6022
- toolOutput.content = result.content;
6023
- if (pluginConfig.hooks?.truncator?.log !== false) {
6024
- console.log(formatTruncationLog(result));
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
+ }
6025
6031
  }
6026
6032
  }
6027
6033
  }
6028
- }
6029
- if (pluginConfig.hooks?.auto_format?.enabled) {
6030
- if (toolName === "edit" || toolName === "Edit" || toolName === "write" || toolName === "Write") {
6031
- const filePath = toolInput.filePath;
6032
- if (filePath) {
6033
- const fmtConfig = pluginConfig.hooks.auto_format;
6034
- if (shouldFormat(filePath, fmtConfig?.extensions)) {
6035
- const result = runFormatter(filePath, ctx.directory, fmtConfig?.formatter);
6036
- if (fmtConfig?.log !== false) {
6037
- console.log(formatAutoFormatLog(result));
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
+ }
6038
6044
  }
6039
6045
  }
6040
6046
  }
6041
6047
  }
6042
- }
6043
- if (pluginConfig.hooks?.typecheck_gate?.enabled) {
6044
- if (toolName === "edit" || toolName === "Edit" || toolName === "write" || toolName === "Write") {
6045
- const filePath = toolInput.filePath;
6046
- if (filePath && isTypeScriptFile(filePath)) {
6047
- const tcConfig = pluginConfig.hooks.typecheck_gate;
6048
- const result = runTypeCheck(filePath, ctx.directory, tcConfig);
6049
- if (!result.clean) {
6050
- console.warn(formatTypeCheckWarning(result));
6051
- if (tcConfig?.block_on_error) {
6052
- input.__blocked = true;
6053
- input.__blockReason = `Type errors in ${filePath}`;
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));
6054
6062
  }
6055
- } else if (tcConfig?.log !== false) {
6056
- console.log(formatTypeCheckWarning(result));
6057
6063
  }
6058
6064
  }
6059
6065
  }
6060
6066
  }
6061
- }
6062
- };
6067
+ };
6068
+ } catch (error) {
6069
+ console.error("[CliKit] Plugin initialization error:", error);
6070
+ throw error;
6071
+ }
6063
6072
  };
6064
6073
  var src_default = CliKitPlugin;
6065
6074
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clikit-plugin",
3
- "version": "0.2.21",
3
+ "version": "0.2.23",
4
4
  "description": "OpenCode plugin with 10 agents, 19 commands, 48 skills, 14 hooks",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",